【译】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. 图片文件,图片文件流和BASE64加密字符串之间的转换,以及图片的BASE64加密字符串再jsp上如何显示

    http://blog.csdn.net/sidongxue2/article/details/43036373

  2. java 多线程使用方法及Socket的使用

    public class newThread implements Runnable{ public void run(){ dosome(); } public void dosome(){ Sys ...

  3. poj1503---大数加法

    先讲一种错误的做法:WA了n次,大神一定帮我看一下//看到有说数组大小开到250,我改了之后还是不//思路是将arr这个数组的每一行附上输入的值,然后求每列所有数之和,当然进位 //maxlen记录这 ...

  4. C++ 之再继续

    1C++函数重载,内联函数(for程序性能优化),函数递归

  5. 【Apache ZooKeeper】为ZNode设置watcher

    众所周知,ZooKeeper中的ZNode是树形结构,现在我需要给/app1结点设置watcher,监听/app1下增减.删除和修改的结点,并将相应的事件使用log4j记录到日志文件中.ZNode的变 ...

  6. 在vs2010中编译log4cxx-0.10.0详细方法

    本文一共包含了17个步骤,按照下面的步骤就可以完成vs2010中编译log4cxx的工作了. 1. 下载 log4cxx 以及 apr 和 apr-util 源码: a) http://www.apa ...

  7. CSS技巧和犯错点总结

    4.14 CSS  background属性简写: background-position属性组合方式:[ left | center | right ] || [ top | bottom ] (组 ...

  8. c++中,size_typt, size_t, ptrdiff_t 简介

    size_type 类型 从逻辑上来讲,size() 成员函数似乎应该返回整形数值,或如 2.2 节“建议”中所述的无符号整数.但事实上,size 操作返回的是 string::size_type 类 ...

  9. 使用SQL脚本删除冗余的视图和表

    使用SQL脚本删除冗余的视图和表 SQL脚本删除视图信息 USE DatabaseGOIF OBJECT_ID('ViewName')IS NOT NULLBEGINDROP VIEW ViewNam ...

  10. 《转载》使用CSS3 Flexbox布局

    Flexbox(中文版本可以点击这里)的布局是一个用于页面布局的全新CSS3模块功能.它可以把列表放在同一个方向(从左到右或从上到下排列),并且让这些列表能延伸到占用可用的空间.较为复杂的布局可以通过 ...