【译】html5游戏入门

原文链接

简介

如果你想用canvas做个游戏,那么来对地方了。

但是但是你至少知道javascript怎么拼写(╯‵□′)╯︵┻━┻

既然没问题,那先来一下或者下载

创建canvas标签

废话不多说,我们必须创建一个canvas标签,简单起见,用一下不喜欢的jQuery

var CANVAS_WIDTH = 480;
var CANVAS_HEIGHT = 320; var canvasElement = $("<canvas width='" + CANVAS_WIDTH +
"' height='" + CANVAS_HEIGHT + "'></canvas>");
var canvas = canvasElement.get(0).getContext("2d");
canvasElement.appendTo('body');

游戏循环

为了能够让游戏平滑动画,我们用30帧的频率。

var FPS = 30;
setInterval(function() {
update();
draw();
}, 1000/FPS);

现在我们可以先给这两个函数放置play,重要的是setInterval函数会定期照顾他们的。

hello world

现在我们有了这个循环,让我们开始画东西吧~

function draw() {
canvas.fillStyle = "#000"; // Set color to black
canvas.fillText("Sup Bro!", 50, 50);
}

注意:确认修改之后刷新一下,万一哪里不对,代码变的少还能看出哪里不对。

如果没错,那么显示的是静止的字母,虽然好看,但我们已经有了动画循环,所以我们应该很容易让他动起来。

var textX = 50;
var textY = 50; function update() {
textX += 1;
textY += 1;
} function draw() {
canvas.fillStyle = "#000";
canvas.fillText("Sup Bro!", textX, textY);
}

现在如果没出错,那么字母应该在移动,但是有残影出现。想想为什么会这样,因为我们没有清除之前的画面呢,so 我们加点清除画布的代码。

function draw() {
canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
canvas.fillStyle = "#000";
canvas.fillText("Sup Bro!", textX, textY);
}

现在可以看到字母在屏幕上移动了,恭喜你,你已经快入门了。让我们继续。

创建玩家

接下来创建一个物体用来给玩家控制,我们创建了一个简单的object:

var player = {
color: "#00A",
x: 220,
y: 270,
width: 32,
height: 32,
draw: function() {
canvas.fillStyle = this.color;
canvas.fillRect(this.x, this.y, this.width, this.height);
}
};

我们简单地着色了这个物体,当我们清除画布的时候,画上这个物体。

function draw() {
canvas.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
player.draw();
}

键盘控制

使用jQuery HotKeys

使用jQuery HotKeys,这个插件提供了简单的键盘输入检测
我们可以这么绑定事件

$(document).bind("keydown", "left", function() { ... });

不用想哪个按键是哪个号码真舒服,我们刚才实现了“当玩家按上的时候,做一些事情”,碉堡的插件!

玩家的移动

键盘输入检测已经完成了,但我们还要处理键盘输入之后要做什么。
你可能会想使用事件驱动的方式去处理键盘输入,但是这样做系统不一,按键效果不一样,而且脱离了动画循环呢,这样做就可以跨系统了,保证了一致性,也让游戏更平滑了。

有一个好消息,我们有一个key_status.js的文件,提供了类似keydown.left等等。去下载的文件里找

现在我们可以去查询是否有按键了,然后我们就这么写:

function update() {
if (keydown.left) {
player.x -= 2;
} if (keydown.right) {
player.x += 2;
}
}

这样玩家可以控制了。

你可能注意到玩家可以跑出屏幕,让我们限制一下玩家的位置,而且似乎控制速度有点慢,我们顺便加加速。

function update() {
if (keydown.left) {
player.x -= 5;
} if (keydown.right) {
player.x += 5;
} player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
}

clamp这个函数可以在下载的util.js里看到

然后我们加点炮弹进去。

function update() {
if (keydown.space) {
player.shoot();
} if (keydown.left) {
player.x -= 5;
} if (keydown.right) {
player.x += 5;
} player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
} player.shoot = function() {
console.log("Pew pew");
// :) Well at least adding the key binding was easy...
};

添加更多物体

子弹
我们需要一个数组放子弹

var playerBullets = [];

接下来我们创建一个子弹原型

