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

基于HTML5的简单游戏动画Demo_update3

2013-05-31 13:13 477 查看
demo运动的小球

update1添加多个角色

update2碰撞检测

==========================~O(∩_∩)O~==========卖萌的分割线===========================================
5月结束前最后一次更新。
和update2相比,这次的新增点包括:

1、匀加速运动。包括两个方向(x和y),程序将给出“y方向的匀加速和x方向的匀速”合运动示例,也就是常见的抛物运动。

2、圆周运动。圆周运动的模型和原来的运动模型不匹配,如果从物理的角度看,圆周运动是由于物体受到向心力而产生的,其中涉及到向心加速度、角速度等问题,过于复杂。这里区别于原来的位移、速度、加速度模型,另外设置了运动圆心、角度、半径模型,从而从纯几何的角度实现圆周运动。当然,边界检测对这个模型就不适用了。

3、模拟碰撞(仅边界检测)使物体减速的效果。在实际场景中,一个物体掉到地上再弹起不可能再回到原来的高度,因为碰到地面后由于形变和阻力等原因导致物体的能量减小,也就是速度变慢。这里采用最简单的方法模拟物体速度变慢的效果。

先来看效果:





动态截图跳帧很厉害,如果想看原来的效果,自己复制粘贴源码到html文件和js文件用浏览器运行一下吧!

另外,碰撞检测的解决方法还没想好,所以干脆先不要碰撞检测了,原来的代码还在,只是暂时没有用到。

下面是这次的源码:

javascript文件

/**	碰撞检测方法
*	关于碰撞检测的具体方法在写物理引擎的时候再继续完善
*/
function CollisionDetect(spriteA, spriteB) {
var length = Math.sqrt((spriteA.x-spriteB.x)*(spriteA.x-spriteB.x) + (spriteA.y-spriteB.y)*(spriteA.y-spriteB.y));
var minLength = spriteA.radius+spriteB.radius;
if(length <= minLength) {		// 如果碰撞了,停止
spriteA.speed.x = 0;
spriteA.speed.y = 0;
spriteB.speed.x = 0;
spriteB.speed.y = 0;
}
};
/**	边界检测
*	边界检测方法:当前只对MoveXY运动的物体有效
*/
function BoundDetect(sprite) {
if(sprite.x > 1000-sprite.radius || sprite.x < sprite.radius) {
sprite.velocity.vx *= (-1);			// 反向
sprite.velocity.vx += sprite.ax;	// 速度调整
}
if(sprite.y > 500-sprite.radius || sprite.y < sprite.radius) {
sprite.velocity.vy *= (-1);			// 反向
sprite.velocity.vy += sprite.ay;	// 速度调整
}
};
function BoundDetect2(sprite) {					// 添加了阻力的碰撞检测
if(sprite.x > 300-sprite.radius || sprite.x < sprite.radius) {
sprite.velocity.vx *= (-1);			// 反向
sprite.velocity.vx += 3*sprite.ax;	// 速度调整
if(sprite.velocity.vx < 0 && sprite.velocity.vx > -1) {
sprite.velocity.vx = 0;
sprite.ax = 0;
}
}
if(sprite.y > 500-sprite.radius || sprite.y < sprite.radius) {
sprite.velocity.vy *= (-1);			// 反向
sprite.velocity.vy += 3*sprite.ay;	// 速度调整
if(sprite.velocity.vy < 0 && sprite.velocity.vy > -1) {
sprite.velocity.vy = 0;
sprite.ay = 0;
}
}
};
/**	帧频
*/
var ifps = 1000/60;							// 帧频为60fps
/**	帧对象
*/
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方法
}
}
}
/**	角色类设计
*/
var Sprite = function() {
this.ax = 0;				// 初始加速度ax
this.ay = 0;				// 初始加速度ay
this.velocity = {
vx : 1,					// 初始横向速度
vy : 1					// 初始纵向速度
};
this.round = {				// 圆周运动相关参数
angularVelocity : -1,	// 角速度
roundRadius : 0,		// 圆周运动半径
angle : 0,				// 初始角
centerX : 0,			// 圆心x
centerY : 0				// 圆心y
}
};
Sprite.prototype = {
draw : function() {
},
moveXY : function() {
this.x += this.velocity.vx;
this.y += this.velocity.vy;
this.velocity.vx += this.ax;
this.velocity.vy += this.ay;
},
moveRound : function() {
var rm = this.round;
rm.angle += rm.angularVelocity;
rm.angle = rm.angle >= 360 ? 0 : rm.angle;
this.x = rm.centerX + rm.roundRadius * Math.cos(rm.angle*(Math.PI/180));
this.y = rm.centerY + rm.roundRadius * Math.sin(rm.angle*(Math.PI/180));
}
};
/**	圆类:继承角色类
*/
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) {
this.currentFrame = aFrame;
this.spriteSet;
};
AutoControler.prototype = {

addSprite : function(aSprite) {				// 添加角色的方法
if(!this.spriteSet){
this.spriteSet = new Array();
}
this.spriteSet.push(aSprite);
},

move : function() {							// 控制角色运动的方法
var self = this;
var arr = this.spriteSet;
var len = arr.length;
for(var i = 0; i < len; ++i) {
if(arr[i].round.angularVelocity == -1) {
arr[i].moveXY();
}
else {
arr[i].moveRound();
}
}
this.currentFrame.refresh();
for(var i = 0; i < len; ++i) {
BoundDetect(arr[i]);				// 边界检测:检测每一个角色
//for(var j = 0; j < len; ++j) {
//	if(i == j) continue;
//	CollisionDetect(arr[i], arr[j]);
//}
}
setTimeout(function(){self.move();}, ifps);
},

move2 : function() {						// 碰撞后速度减小
var self = this;
var arr = this.spriteSet;
var len = arr.length;
for(var i = 0; i < len; ++i) {
if(arr[i].round.angularVelocity == -1) {
arr[i].moveXY();
}
else {
arr[i].moveRound();
}
}
this.currentFrame.refresh();
for(var i = 0; i < len; ++i) {
BoundDetect2(arr[i]);				// 边界检测:检测每一个角色
}
setTimeout(function(){self.move2();}, ifps);
}

};


