如何开发一个简单的HTML5画布游戏?

9秒学院游戏开发代码示例

创建画布

//创建画布

var canvas = document . createelement(" canvas ");

var CTX = canvas . get context(" 2d ");

帆布.宽度= 512;

canvas.height = 480

document . body . appendchild(canvas);

首先,我们需要创建一个画布作为游戏的舞台。HTML,编写一个

准备图片

//背景图片

var bgReady = false

var bgImage = new Image();

bgImage.onload = function () {

bgReady = true

};

bgimage . src = " images/background . png ";

游戏少不了图片,先加载一些图片吧。为了简单起见,这里只创建简单的图片对象,而不是编写一个类或者Helper来加载图片。变量bgReady用于标识图片是否已经加载,是否可以安全使用,因为如果图片是在没有加载的情况下绘制的,会给出错误。

我们用上面的方法来处理整个游戏中需要的三个画面:背景,英雄,怪物。

游戏对象

//游戏对象

var hero = {

速度:256,//像素每秒移动

x: 0,

y: 0

};

var monster = {

x: 0,

y: 0

};

var monster catch = 0;

现在定义一些稍后会用到的对象。我们的英雄有一个速度属性来控制他每秒移动多少像素。游戏过程中怪物不动,只有坐标属性就够了。monsters catch用于存储怪物被抓的次数。

处理用户输入

//处理键

var keydown = { };

addEventListener("keydown ",函数(e) {

keys down[e . keycode]= true;

},假);

addEventListener("keyup ",函数(e) {

删除keydown[e . keycode];

},假);

现在开始处理用户的输入(对于刚接触游戏开发的前端同学来说,这个部分一开始可能需要一些脑力)。在前端开发中,用户通常会在执行动画或者发起异步请求之前触发点击事件,但是这里我们希望游戏的逻辑能够更加紧凑,能够及时响应输入。所以我们首先保存用户的输入,而不是立即响应。

为此,我们使用keysDown对象来存储用户按下的键码。如果按下的键值在这个对象中,那么我们将相应地处理它。

开始游戏

//当用户抓到怪物时,开始新一轮游戏。

var reset = function () {

hero . x = canvas . width/2;

hero . y = canvas . height/2;

//在界面上随意放新的怪物。

monster . x = 32+(math . random()*(canvas . width-64));

monster . y = 32+(math . random()*(canvas . height-64));

};

重置方法用于开始新一轮的和平游戏。在这个方法中,我们把英雄放回画布的中心,把怪物放在一个随机的地方。

更新对象

//更新游戏对象的属性

var update = function (modifier) {

if(keydown中的38){//用户按下了↑。

hero.y -= hero.speed *修改器;

}

if(40 in keydown){//用户按下了↓

hero.y += hero.speed *修改器;

}

if(keydown中的37){//用户按下了键。

hero.x -= hero.speed *修改器;

}

if(39 in keydown){//用户按下→

hero.x += hero.speed *修改器;

}

//英雄和怪物相遇了吗?

如果(

hero.x & lt= (monster.x + 32)

& amp& ampmonster.x & lt= (hero.x + 32)

& amp& amphero.y & lt= (monster.y + 32)

& amp& ampmonster.y & lt= (hero.y + 32)

) {

++ monster scatter;

reset();

}

};

这是游戏中用来更新画面的更新功能,会定期反复调用。首先,它负责检查用户当前是否按住了中间的方向键,然后在相应的方向上移动英雄。

可能就是这个传入的修饰变量需要一点脑力。你可以去main。

在方法中看到它的来源,但是这里有必要详细解释一下。是一个从1开始,随时间变化的因子。比如1秒过去了,它的值就是1,英雄的速度会乘以1,也就是每秒移动256个像素;如果用了半秒,那么它的值就是0.5,英雄的速度乘以0.5,也就是说英雄在这半秒内的移动速度是正常速度的一半。理论上,由于这次更新,

方法调用的非常快,非常频繁,所以modifier的值会很小,但是有了这个因素,无论我们的代码运行的有多快,都可以保证英雄的移动速度是恒定的。

既然英雄的移动是基于用户的输入,那么就该检查移动过程中触发的事件了,也就是英雄遇到了怪物。这是这场游戏的胜利,怪兽捕手。

+1,开始新一轮。

渲染一个对象

//绘制所有对象

var render = function () {

如果(bgReady) {

ctx.drawImage(bgImage,0,0);

}

if (heroReady) {

ctx.drawImage(heroImage,hero.x,hero . y);

}

if (monsterReady) {

ctx.drawImage(monsterImage,monster.x,monster . y);

}

//分数

ctx.fillStyle = "rgb(250,250,250)";

CTX . font = " 24px Helvetica ";

ctx.textAlign = " left

ctx.textBaseline = " top

CTX . fill text(" monster RS catched:"+monster scapped,32,32);

};

之前的工作很无聊,直到你把一切都画出来。首先当然是画背景。然后做同样的事情,画英雄和怪物。这个过程中的顺序是有讲究的,因为后面画的对象会覆盖前面的对象。

之后我们改变了Canvas的绘制上下文的样式,调用fillText来绘制文本,也就是记分板部分。这款游戏没有其他复杂的动画效果和打斗场面,画图部分就搞定了!

主循环函数

//游戏主功能

var main = function () {

var now = date . now();

var delta = now-then;

更新(delta/1000);

render();

那么=现在;

//立即调用main函数

requestAnimationFrame(main);

};

上面的主函数控制着整个游戏的流程。首先,获取当前时间来计算时差(自从最后一次调用main函数以来已经过去了多少毫秒)。得到修饰符后,除以1000(即1秒的毫秒数),并将其传入更新函数。最后调用render。

函数并节省时间。

关于游戏中画面循环更新的讨论,请参考猛攻!竞技场案例研究.

循环的进一步解释

RequestAnimationFrame的浏览器兼容性处理

var w =窗口;

requestAnimationFrame = w . requestAnimationFrame | | w . webkitrequestanimationframe | | w . msrequestanimationframe | | w . mozrequestanimationframe;

如果你没有完全理解上面的代码也没关系,我只是认为解释它总是很棒的。

为了循环调用main函数,之前游戏用的是setInterval。但是现在有了更好的方法,那就是requestAnimationFrame。使用新方法,你必须考虑浏览器的兼容性。上面的垫片就是这个原因,而且是原来保罗爱尔兰博客的简化版。

开始游戏!

//小子,我们开始游戏吧!

var then = date . now();

reset();

main();

终于完成了,这是这个游戏的最后一个代码。首先,设置一个初始时间变量,首先运行主函数。然后打电话

重置

函数开始新一轮的游戏(如果你还记得的话,函数是把英雄放在画面中间,把怪物放在随机的地方,让英雄可以抓到)。

至此,我相信您已经掌握了开发一个简单的H5游戏所需的基本技能。玩这个游戏或者下载代码自己研究:)