demo运动的小球
update1添加多个角色
update2碰撞检测
update3 抛物运动和圆周运动==========================~O(∩_∩)O~==========卖萌的分割线===========================================
本篇章为《基于HTML5的简单游戏动画Demo》系列的持续更新篇,所有更新内容和更新日期如下。
==========================~O(∩_∩)O~==========卖萌的分割线===========================================
6月14日更新:
1、使用图片作为sprite的动画demo;
2、sprite图片的制作要点。
先前做的所有Demo都是直接用canvas画图,对于简单的图形如矩形、圆形、直线曲线等都没有问题,但是仅用这些元素做游戏未免有些单调(不是说不可以,但是在很大程度上限制了游戏制作的范畴)。
实际上现在大多数2d游戏,都是用图片实现动画,flash游戏如此,C++游戏如此,当然HTML5游戏也可以。所以,这次更新给大家带来一个用图片实现的角色动画。动画非常的简单,就是角色的行走,包括上下左右四个方向,当然玩家可以控制角色的运动。
利用图片实现角色动画的原理很简单,就是事先准备好角色的运动图片,不是单一的图片,而是运动的每一帧图片。如果你了解角色运动的规律,不会画角色的运动关键帧,你可能不得不找一个游戏美工帮你的忙了。当然网上也有很多素材,这次我用到的图片也是从网上下载的素材。
关于角色的运动规律我就不说了。当你获得角色运动的每一帧图片之后,你要做的不是马上开始敲代码,而是整理好你的图片。第一,所有的图片大小必须一样,当然角色的大小和位置在每一帧中也要对应;第二,背景最好是透明的。
整理好你的图片之后,就可以写代码了。实现角色动画的原理是:设置一个定时器,让定时器每隔一段时间显示你的角色的一帧,然后读下一帧,如此循环。这和之前的动画Demo原理是一样的,只不过现在要做的不是绘制图形,而是绘制图片。
关于绘制图片,据我所知有两种方法(这里仅讨论canvas绘制方法,不考虑dom方法,若考虑dom方法,那就不止两种):一种是每次绘制不同的图片,也就是角色动作的每一帧做成单张图片显示;另一种主流的方法是,把所有图片打包到一张图片里面,利用drawImage方法可以只绘制图片的一部分这一特性,我们通过裁剪区域指定每次要显示的帧。
这次的Demo用到的就是主流的方法。图片是网上下载的,单帧32*48,打包后大小为128*192。如下所示:
然后就是实现的代码。代码写得比较简单,但是实现了基本的功能:可以控制角色的运动方向(上下左右),并且带有边界检测。请使用小键盘的方向键或wasd控制角色。
<!DOCTYPE>
<html>
<head>
<title>HTML5 Game Demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
// 常量
var cvsW = 500;
var cvsH = 300;
var spriteW = 32;
var spriteH = 48;
// 源图像
var img = new Image();
img.src="lings.png";
// 全局变量
var sid = 0; // sprite的动作id,上下左右四个动作
var sidx = 0; // 每个动作的单帧的id,每个动作4帧
var stepx = 0; // 移动步长,用于控制速度和方向
var stepy = 0; // 移动步长,用于控制速度和方向
var lx = 0; // 当前sprite的位置x
var ly = 0; // 当前sprite的位置y
// 绘制sprite的方法,用setTimeout设置循环
function drawSprite() {
var sx = spriteW*sidx;
var sy = spriteH*sid;
ctx.clearRect(0, 0, cvsW, cvsH);
ctx.drawImage(img, sx, sy, spriteW, spriteH, lx, ly, spriteW, spriteH);
lx += stepx;
if(lx >= cvsW-spriteW || lx <= 0) stepx = 0; // 边界检测
ly += stepy;
if(ly >= cvsH-spriteH || ly <= 0) stepy = 0; // 边界检测
sidx += 1;
sidx = ((sidx>=4) ? 0 : sidx);
setTimeout(drawSprite, 100);
};
/** class control
* control用于控制sprite的运动方向,有上下左右四个移动方法
*/
function control() {
this.moveUp = function() {
sid = 3;
stepx = 0;
stepy = -5;
if(ly <= 0) stepy = 0; // 边界检测
};
this.moveDown = function() {
sid = 0;
stepx = 0
stepy = 5;
if(ly >= cvsH-spriteH) stepy = 0; // 边界检测
};
this.moveLeft = function() {
sid = 1;
stepy = 0;
stepx = -5;
if(lx <= 0) stepx = 0; // 边界检测
};
this.moveRight = function() {
sid = 2;
stepy = 0;
stepx = 5;
if(lx >= cvsW-spriteW) stepx = 0; // 边界检测
};
}
var ctl = new control();
// 该方法响应键盘事件
function keyDownOperator(key) {
switch(key) {
case 38:
case 87:ctl.moveUp();break;
case 40:
case 83:ctl.moveDown();break;
case 37:
case 65:ctl.moveLeft();break;
case 39:
case 68:ctl.moveRight();break;
}
}
</script>
</head>
<body onkeydown="keyDownOperator(event.keyCode)">
<canvas id="mycvs" width="500" height="300" style="border:2px solid #888888;"></canvas>
<script type="text/javascript">
var cvs = document.getElementById("mycvs");
var ctx = cvs.getContext("2d");
drawSprite();
</script>
</body>
</html>
运行效果截图:
大家可以试一试,本人在chrome下测试没有任何问题。
先更新到这吧O(∩_∩)O