近期看了几本老外的书,学习了一些大神们的博客,接触了一下火的不得了的canvas做游戏,把自己的学习过程分享出来。
1.游戏的基本内容
1.1什么是动画
动画是通过连续播放一系列画面,给视觉造成连续变化的图画。它的基本原理与电影、电视一样,都是视觉原理。医学已证明,人类具有视觉暂留的特性,就是说人的眼睛看到一幅画或一个物体后,在1/24秒内不会消失。利用这一原理,在一幅画还没有消失前播放出下一幅画,就会给人造成一种流畅的视觉变化效果。因此,电影采用了每秒24幅画面的速度拍摄播放,电视采用了每秒25幅(PAL制,中央电视台的动画就是PAL制)或30幅(NSTC制)画面的速度拍摄播放。如果以每秒低于24幅画面的速度拍摄播放,就会出现停顿现象。
从播放效果上看,分为顺序动画(连续动作)和交互式动画(反复动作)。逐帧动画是一种常见的动画形式(Frame By Frame),其原理是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成动画。
1.2使用HTML5来做动画
HTML5制作的动画主要是逐帧动画。目前主要有DOM, SVG与Canvas三种方式来实现。在此我们主要讨论Canvas方式来制作动画。
Canvas的支持
到目前为止,基本所有浏览器
的最新版本均提供了对canvas的全面支持。基于“渐近增强,优雅降级”的移动互联网应用体验,如果用户使用的浏览器版本较低,可以在canvas标签中写入信息来提示用户升级浏览器。如:
<canvas>您的浏览器不支持此动画,请升级您的浏览器</canvas>
如果要使用编程的方式来检测对于canvas的支持程度,可以使用如下代码:
if(document.createElement(“canvas”).getContext(“2d”)){
console.log(“当前浏览器支持canvas”);
}
当然,也可以引入第三方的开源JavaScript库(http://code.google.com/p/explorercanvas/),在不支持canvas的浏览器中来模拟canvas的各种API。由于各个设备及浏览器版本的实现方式不同,为了保证用户得到一致的体验,我们需要在尽可能多的设备及浏览器上对我们的游戏进行测试及调优。
HTML5基本文档模板
我们的游戏需要在一个HTML文档中的canvas标签中渲染,在此我们创建一个最基本的HTML文档模板。如下
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>base canvas</title>
<link rel="stylesheet" type=”text/css” href="style.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type=”text/javascript”>
window.onload = function () {
};
</script>
</body>
</html>
简单浏览一下,刚开始我们定义了HTML5文档类型,之后定义了header标签,引用了外部的CSS文件。然后在body中定义了一个canvas标签来做为我们的游戏渲染容器。在body标签结束前,我们创建了一个script标签,在其中来使用JavaScript来实现我们的游戏(之所以在header中使用link标签来加载外部css文件,或在body结束标签前再定义script标签、引入外部JavaScript文件,是为了保证页面的逐步呈现速度,保证浏览器更高效地渲染HTML页面,提高脚本下载的并行度,参见Steve Souders大神的《高性能网站建设指南》).
可以看到,在脚本中我们为window对象的onload事件指定了回调函数,即在所有的文档元素加载完成后,再执行回调函数中的程序。这可以保证canvas标签在我们使用之前已经创建成功。当然,如果当前的HTML文档中有大量的资源(如图片,音乐等)需要加载,那我们的window.onload事件会需要等待很长的时间才能执行,在这种情况下最好是使用脚本来动态加载相应的资源,之后会介绍到相关的知识。
其它
随着开发游戏的复杂度增加,我们的代码量及程序复杂度会随之增长,这就需要我们对游戏进行建模,将代码按一定的规则放置在外部脚本文件中引入。
同时,游戏开发中一个好的编辑器与调试工具也会得到事半功倍的效果。在此我们使用
sublime text2
来做为编辑器,使用
chrome
中的开发人员工具来做为调试工具。
1.3 逐帧动画
因为
canvas
动画是逐帧动画,所以我们需要有一个循环来控制动画中的每一帧的渲染。而对于每一帧动画的渲染,会按如下序列进行:
a.
执行计算当前帧动作的所有代码,将其结果调用
canvas API
放入内存
b.
将内存中当前帧渲染到
canvas
容器中
c.
进入下一帧的处理流程(通常会在此时擦除画布)
在
JavaScript
中,有两个函数
setTimeout
与
setInterval
通常用来进行相关的计时调用。
setTimeout
只会执行回调函数一次,
setInterval
会每隔
X
毫秒执行函数一次。但这两个函数均不是为开发游戏而生,都存在着一些问题。
基于
JavaScript
引擎的计时策略,以及本质上的单线程运行方式,所以其它代码的运行可能会阻塞此线程。因此没法确保
函数会在
setTimeout
指定的时刻被调用。而当回调函数的执行被阻塞时,
setInterval
仍然会发布更多的毁掉指令。在很小的定时间隔情况下,这会导致回调函数被堆积起来。所以通常我们不建议使用
setInterval,
而是采用
setTimeout
来替代,最简单的处理回调函数被阻塞的情况就是在回调函数中再调用
setTimeout.(
具体参见
JavaScript
Garden
http://bonsaiden.github.com/JavaScript-Garden/zh/
)
.
但是,随着对动画的流畅度要求提高,如果有大量定时器在同时运行,这些定时器之间的调度会对性能有轻微的影响。一种解决方案就是实现一个采用帧管理的动画框架,通过一个定时器触发动画帧,不同的动画来注册这些帧,在每一帧上处理多个动画的属性变化。这样的好处是减少了定时器调度的开销,但是对于动画框架的开发者来说,统一帧管理、提供监听帧的API等,都是需要开发和维护的。浏览器厂商目前提供一个专门做动画的方法,即requestAnimationFrame(),从浏览器的层面对帧动画进行了优化,如下代码示例(参见http://paulirish.com/2011/requestanimationframe-for-smart-animating/)。
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
(function animloop(){
requestAnimFrame(animloop);
render();
})();
1.4
JavaScript对象知识
JavaScript是一个基于对象的语言,它的对象就是一种包含属性的特殊的数据结构,这此属性可以是变量,函数或其它对象。同时JavaScript对象可以随时被动态改变。如:
var objectA={};
objectA.name=”objectA”;
如果我们需要同时创建同一类型的对象,可以使用构造函数的形式。JavaScript的构造函数是一种特殊的函数,它可以基于设置给自身的属性来生成对象。在创建了构造函数后,我们就可以使用new关键字来生成对象了。如:
function Animal(name){
this.name=name || “animal”;
this.say=function(){ console.log(this.name);
}
var dog=new Animal(“dog”); dog.say();
var cat=new Animal(“cat”); cat.say();
JavaScript是基于原型的一种语言。在我们创建了一个新的对象实例时,实际是我们是创建了一个对象,这个对象继承了构造函数的原型链(具体参见《JavaScript面向对象编程》及http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance.html
或http://7685941014.blog.163.com/blog/static/124615480201061782347164/
)
function Person(name){
this.name=name;
console.log(this.name);
}
function Student(name,school){
Person.call(this,name);
this.school=school;
}
Student.prototype=new Person();
Student.prototype.constructer=Student;
由于JavaScript的函数也是一种对象,所以,可以给函数设置属性及方法。比如很多时候我们使用的回调方法等。如:
var person=[“Jim”,”James”,”Kimmy”];
person.forEach(function(o,i){ console.log(i+”,”+o); }
直接构造for循环或者使用forEach方法来遍历Array的所有元素,在Array对象的元素数目很大的情况下,使用forEach方法会有效率上的问题。与此类似,在使用for…in 循环来遍历对象的所有属性时,如果对象的原型链嵌套层次比较深,也会导致效率上有问题。(for … in不能遍历出enumerable为false的属性,如Array的length属性)。
1.5用户交互
游戏的核心在于用户交互性,用户交互是基于事件的。事件包括监听器及事件处理。在canvas上绘制的图形自身不支持DOM事件检测,只有canvas标签自身支持DOM整件监听。因此需要对canvas容器的事件进行处理,实现相对事件监听及处理。
按W3C的规范http://www.w3.org/TR/DOM-Level-3-Events ,我们可以为对象注册事件,如下:
element.addEventListener(type, handler [, useCapture]);
一个典型监听鼠标点击的事件如下:
canvas.addEventListener('mousedown', function (event) {
console.log("Mouse pressed on element!");
}, false);
换句话说,每一个对象都订阅了指定的事件触发事件,在该事件触发时,会将此信息广播给所有订阅其信息的对象,此对象再调用对应的事件触发回调函数来进行处理。如果我们想注销某一个事件,则使用
element.removeEventListener(type, handler [, useCapture]);
鼠标事件
鼠标事件包括mousedown,mouseup,mouseover等。如果需要获取鼠标位置时,在监听到mousemove事件响应后,可做如下处理:
var utils={};
utils.cpatureMousePosition=function(element){
var mouse={x:0,y:0};
element.addEventListener("mousemove",function(event){
var x,y;
if(event.pageX||event.pageY){
x=event.pageX;
y=event.pageY;
}else{
x=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft;
y=event.clientY+document.body.scrollTop+document.documentElement.scrollTop;
}
x-=element.offsetLeft;
y-=element.offsetTop;
mouse.x=x;
mouse.y=y;
},false);
return mouse;
};
具体的原因在于各个浏览器对于鼠标位置的处理实现方式与提供的接口不同:参见http://www.seobye.com/div-css/87/及http://javascript.about.com/library/blmousepos.htm,可以在页面中使用上面定义的方法:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Get Mouse Position</title>
<link rel="stylesheet" type=”text/css” href="style.css">
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type=”text/javascript”>
window.onload = function () {
var canvas=document.getElementById(“canvas”);
var mouse=utils.captureMousePosition(canvas);
(function drawFrame(){
window.requestAnimFrame(drawFrame,canvas);
console.log(mouse.x+”,”+mouse.y);
})();
};
</script>
</body>
</html>
键盘事件
有两个键盘事件——keydown与keyup。可以通过event.keyCode (https://github.com/lamberta/html5-animation/blob/master/xtras/keycode.js )来获取当前键盘值的ASCII值。然后使用switch来区分处理具体的按键并加以处理。如下:
element.addEventListener(“keyup”,function(event){
switch(event.keyCode){
case: break;
}
},false);
分享到:
相关推荐
"HTML5 Canvas游戏开发实战"这本书正是针对这一技术领域,通过实战案例来深入讲解如何利用Canvas进行游戏开发。 本书的重点可能会包括以下几个方面: 1. **Canvas基础**:首先,书会介绍Canvas的基本概念和语法,...
在这个"HTML5 Canvas核心技术图形、动画与游戏开发"的PDF扫描版中,读者可以深入学习到Canvas的核心概念和实践技巧。 首先,Canvas的基本使用方法是通过JavaScript API来实现的。这个API提供了大量的绘图命令,如`...
在微信小程序中,Canvas是一个非常重要的组件,它允许开发者在...以上就是关于"小程序canvasDemo"项目中涉及的主要技术点,通过学习和实践,你可以掌握微信小程序中canvas的使用技巧,进一步提升你的小程序开发能力。
HTML5的Canvas是一个强大的绘图API,它允许开发者在网页上进行动态的、基于...随着对Canvas的深入理解和实践,你会发现它的潜力无穷无尽。在实际项目中,可以结合CSS3、WebGL等技术,构建更复杂的交互式Web应用。
HTML5 Canvas是Web开发中的一个强大工具,它允许开发者在网页上进行动态图形绘制,创造出丰富的交互式用户体验。在这个“html5_canvas_...这样的实现不仅方便分享,也为开发者提供了一个学习和实践Canvas API的好平台。
这个功能在很多场景下都非常有用,比如网页分享、游戏截图、在线编辑器保存草图等。 首先,我们要了解canvas的基本用法。canvas是一个矩形画布,通过JavaScript来控制它的内容。我们可以通过`<canvas>`标签在HTML中...
《canvas+js绘制图形的实践探索》 在Web开发领域,HTML5的canvas元素提供了一种强大的机制,允许开发者在浏览器上进行动态图形绘制。这篇博文将深入探讨如何结合JavaScript,利用canvas API来构建一个简单的绘图小...
这本书——"HTML5 Canvas实战"显然深入探讨了这一技术,并提供了实践案例,非常适合前端开发者深入学习和提升技能。 Canvas是HTML5标准的一部分,它提供了一个二维绘图上下文,可以通过JavaScript来绘制图形,包括...
HTML5 Canvas是Web开发中的一个关键技术,...通过学习和实践这些HTML5 Canvas的核心技术,开发者可以构建出交互性强、视觉效果丰富的Web应用程序,无论是数据可视化、游戏开发还是艺术创作,Canvas都能提供强大的支持。
这篇博客"canvas画图测试"可能涉及了使用Canvas进行图形绘制的基础知识和实践技巧。Canvas API的使用通常包括以下几个核心知识点: 1. **Canvas元素**:在HTML中,`<canvas>`标签定义了一个可编程的画布,通过...
"android游戏源码分享"这个主题,正是一个汇集了国外开源社区Android游戏源码的集合,旨在促进开发者之间的交流与合作。 首先,Android游戏源码的学习对于初学者或有经验的开发者都至关重要。通过阅读源码,我们...
在“HTML5 Canvas学习笔记(6)拼图游戏(数字版)”这篇博文中,作者分享了如何利用Canvas构建一个数字拼图游戏。下面我们将详细探讨这个知识点。 1. **HTML5 Canvas基础**: - Canvas是一个基于矢量图形的画布元素...
在现代互联网技术的推动下,H5游戏已经成为一种广受欢迎的娱乐形式,尤其在移动设备上,其便捷性和跨平台特性使得H5游戏源码备受开发者关注。本文将以“熊出没”跑酷游戏为例,深入探讨H5游戏的开发技术、源码结构...
弹幕源自日本的弹幕视频分享网站,是指用户在观看视频时发送的文字评论,这些评论以滚动、飞过或淡入淡出等方式出现在屏幕上,营造出一种仿佛有无数文字“子弹”穿越屏幕的效果。在HTML5 Canvas上实现弹幕,我们需要...
H5游戏源码的分享,对于学习者来说是一次宝贵的实践机会,可以了解游戏逻辑、动画效果、用户交互等核心元素的实现方法。 【标签】"游戏":游戏是软件的一种类型,它可以提供娱乐、挑战或教育功能。H5游戏作为游戏的...
HTML5 Canvas API是Web开发中的一个强大工具,它允许开发者在网页上绘制2D图形,创建动态、交互式的游戏和应用程序。在这个项目中,“games:使用canvas api开发一堆HTML游戏以使其更好,并且仅使用HTML/CSS/JS堆栈...
`canvas`是Web开发中的一个强大工具,为开发者提供了丰富的图形处理能力,使得创建复杂的交互式图形、动画以及游戏成为可能。 `canvas`标签是一个矩形区域,通过JavaScript来控制其上的绘图操作。以下是一些核心...
【标题】:“JS制作的一个类似google应用的小游戏” 在标题中提到的“JS制作的一个类似google应用的小游戏”,我们可以理解为这是一个使用JavaScript编程语言开发的、模仿谷歌应用程序风格的互动娱乐项目。...
微信小程序“跳一跳”是一款深受用户喜爱的轻量级休闲游戏,它的设计简洁而富有挑战性,通过控制小方块跳跃,不断前进,玩家在享受游戏乐趣的同时,也能锻炼反应速度和空间判断能力。本资源包含“跳一跳”小游戏的...
8. **性能优化**:分享关于Canvas性能的技巧,如批处理绘图操作、使用图像数据缓冲区和避免不必要的重绘。 9. **高级应用**:深入探讨更复杂的用例,如粒子系统、游戏开发、图表绘制和数据可视化。 10. **实践案例...