html文件

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Moving Circle</title>
<script src="demo.js"></script>
</head>
<body>
<canvas id="zCanvas" width="1000" height="500" style="border:2px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<canvas id="small" width="300" 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);
// 构造7个角色
var ca = new Circle(ctx,80,80,10);
var cb = new Circle(ctx,20,20,10);
var cc = new Circle(ctx,50,300,10);
var cd = new Circle(ctx,800,100,10);
var ce = new Circle(ctx,500,200,10);
// 改变角色cb的属性
cb.propotity.fillStyle = "#ff0000";
cb.velocity = {vx:0, vy:0};
cb.ay = 0.3;
// 改变角色cc的属性
cc.propotity.fillStyle = "#8888aa";
cc.velocity = {vx:5, vy:0};
cc.ay = 1;
// 改变角色cd的属性
cd.propotity.fillStyle = "#0000ff";
cd.velocity = {vx:3,vy:1};
// 改变角色ce的属性
ce.propotity.fillStyle = "#aaff00";
ce.velocity = {vx:1,vy:2};
// 创建做圆周运动的角色
var cr = new Circle(ctx,80,80,10);
var cs = new Circle(ctx,80,80,10);
// 修改cr属性
cr.propotity.fillStyle = "#aa55bb";
cr.round = {angularVelocity : 5, roundRadius : 50, angle : 0, centerX : 200, centerY : 200};
// 修改cs属性
cs.propotity.fillStyle = "#ffcc88";
cs.round = {angularVelocity : 5, roundRadius : 80, angle : 0, centerX : 500, centerY : 200};
// 把角色添加到帧
frame.sprites.push(ca);
frame.sprites.push(cb);
frame.sprites.push(cc);
frame.sprites.push(cd);
frame.sprites.push(ce);
frame.sprites.push(cr);
frame.sprites.push(cs);
// 创建控制器对象
var controler = new AutoControler(frame);
controler.addSprite(ca);
controler.addSprite(cb);
controler.addSprite(cc);
controler.addSprite(cd);
controler.addSprite(ce);
controler.addSprite(cr);
controler.addSprite(cs);
controler.move();
////////////////////////////////////////////////////////////////////////////////////////////
var canr = document.getElementById("small");
var ctxr = canr.getContext("2d");
var framer = new Frame(ctxr);
var cra = new Circle(ctxr,50,50,20);
cra.propotity.fillStyle = "#ff8888";
cra.velocity = {vx:3, vy:0};
cra.ay = 0.5;
framer.sprites.push(cra);
var controlerr = new AutoControler(framer);
controlerr.addSprite(cra);
controlerr.move2();
</script>
</body>
</html>


注意改一下js文件名。

从下一次更新开始,所有的更新将在下一篇文章里面整理,不会再另开新的文章。另外,基于html5的游戏物理引擎的文章将会发布。

物理引擎部分将会以该系列为基础进行讲解。敬请期待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