打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
HTML5 Canvas 逐帧动画的实现

前端向左,后台向右

分类: HTML5 2011-11-15 16:37 3670人阅读 评论(4) 收藏 举报

和C++游戏开发相同,HTML5逐帧动画需要的图像元素也是一张绘制了每一帧图像效果的图片。通过循环绘制各帧的图像来实现动画的效果。

本示例中演示的是一个小人,默认状态下,小人朝右方站立;按下左/右方向键的时候,小人朝左/右方奔跑(在画布中没有位移);松开按键后保持奔跑的方向站立。

其中,向左或向右站立分别是一张6帧的图片,向左或向右奔跑分别是一张12帧的图片。

代码如下:

HTML代码:

  1. <canvas id="canvas" width="600" height="400">  
  2.     <p>Your browser does not support the canvas element!</p>  
  3. </canvas>  
JavaScript代码如下:

以下这段代码已经在本人的博文中多次重用,所以就不解释了。

[javascript] view plaincopy
  1. Array.prototype.remove = function(obj) {  
  2.     for (i in this) {  
  3.         if (this[i] === obj) {  
  4.             this.splice(i, 1);  
  5.         }  
  6.     }  
  7. }  
  8.   
  9. function BasicObject(x, y, order) {  
  10.     this.x = x;  
  11.     this.y = y;  
  12.     this.order = isNaN(order) ? 0 : order;  
  13.       
  14.     this.addTo = function(list) {  
  15.         list.push(this);  
  16.         list.sort(function(a, b) {return a.order - b.order;});  
  17.     }  
  18.       
  19.     this.removeFrom = function(list) {  
  20.         list.remove(this);  
  21.     }  
  22. }  
逐帧动画的基础对象,继承自基础对象类,添加了图像、总帧数两个属性,以及绘制逐帧对象的方法
[javascript] view plaincopy
  1. function FrameAnimationObject(x, y, order, image, frame) {  
  2.     BasicObject.call(this, x, y, order);  
  3.     this.image = image;  
  4.     this.frame = frame;  
  5.     this.currentFrame = 0;  
  6.       
  7.     this.draw = function(context) {  
  8.         var sw = this.image.width / this.frame;  
  9.         var sx = this.currentFrame * sw;  
  10.         context.drawImage(this.image, sx, 0, sw, this.image.height, this.x, this.y, sw, this.image.height);  
  11.         this.currentFrame++;  
  12.         this.currentFrame = (this.currentFrame >= this.frame) ? 0 : this.currentFrame;  
  13.     }  
  14. }  
  15. FrameAnimationObject.prototype = new BasicObject();  

奔跑小人的类,继承自逐帧动画基础对象,指定了需求使用的图像资源,并添加了响应键盘事件的方法

[javascript] view plaincopy
  1. function Person(x, y, order) {  
  2.     FrameAnimationObject.call(this, x, y, order);  
  3.     this.image = new Image();  
  4.     this.image.src = "stop_right.png"  
  5.     this.frame = 6;  
  6.       
  7.     this.onkeydown = function(event) {    
  8.         if (event.keyCode == 37) {    
  9.             this.image.src = "run_left.png";    
  10.             this.frame = 12;    
  11.         }    
  12.         else if (event.keyCode == 39) {    
  13.             this.image.src = "run_right.png";  
  14.             this.frame = 12;      
  15.         }    
  16.           
  17.         this.currentFrame = (this.currentFrame >= this.frame) ? 0 : this.currentFrame;    
  18.     }    
  19.         
  20.     this.onkeyup = function(event) {    
  21.         if (event.keyCode == 37) {    
  22.             this.image.src = "stop_left.png";    
  23.         }    
  24.         else if (event.keyCode == 39) {    
  25.             this.image.src = "stop_right.png";    
  26.         }    
  27.         this.frame = 6;    
  28.         this.currentFrame = (this.currentFrame >= this.frame) ? 0 : this.currentFrame;    
  29.     }    
  30. }  
  31. Person.prototype = new FrameAnimationObject();  

动画引擎类以及程序入口

[javascript] view plaincopy
  1. function Engin() {  
  2.     var canvas = document.getElementById("canvas");  
  3.     var context = canvas.getContext("2d");  
  4.       
  5.     var buffer = document.createElement("canvas");  
  6.     buffer.width = canvas.width;  
  7.     buffer.height = canvas.height;  
  8.     var bufferCtx = buffer.getContext("2d");  
  9.       
  10.     var objs = new Array();  
  11.       
  12.     const FPS = 20;  
  13.       
  14.     this.manage = function() {  
  15.         bufferCtx.clearRect(0, 0, buffer.width, buffer.height);  
  16.         context.clearRect(0, 0, canvas.width, canvas.height);  
  17.           
  18.         for (x in objs) {  
  19.             if (objs[x].update) {  
  20.                 objs[x].update(objs);  
  21.             }  
  22.         }  
  23.           
  24.         for (x in objs) {  
  25.             if (objs[x].draw) {  
  26.                 objs[x].draw(bufferCtx);  
  27.             }  
  28.         }  
  29.           
  30.         context.drawImage(buffer, 0, 0);  
  31.     }  
  32.       
  33.     document.onkeydown = function(event) {  
  34.         for (x in objs) {  
  35.             if (objs[x].onkeydown) {  
  36.                 objs[x].onkeydown(event);  
  37.             }  
  38.         }  
  39.     }  
  40.       
  41.     document.onkeyup = function(event) {  
  42.         for (x in objs) {  
  43.             if (objs[x].onkeyup) {  
  44.                 objs[x].onkeyup(event);  
  45.             }  
  46.         }  
  47.     }  
  48.       
  49.     this.run = function() {  
  50.         var p = new Person(canvas.width / 2, canvas.height / 2);  
  51.         p.addTo(objs);  
  52.           
  53.         setInterval(this.manage, 1000 / FPS);  
  54.     }  
  55. }  
  56.   
  57. window.onload = function() {  
  58.     new Engin().run();  
  59. }  

需要说明的是,本次将键盘事件的响应放到了动画对象的类中来实现,并在引擎类中通过设定document的键盘事件来引用,这昂做事为了依照上一篇博文总所说的将动画对象的逻辑操作封装在最外层,同时避免了引擎类的过分膨胀。当动画对象逐渐增多时,效果更加明显。

0
1
主题推荐
动画 canvas html5 游戏开发 图片
猜你在找
php面试题
在线绘图插件--wPaint 的实际应用
使用js实现滑动页面效果很漂亮
openssl从PFX导出私钥公钥
Xcode 6 pch创建文件
java开发com组件
经验总结技术人员如何赚钱
jsp如何实现页面跳转
基于Web的实时通讯方案
使用windowshowDialog打开新页面后滚动条设置

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
JS文件/图片从电脑里面拖拽到浏览器上传文件/图片
html自学教程(八)html5基础
JS自定义对象
第8章 综合项目—点餐系统
FastAdmin多表联查
一个不错的HTML5 Canvas多层点击事件监听实例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服