基于HTML5的简单游戏动画Demo_update1

这篇博客介绍了如何使用HTML5实现简单的游戏动画,从update1版开始,增加了多个小圆的运动功能,并实现了碰撞检测。通过创建帧对象和自动控制器,实现了小圆的自动移动、方向控制和边界反弹。更新还包括抛物运动和圆周运动的演示。
摘要由CSDN通过智能技术生成


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的都没问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值