function Bullet(I) {
I.active = true; I.xVelocity = 0;
I.yVelocity = -I.speed;
I.width = 3;
I.height = 3;
I.color = "#000"; I.inBounds = function() {
return I.x >= 0 && I.x <= CANVAS_WIDTH &&
I.y >= 0 && I.y <= CANVAS_HEIGHT;
}; I.draw = function() {
canvas.fillStyle = this.color;
canvas.fillRect(this.x, this.y, this.width, this.height);
}; I.update = function() {
I.x += I.xVelocity;
I.y += I.yVelocity; I.active = I.active && I.inBounds();
}; return I;
}

但玩家射击时,我们应该实例子弹,然后添加到子弹数组中.

player.shoot = function() {
var bulletPosition = this.midpoint(); playerBullets.push(Bullet({
speed: 5,
x: bulletPosition.x,
y: bulletPosition.y
}));
}; player.midpoint = function() {
return {
x: this.x + this.width/2,
y: this.y + this.height/2
};
};

我们需要把子弹的动画添加到没帧的动画里,为了能让子弹变成无限的效果,我们过滤了子弹数组,只保留了激活的子弹.同时删除了已经撞到敌人的子弹.

function update() {
...
playerBullets.forEach(function(bullet) {
bullet.update();
}); playerBullets = playerBullets.filter(function(bullet) {
return bullet.active;
});
}

最后一步就是画子弹了.

function draw() {
...
playerBullets.forEach(function(bullet) {
bullet.draw();
});
}

敌人
现在我们要像添加子弹一样添加敌人.

 enemies = [];

function Enemy(I) {
I = I || {}; I.active = true;
I.age = Math.floor(Math.random() * 128); I.color = "#A2B"; I.x = CANVAS_WIDTH / 4 + Math.random() * CANVAS_WIDTH / 2;
I.y = 0;
I.xVelocity = 0
I.yVelocity = 2; I.width = 32;
I.height = 32; I.inBounds = function() {
return I.x >= 0 && I.x <= CANVAS_WIDTH &&
I.y >= 0 && I.y <= CANVAS_HEIGHT;
}; I.draw = function() {
canvas.fillStyle = this.color;
canvas.fillRect(this.x, this.y, this.width, this.height);
}; I.update = function() {
I.x += I.xVelocity;
I.y += I.yVelocity; I.xVelocity = 3 * Math.sin(I.age * Math.PI / 64); I.age++; I.active = I.active && I.inBounds();
}; return I;
}; function update() {
... enemies.forEach(function(enemy) {
enemy.update();
}); enemies = enemies.filter(function(enemy) {
return enemy.active;
}); if(Math.random() < 0.1) {
enemies.push(Enemy());
}
}; function draw() {
... enemies.forEach(function(enemy) {
enemy.draw();
});
}

加载和添加图片

虽然目前这些方块飞来飞去看起来很酷,但有图片就更酷了。我们使用了一个叫sprite.js的文件,可以从下载的文件里看到。

player.sprite = Sprite("player");

player.draw = function() {
this.sprite.draw(canvas, this.x, this.y);
}; function Enemy(I) {
... I.sprite = Sprite("enemy"); I.draw = function() {
this.sprite.draw(canvas, this.x, this.y);
}; ...
}

碰撞检测

我们已经有了很多敌人飞来飞去了,但他们没有交互呢mb打不到他们,我们是时候加点碰撞检测了.
让我们使用一个简单的方法检测:

function collides(a, b) {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}

我们需要检测如下两种碰撞:

  1. 玩家子弹和敌方飞船
  2. 玩家和敌方飞船

让我们给update加入处理碰撞之后的处理

function handleCollisions() {
playerBullets.forEach(function(bullet) {
enemies.forEach(function(enemy) {
if (collides(bullet, enemy)) {
enemy.explode();
bullet.active = false;
}
});
}); enemies.forEach(function(enemy) {
if (collides(enemy, player)) {
enemy.explode();
player.explode();
}
});
} function update() {
...
handleCollisions();
}

现在我们需要给敌方飞船和玩家添加爆炸效果,爆炸的同时会移除

function Enemy(I) {
... I.explode = function() {
this.active = false;
// Extra Credit: Add an explosion graphic
}; return I;
}; player.explode = function() {
this.active = false;
// Extra Credit: Add an explosion graphic and then end the game
};

声音

为了可玩性,我们将要添加声音效果进去,我们用到sound.js这个文件,让事情变得非常简单。

player.shoot = function() {
Sound.play("shoot");
...
} function Enemy(I) {
... I.explode = function() {
Sound.play("explode");
...
}
}

使用这些API就能很快地完成一个简单的游戏.

告别

