您的位置:首页 > Web前端 > HTML5

基于HTML5的简单游戏动画Demo_update1

2013-05-20 17:34 603 查看
demo运动的小球

update2碰撞检测

update3抛物运动和圆周运动
==========================~O(∩_∩)O~==========卖萌的分割线===========================================

前面的动画看起来还算不错,但我们很容易发现一个问题,那就是只能实现一个小圆的运动。为什么呢?原因是每次画布更新的时候都只对一个小圆有效。当然你可以在画布更新的函数里面添加其它小圆的位置信息,但这显然不是我们想要的,因为这会产生极其难以维护的代码。

下面的update1版实现了多个小圆的运动,而且不同小圆可以设置自己的运动方向、运动速度等。要实现这些效果,就需要更进一步了解关于动画的知识。

动画的实现原理就不多解释了。说到动画,不得不说帧,帧是动画中的基本单位,可以把帧理解为某个时刻的一个画面,动画就是连续时间段的帧序列的集合的顺序显示。有了帧的概念,我们的程序中也应该设计一个帧的对象,维护当前的画面。当然我们也可以维护一系列的帧对象,但在此Demo中没有必要,因为我们只关注当前帧。也就是说,我们只维护一个帧对象,让帧按帧频数定时更新。

update1版的Demo除了增加了帧对象之外,还重新设计了一下控制器——这是一个由程序自身维护的自动控制器,也就是说,这个控制器控制着小圆的自动移动,包括方向控制和边界碰撞反弹处理等。

