使用Canvas实现动画效果
这是动手开发一个HTML5赛车小游戏系列文章。你可以查看前一篇内容:
这里我们使用Canvas开发这个游戏,而不是采用传统的DOM方式实现,虽然这个简单的游戏使用DOM也可以实现(甚至有可能更容易点)。但是Canvas可以更加方便的控制图片,功能更更加强大,因为你可以完全按照自己的想法进行绘制和操作图像。
Canvas是HTML5中新加入的标签。它定义了一个图形,可以是图表或任何内容,但是它只是一个容器,你必须使用JavaScript来进行绘制图形。Canvas并不是为动画准备的,但是你可以使用它来实现动画效果。
前面介绍过在HTML中如何使用JavaScript实现DOM的动画效果:
其实使用Canvas中的动画实现某种程度也利用了同样的思想。快速的定时的改变所绘制的图形的位置。当然Canvas上所绘制的图形不会自动消失,如果你不断的画图形会不断的重复出现在画布中,所以你需要在重绘之前清除画布,这样你得到的才是动画而不是动画的轨迹。
JavaScript中没有诸如sleep
等阻塞的方法,所以我们需要使用setTimeout或setInterval来实现定时执行的功能。大部分现代浏览器中提供了一个新的方法requestAnimationFrame
来代替普通的定时器,这是由FireFox首先实现的,虽然目前还不是标准,但是大部分现代浏览器中已经支持这个方法,你可能需要使用不同的前缀调用它,如:mozRequestAnimationFrame
或webkitRequestAnimationFrame
。这个方法类似setTimeout,它由浏览器自行判断执行的时机,当页面不可见时它会自动降频,以达到节约资源的目的。它是你实现动画的最佳选择。它的执行频率大于是每秒60次,因为这是浏览器刷新的极限,如果再高对浏览器来说就没有意义了。当然对于不支持的浏览器我们可以使用setTimeout或setInterval来代替,相信你可以很容易的实现类似功能。下面是一个兼容的写法:
window.requestAnimFrame = (function() { oreturn window.requestAnimationFrame o|| window.webkitRequestAnimationFrame o|| window.mozRequestAnimationFrame o|| window.oRequestAnimationFrame o|| window.msRequestAnimationFrame || function() { o//return setTimeout(arguments[0], 1000 / 60); oreturn -1; o} // return -1 if unsupported })(); window.cancelRequestAnimFrame = (function() { oreturn window.cancelAnimationFrame o|| window.webkitCancelRequestAnimationFrame o|| window.mozCancelRequestAnimationFrame o|| window.oCancelRequestAnimationFrame o|| window.msCancelRequestAnimationFrame || function() { oreturn -1; o} // return -1 if unsupported })();
当然你还要熟悉一下Canvas绘图的API。
首先你需要获取一个画布的对象,然后通过画布对象的getContext()
方法获取一个绘图上下文。这个方法接受一个字符串参数"2d"
,这是目前你所能用的,当然还有其他的模式,比如WebGL,虽然已经被Chrome和FireFox所支持,但是MS的IE浏览器应该是不会支持了。通过这个绘图上下文你可以画线也可以画图形,可以描边路径也可以填充它,还可以直接绘制图片,或者直接操作图片数据等等。
网上有很多这方面的资料,这里就不多说了,文章的结尾我会给出一些参考资料。如果你对Canvas绘图不是很熟悉,MDN的Canvas教程将会是你的好选择。
这里我们做一个最简单的实例,让一个圆在画布上移动起来:
-
o
- 首先我们需要把一个方框画到画布上。点击查看示例:http://jsfiddle.net/mqVZ7/1/
- 接下来让我们每秒将小方块向右向下移动5个像素,并改变它的颜色。为了方便查看我们将小方块的透明度设置为.5。你会看到一串小方块运动的轨迹:http://jsfiddle.net/mqVZ7/2/
- 这并不是我们需要的动画效果,它绘制的是一个轨迹而不是动画,要想实现动画效果,我们需要在每帧的绘制之前清除画布的所有内容,当然你还可以只重绘需要的部分。这里我们重绘整个画布,为了运动更平滑我们将移动的距离改为1个像素:http://jsfiddle.net/mqVZ7/3/
o
o
好了我们实现了我们想要的效果。当然你同样可以使用前面用过的数学公式。先说到这,后面会继续跟大家讨论控制动画对象等内容。
引用内容:
转载请注明原文出处《使用Canvas实现动画效果》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。
动手开发一个HTML5赛车小游戏
你是不是曾经也有自己做一个游戏的冲动呢?是不是因为事情太多,手头没空或者没有做过游戏的基础而屡屡放弃了呢?现在HTML5正如火如荼,让我们一起使用HTML5中的新功能做一个小游戏玩玩吧。
先来看看效果:
在线演示地址:点击查看
源代码GitHub:点击查看
麻雀虽小,五脏俱全。先来说一下这个小游戏有的内容:
-
o
- 一个开始画面,写了游戏的名字和一个开始按钮。
- 游戏的主体内容,一个可以自己控制的小汽车,还有很多打酱油的汽车,另外还有马路及马路旁边的龙套树木和自行车道…
- 一个结束游戏的画面。
o
o
好了这就是全部游戏的内容。游戏的玩法很简单,相信大家应该都玩过,就是一辆汽车在马路上跑,你要尽量躲避开其他汽车,不与他们相撞,否则游戏结束,游戏会以你跑过的旅程计算分数。
主要用的技术是HTML5中的画布元素Canvas和JavaScript。主要要做的工作就是实现Canvas的tween动画,一些简单的矢量,速度,位移等效果的处理。另外还有一些Sprint动画的处理。
具体的实现过程会在以后的文章中详细讲解。
目前本人正在进一步完善这个简单的JavaScript游戏引擎,以便使用这个游戏引擎实现一个SRPG游戏。新的游戏正在开发当中,如果您对此感兴趣欢迎联系我:dukai86@gmail.com
转载请注明原文出处《动手开发一个HTML5赛车小游戏》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。
HTML5 Canvas和EaselJS入门(译)
HTML5中最受开发者期待的一项新特性莫过于Canvas(画布)元素了。Canvas元素提供了一个可以动态渲染图形和位图的位图画布。它非常类似于Flash中的Bitmap和BitmapData两个类。
但是,要使用Canvas还是有点难度的,特别是如果你还想管理,重绘或者运动图形或图片。与Flash播放器不同的是Canvas没有显示队列或显示个别项目这种概念,它提供一个用于绘图的画布,画什么以及什么时候画都取决于开发者。
Grant Skinner放出了一个名为EaselJS的JavaScript库,视图提供一个类似于Flash的DisplayList API用于简化Canvas的开发工作。虽然这个库目前还在内测阶段,但是却在早期就诶的就支持全部特性。如果你对Canvas感兴趣,那么这将是一个非常好的起点。
在这篇文章中,我将展示如何使用EaselJS来实现Canvas的动画效果。
下面是一个库中主要类的列表:
-
o
- DisplayObject:所有EaselJS中显示元素的抽象基类。包含所有显示元素的公用属性(例如:x,y,角度,x比例,y比例,透明度,阴影等等)。
- Stage:用以包含所有Canvas元素的容器根对象
- Container:可以包含一组对象的容器对象,可以让你把多个对象作为一个组来操作。
- Text:在显示列表的上下文中渲染文本
- Bitmap:按照显示的属性绘制一幅图,一个视频或者画布到画布上
- BitmapSequence:显示运动的或者动态的精灵板()并且提供管理回放和队列的APIs
- Graphics:提供一个简单却又强的绘制适量图形的API
- Shape:在显示列表上下文中通过Graphics Object渲染适量图
o
o
o
o
o
o
o
现在,在我们开始之前,让我们先看一下你在哪能够用到Canvas对象。Canvas是HTML5标准中的一部分,已经被大多数现代浏览器的最新版本所支持,包括:
Safari
Google Chrome
Opera
FireFox
(IE9业已支持 译者注)
但是,还有一个问题,并且这是个大问题。IE并没有支持Canvas对象(虽然下一个版本会支持)。根据NetMarketShare的数据,IE6,7,8占据了57%的浏览器市场,是用户最多的一部分。有个叫ExplorerCanvas的项目试图使IE支持Canvas,但是EaselJS为测试与它的兼容性。当你考虑用Canvas的时候请牢记这点。
现在我们有了一个是哦那个Canvas的好主意,先让我们看一个简单点例子。在示例中,我们将使用EaselJS动态的画一个圆并且移动它穿过画布。这个示例将会展示如何按照类库,介绍一下使用类库的一些基本概念,并且展示如何运动一个图形。
下面是例子
现在让我们看一下代码:
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- o<meta charset="utf-8" />
-
- o<meta name="author" content="Mike Chambers" />
- o<meta name="keywords" content="" />
- o<meta name="description" content="" />
- o<meta name="copyright" content="Mike Chambers" />
- o<meta name="robots" content="index,follow" />
-
-
- o<style>
- o#stageCanvas
- o{
- obackground-color:#333333;
- o}
- o</style>
-
- o<!-- 导入Easel库,下载地址 http://easeljs.com/
- o-->
-
- o<script>
-
- o//检查Canvas在当前浏览器是否支持
- o//http://diveintohtml5.org/detect.html#canvas
- oif(!(!!document.createElement("canvas").getContext))
- o{
- ovar wrapper = document.getElementById("canvasWrapper");
- owrapper.innerHTML = "Your browser does not appear to support " +
- o"the HTML5 Canvas element";
- oreturn;
- o}
-
- o//EaselJS Stage实例包含Canvas元素
- ovar stage;
-
- o//EaselJS Shape示例我们将做成动画
- ovar circle;
-
- o//圆的半径
- ovar CIRCLE_RADIUS = 10;
-
- o//x坐标,当圆离开屏幕的时候
- ovar circleXReset;
-
- o//EaselJS Rectangle(矩形)实例用于存储Canvas的边界值
- ovar bounds = new Rectangle();
-
- o//初始化函数
- ofunction init()
- o{
-
- o//通常这里我们会做一些Canvas的嗅探工作.
- o//浏览http://www.modernizr.com/有个用于HTML5嗅探非常有用的库
- o//获取Canvas对象的引用
- ovar canvas = document.getElementById("stageCanvas");
-
- o//复制画布绑定到边界实例
- o//注意,如果我们改变了画布的大小,我们需要同时改动这些边界
- obounds.w = canvas.width;
- obounds.h = canvas.height;
-
- o//pass the canvas element to the EaselJS Stage instance
- o//The Stage class abstracts away the Canvas element and
- o//is the root level display container for display elements.
- ostage = new Stage(canvas);
-
- o//创建一个EaselJS图形元素用来创建画圆的命令
- ovar g = new Graphics();
-
- o//1px的画笔
- og.setStrokeStyle(1);
-
- o//设置画笔颜色, 使用EaselJS
- o//Graphics.getRGB静态方法.
- o//创建了一个透明度为.7的白色
- og.beginStroke(Graphics.getRGB(255,255,255,.7));
-
- o//画这个圆
- og.drawCircle(0,0, CIRCLE_RADIUS);
-
- o//注意过圆现在并未真正的被画出来
- o//图形实例只是具有画圆的命令
- o//它在stage需要渲染的时候才被画出来
- o//通常在我们调用stage.tick()的时候
-
- o//创建一个新的图形实例. 这是一个可以添加到stage中并可以被渲染的显示对象
- o//Pass in the Graphics instance that we created, and that
- o//we want the Shape to draw.
- ocircle = new Shape(g);
-
- o//初始化x坐标,并初始化
- ocircle.x = circleXReset = -CIRCLE_RADIUS;
-
- o//设置y坐标
- ocircle.y = canvas.height / 2;
-
- o//将圆加入到舞台
- ostage.addChild(circle);
-
- o//让stage开始渲染
- ostage.tick();
-
- o//添加Tick类的订阅.这会每隔一段时间就调用tick方法
- o//(就像Flash中的ENTER_FRAME)
- oTick.addListener(this);
- o}
-
- o//每隔一定时间被Tick调用的函数
- ofunction tick()
- o{
- o//检查图像是否超出了stage的右边界
- oif(circle.x > bounds.w)
- o{
- o//如果有,则重置
- ocircle.x = circleXReset;
- o}
-
- o//将圆的x坐标移动10像素
- ocircle.x += 10;
-
- o//重新渲染stage
- ostage.tick();
- o}
- o</script>
-
- </head>
- <body onload="init()">
- o<div width="400" height="300" id="canvasWrapper">
- o<canvas width="400" height="300" id="stageCanvas"></canvas>
- o</div>
- </body>
- </html>
你可以点击这里下载本示例代码。
你可以看到,代码是相当的简单,并且它的结构也非常类似使用Flash中的DisplayList API。
有一些非常重要的地方需要指出。
EaselJS Stage示例包含Canvas元素,并且处理所有的内容什么时候如何渲染。只有当你调用stage.tick()的时候stage才渲染,并且为了效率方面的考虑,你仅需要在有内容发生更改或者需要重绘画布的时候再调用这个方法。
Tick类用于处理时间管理。当任何一个观察者对象被通知的时候它将调用一个tick方法。这与ActionScript中的ENTER_FRAME事件类似。
如果你改变了画布的大小,它的内容会被清空。然而,如果你使用EaselJS,唯一你需要做的就是在改变画布大小后调用stage.tick()方法,然后画布会重新渲染。
由于IE缺乏对Canvas的支持,你探测浏览器是否支持Canvas的工作变得非常重要,你最好给用户一个可以接受的回落。上面的示例代码中有简单的示范,同样你也可以使用Modernizr JavaScript Library这个库,这个库提供了检查浏览器对HTML5特性支持的API。
最后,当前版本是一个早期版本,因此APIs有可能发生改变。另外,有些你期望能用的内容可能尚未支持。例如,当前还没有能够获取一个显示对象高度或宽带的方法(你可能自己已经发现了)。然而不管怎么样,这个库还是非常健壮的,并且已经应用到一下产品级的项目中了。
下面是一些可能对你开始通过EaselJS使用Canvas有用的资源:
-
o
- EaselJS Homepage
- EaselJS API Docs
- Modernizr JavaScript Library (for detecting support for HTML5 features).
- Canvas Element Draft Specification
- Canvas Element (Wikipedia)
- Let’s call it a draw(ing surface) Good introduction to the low level Canvas API.
- HTML5 Browser Support Matrix
- HTML5 and CSS3 Readiness
- HTML5 Support in your Browser
o
o
o
o
o
o
o
o
转载请注明原文出处《HTML5 Canvas和EaselJS入门(译)》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。