java编程:优化Java动画编程中的显示效果来源: 发布时间:星期二, 2009年9月8日 浏览:0次 评论:0
Java动画编程有多种实现思路方法但它们实现基本原理是样即在屏幕上画出系列帧来造成运动感觉Java多线程技术是Java动画编程中普遍运用技术它在控制动画流程和动画显示效果方面起着重要作用Java动画编程中动画闪烁和图像残缺不全等现象是Java员经常遇到问题本文以作者应用例子为基础阐述如何运用多线程、重载Update、双缓冲和图像跟踪等窍门技巧来解决这类问题以达到动画显示最佳效果
Java多线程技术 Java多线程技术介绍 目前线程(Thread)已经为许多操作系统和应用开发系统所采用线程是单个控制流具有顺序特点但是线程不是个它仅仅是个执行序列线程具有很强并发功能在同时刻可以有多个线程同时处于执行状态线程是动态具有定生命周期分别经历从创建、执行、阻塞、直到消亡过程Java语言对多线程编程支持有两种实现思路方法:种是直接继承Thread类另种是实现Runnable接口Thread类提供了对线程控制思路方法如startstoprun、suspend、resume和sleep等思路方法它们可以对线程状态进行控制 动画线程设计和实现 为了每秒中多次更新屏幕必须创建个线程来实现动画循环这个循环要跟踪当前帧并响应周期性屏幕更新要求许多Java初学者容易犯个是将动画循环放在pa中这样占据了主AWT线程而主线程将负责所有绘图和事件处理因此应该生成个独立动画线程来完成图像显示和更新例如在个Applet框架下当Applet启动(Start)时生成个动画线程;在Applet停止(stop)时终止该动画线程以释放它所占用CPU资源下列代码(简称“C1”代码)是该动画线程具体实现: public void start { (animatorThreadnull) { animatorThread= Thread(this); //开始动画线程 animatorThread.start; } } public void stop{ //停止动画线程 animatorThread=null; } 上面终止动画线程时候并不是该动画线程stop思路方法而是设置该动画线程为null如果直接线程stop思路方法会强制线程终止所有执行工作有时会带来不好结果设置该动画线程为null则在run思路方法中由于不满足循环条件线程会自然退出这样也进步优化了该动画 重载update和双缓冲技术消除闪烁 在Java中动画发生闪烁有两个原因:个是由于在显示下帧画面时候了repa思路方法;而repa思路方法被时要清除整个背景然后才pa思路方法显示画面这样在清除背景和绘制图像短暂时间间隔内被用户看见就是闪烁另个是由于pa思路方法要进行复杂计算绘制每帧花费时间太长图像中各个像素值不能同时得到使得动画生成频率低于显示器刷新频率从而造成闪烁 下面两种思路方法可以明显地消除或减弱闪烁 重载update思路方法 当AWT接收到个Applet重绘请求时它就Appletupdate思路方法缺省情况下update思路方法清除Applet背景然后pa思路方法重载update思路方法就可以将以前在pa思路方法中绘图代码包含在update思路方法中从而避免每次重绘时将整个区域清除既然背景不再自动清除Java员需要自己在update中完成 双缓冲技术 另种消除帧的间闪烁思路方法是使用双缓冲技术它在许多动画Applet中被使用主要原理是创建幅后台图像将每帧画入图像然后drawImage思路方法将整个后台图像次画到屏幕上去这种思路方法优点在于大部分绘制是离屏将离屏图像次绘至屏幕上比直接在屏幕上绘制要有效得多在创建后台图像前首先要通过createImage思路方法生成合适后台缓冲区然后获得在缓冲区做图环境(即Graphics类对象) 下列例子代码(简称“C2”代码)就是这两种思路方法结合使用双缓冲技术在重载update思路方法中实现其中offImage是Image类对象offGraphics是Graphics类对象这两个类对象是实现双缓冲技术关键相关代码如下: public void pa(Graphics g){ update(g); } public void update(Graphics g){ Dimension d=getSize; //如果后台图像不存在就创建个后台图像 ((offGraphicsnull)||(d.width!=offDimension.width) ||(d.height!=offDimension.height)) { offDimension=d; offImage=createImage(d.width,d.height); offGraphics=offImage.getGraphics; } //擦除上帧 offGraphics.Color(getBackground); offGraphics.fillRect(0,0,d.width,d.height); offGraphics.Color(Color.black); //将当前帧输出到指定image中 for( i=0 ; i<10 ; i){ offGraphics.drawImage(images[i],frameNumber*5%(d.width/2) ,i*d.height/10,this); } //输出指定后台图像 g.drawImage(offImage,frameNumber*5%(d.width/2),0,this); } 双缓冲技术可以使动画平滑但有个缺点要分配个后台图像缓冲如果图像相当大这将占用很大块内存 图像跟踪和逐步完善 图像跟踪 当动画线程刚刚启动时候由于没有全部载入图像屏幕上显示画面经常是残缺不全这时可以使用MediaTracker或ImageOberver类对象进行图像跟踪待图像全部载入后再drawImage思路方法将图像输出到屏幕上去DrawImage思路方法第 4个参数正是ImageObserver类对象所以可以用ImageObserver类对象进行图像跟踪在实际应用Appletinit思路方法中实现图像跟踪相当于在动画线程DrawImage思路方法以前就画了次图像动画线程化过程即init思路方法是先被下列代码(简称“C3”代码)展示了init思路方法使用MediaTracker类对象来实现跟踪图像载入代码如下: public void init{ tracker= MidiaTracker(this); for( i=1;i<=10;i){ image[i-1]=getImage(getCodeBase,"image"+i+" .g"); //用MediaTracker类对象addImage思路方法跟踪图像载入 tracker.addImage(images[i-1],0); } ...... } 进步完善 在“C2”代码重载update思路方法中加入下列语句从而对MediaTracker类对象图像跟踪思路方法做出判断语句如下: (!tracker.checkAll){ //如果图像还没有装载完毕则仅清除背景同时输出个状态 g.clearRect(0,0,d.width,d.height); g.drawString("Please wait...",0,d.height/2); ; } 在“C1”代码stop思路方法中加入两行代码用以释放由双缓冲技术所占用内存资源这时stop思路方法改为: public void stop{ //停止动画线程 animatorThread=null; //释放用于双缓冲内存资源 offGraphics=null; offImage=null; } 修改到此还有个小问题就是动画线程启动后第幅图像有时仍有残留痕迹而不是随着图像更新而完全擦除掉如果想解决此问题只要将“C2”代码中最后for循环和g.drawImage思路方法改为如下代码就可以了 for( i=0;i<10;i){ offGraphics.drawImage(images[frameNumber%10], ,frameNumber*5%(d.width),i*d.height/10,this); } g.drawImage(offImage,0,0,this); 保持恒定帧速度 为了使用户观看动画时没有闪烁感至少需要达到每秒12帧速度更高帧速度会产生更平滑动画通常在动画显示每两帧的间线程sleep思路方法休眠个固定时间这样做缺点是使用绝对延迟时间会使延迟过长即造成等待时间过长为了每秒显示10~20帧图像并保持恒定帧速度(也就是恒定显示频率)在动画线程run思路方法中可加入如下代码: try{ startTimedelay; Thread.sleep(Math.max(0,startTime-.currentTimeMillis)); }catch(InterruptedException e){ ; } 本文着重阐述了优化Java动画编程显示效果几种思路方法当然随着Java技术以及其它计算机技术发展还将会有多种优化动画显示效果思路方法例如在提高动画帧速度方面可在Java中微软公司DirectDraw工具但是本文所介绍思路方法更具有通用性 0
相关文章
读者评论发表评论 |
|