下面看一下代码:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Moving Circle</title>
<script type="text/javascript">
/**	帧频
*	帧频就是每秒的帧数,这里采用每秒50帧,即帧频为50fps
*	用ifps表示计时间隔,这里为20ms,也就是每20ms播放一帧,对应帧频50fps
*/
var ifps = 20;
/**	帧结构设计
*	所谓帧就是某个时刻的画面,帧的作用就是获取某个时刻(通常是当前时刻)所有需要画到画布上的内容,然后把内容画在画布上
*	逐帧动画的实质就是帧的更新,或者是准备好一系列的帧,然后按顺序读取帧
*/
var Frame = function(ctx) {
this.sprites = new Array();				// 当前画布中的角色集合
this.ctx = ctx;							// 帧维护的画布(可以不止一个,这里只用一个)
}
Frame.prototype = {
refresh : function() {					// refresh方法把当前帧的内容画到画布上,就是更新整个画布
this.ctx.clearRect(0,0,1000,500);	// 清空画布
var num = this.sprites.length;
for(var i = 0; i < num; ++i) {		// 遍历全部内容
this.sprites[i].draw();			// 调用各自的draw方法
}
}
}
/**	角色类设计
*	类成员
*	x		:	location x
*	y		:	location y
*	speed	:	moving speed,with x direction & y direction
*	stop	:	moving controler	0:move,1:stop
*	stopl	:	left controler		0:left move,1:left stop
*	stopr	:	right controler		0:right move,1:right stop
*	stopu	:	up controler		0:up move,1:up stop
*	stopd	:	down controler		0:down move,1:down stop
*	类方法
*	draw	:	draw itself on the canvas
*	left	:	left moving
*	right	:	right moving
*	up		:	up moving
*	down	:	down moving
*/
var Sprite = function() {
this.speed = {
x : 1,			// 初始横向速度
y : 1			// 初始纵向速度
}
this.stop = 1;
this.stopl = 1;
this.stopr = 1;
this.stopu = 1;
this.stopd = 1;
}
Sprite.prototype = {
draw : function() {
},
left : function() {
this.x -= this.speed.x;
},
right : function() {
this.x += this.speed.x;
},
up : function() {
this.y -= this.speed.y;
},
down : function() {
this.y += this.speed.y;
}
}
/**	圆类:继承角色类
*	类成员(非父类成员)
*	ctx			:	用于绘制的Context,就是指定要绘制的画布
*	radius		:	半径
*	propotity	:	维护style的属性集,包括填充颜色、描边颜色、描边大小等
*	类方法
*	Circle		:	构造方法
*	draw		:	覆盖父类的自绘制方法
*	left		:	同父类
*	right		:	同父类
*	up			:	同父类
*	down		:	同父类
*/
var Circle = function(ctx,x,y,radius,style) {
this.ctx = ctx;
this.x = x;
this.y = y;
this.radius = radius;
this.propotity = {
fillStyle:"#acffac",
strokeStyle:"#000000",
lineWidth:"2"
};
}
Circle.prototype = new Sprite();
Circle.prototype.draw = function() {
this.ctx.beginPath();
this.ctx.lineWidth = this.propotity.lineWidth;
this.ctx.strokeStyle = this.propotity.strokeStyle;
this.ctx.fillStyle = this.propotity.fillStyle;
this.ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true);
this.ctx.stroke();
this.ctx.fill();
}
/**	自动控制器
*	该类实现角色的自动控制(而不是人为控制)
*	控制的方法有控制向上、向右、向下和向左四个方向的移动
*	控制器可以对边界作出检测并在碰到边界时反方向转移
*	注意不是沿原路返回,比如碰到右边界时向右改为向左,但是上下方向不改变(除非碰到上下边界)
*/
var AutoControler = function(aFrame) {
var self = this;					// self维护对象本身
this.currentFrame = aFrame;			// 维护当前帧对象
this.moveLeft = function(sth) {
if(sth.x < 5) {
sth.stopl = 1;				// 停止向左
sth.stopr = 0;				// 开启向右
this.moveRight(sth);		// 向右
}
if(sth.stopl == 0) {
sth.left();
this.currentFrame.refresh();
setTimeout(function(){self.moveLeft(sth);}, ifps);	// 实现自动控制的关键,通过定时器实现
}
}
this.moveRight = function(sth) {
if(sth.x > 995) {
sth.stopr = 1;				// 停止向右
sth.stopl = 0;				// 开启向左
this.moveLeft(sth);			// 向左
}
if(sth.stopr == 0) {
sth.right();
this.currentFrame.refresh();
setTimeout(function(){self.moveRight(sth);}, ifps);	// 实现自动控制的关键,通过定时器实现
}
}
this.moveUp = function(sth) {
if(sth.y < 5) {
sth.stopu = 1;				// 停止向上
sth.stopd = 0;				// 开启向下
this.moveDown(sth);			// 向下
}
if(sth.stopu == 0) {
sth.up();
this.currentFrame.refresh();
setTimeout(function(){self.moveUp(sth);}, ifps);		// 实现自动控制的关键,通过定时器实现
}
}
this.moveDown = function(sth) {
if(sth.y > 495) {
sth.stopd = 1;				// 停止向下
sth.stopu = 0;				// 开启向上
this.moveUp(sth);			// 向上
}
if(sth.stopd == 0) {
sth.down();
this.currentFrame.refresh();
setTimeout(function(){self.moveDown(sth);}, ifps);	// 实现自动控制的关键,通过定时器实现
}
}
}
</script>
</head>
<body>
<canvas id="zCanvas" width="1000" height="500" style="border:2px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
// 获取当前绘图区
var can = document.getElementById("zCanvas");
var ctx = can.getContext("2d");
// 创建帧对象
frame = new Frame(ctx);
// 构造两个角色
var ca = new Circle(ctx,20,25,10);
var cb = new Circle(ctx,100,80,10);
// 改变角色cb的属性
cb.propotity.fillStyle = "#ff0000";
cb.speed = {x:3,y:3};
// 把角色添加到帧
frame.sprites.push(ca);
frame.sprites.push(cb);
// 创建控制器对象
var controler = new AutoControler(frame);
// 设置角色的运动初态
ca.stopr = 0;
ca.stopd = 0;
cb.stopl = 0;
cb.stopd = 0;
// 开启自动控制
controler.moveRight(ca);
controler.moveDown(ca);
controler.moveLeft(cb);
controler.moveDown(cb);
</script>
</body>
</html>


运行效果就不给出了,因为是动态的,反正截图也看不出什么效果。chrome和IE10都运行通畅,其它浏览器没试过,不过一般支持HTML5的都没问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