再说一下游戏地址,也可以下载

well,我希望你开始喜欢用js和html5写简单的游戏,随着学习的深入,将来会有更多地挑战呢.

参考文献

HTML5 Canvas Cheat Sheet
HTML5 Game Engines

【译】html5游戏入门的更多相关文章

  1. HTML5游戏开发引擎Pixi.js新手入门讲解

    在线演示 本地下载 ​这篇文章中,介绍HTML5游戏引擎pixi.js的基本使用. 相关代码如下: Javascript 导入类库:(使用极客的cdn服务:http://cdn.gbtags.com) ...

  2. HTML5游戏开发系列教程7(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-7/ 今天我们将完成我们第一个完整的游戏--打砖块.这次教程中,将 ...

  3. HTML5游戏开发系列教程6(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-6/ 这是我们最新一篇HTML5游戏开发系列文章.我们将继续使用c ...

  4. HTML5游戏开发系列教程5(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-5/ 最终我决定准备下一篇游戏开发系列的文章,我们将继续使用can ...

  5. HTML5游戏开发系列教程4(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-4/ 这篇文章是我们继续使用canvas来进行HTML5游戏开发系 ...

  6. HTML5游戏开发引擎Pixi.js完全入门手册(一)框架简介及框架结构分析,作者思路剖析

    前言: 最近无聊在淘宝弄了个小店,打算做一个兼职.遇到一个客户,要我帮忙拷贝一个html5游戏.. 我这人有一个习惯,拿到自己没见过的东西.都会去研究一番.去网上查了下发现,资料都是英文版.感觉极度不 ...

  7. HTML5游戏开发系列教程10(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-10/ 最后我们将继续使用canvas来进行HTML5游戏开发系列 ...

  8. HTML5游戏开发系列教程9(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-9/ 今天我们将继续使用canvas来进行HTML5游戏开发系列的 ...

  9. HTML5游戏开发系列教程8(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-8/ 这是我们最新一篇HTML5游戏开发系列文章.我们将继续使用c ...

随机推荐

  1. vc++深入跟踪MFC程序的执行流程

    在MFC程序设计的学习过程中最令人感到难受,甚至于有时会动摇学习者信心的就是一种对于程序的一切细节都没有控制权的感觉.这种感觉来源于学习者不知道一个MFC程序是如何运行起来的(即一个MFC程序的执行流 ...

  2. Struts2 使用通配符动态请求Action

    在以前的学习中,<action>元素的配置,都是用明确的配置,其name.class等属性都是一个明确的值.其实Struts2还支持class属性和method属性使用来自name属性的通 ...

  3. Backward Digit Sums(暴力)

    Backward Digit Sums Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5664   Accepted: 32 ...

  4. C# 中4个访问符和8个修饰符详解

    4个访问修饰符(是添加到类.结构或成员声明的关键字) Public:公有的,是类型和类型成员的访问修饰符.对其访问没有限制. Internal:内部的,是类型和类型成员的访问修饰符.同一个程序集中的所 ...

  5. javascript 全选与反选

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">    ...

  6. 蓝桥杯算法训练<一>

    一.图形显示 此题虽然简单,但是需啊哟注意的是,每个“*”后边有一个空格] 问题描述 编写一个程序,首先输入一个整数,例如5,然后在屏幕上显示如下的图形(5表示行数): * * * * * * * * ...

  7. 初识-Android之智能短信项目相关技术整理

    标签页切换采用传统的TabHost: 采用TabActivty实现TabHost. 效果图-后补: 相关技术详解推荐: http://blog.csdn.net/zhouli_05/article/d ...

  8. ResultSet与Result

    微软的.NET平台上面的数据访问有一个特点,就是数据查询的结果,可以放在内存中,以XML格式进行描述,不需要一直与数据库保持在线连接,用DataSet + Data Adapter来实现! 而在JDB ...

  9. 关于用 random 生成伪随机数的一个手笔

    我在想还要不要写什么文字.确实不需要太多的文字描述吧. 前奏插一个小话题,之前在网上看到这样的冷笑话(有图的),一个程序猿调试个程序,早上怀疑某某地方的错误,下午怀疑某某地方的错误,晚上怀疑某某地方可 ...

  10. Linux学习之域名解析命令

    (1) /etc/hosts :记录hostname对应的ip地址 /etc/resolv.conf :设置DNS服务器的ip地址 /etc/host.conf :指定域名解析的顺序(是从本地的hos ...