原文地址:http://www.script-tutorials.com/html5-game-development-lesson-6/

这是我们最新一篇HTML5游戏开发系列文章。我们将继续使用canvas来进行HTML5游戏开发系列的文章。这次是个完整的游戏例子,再现一款经典的电脑游戏--坦克大战。我将教你们使用交替的数组地图(alternative array-maps),同时将说明如何检测活动对象(坦克)和周围环境之间的碰撞。

前一篇的的介绍在HTML5游戏开发系列教程5(译)。

第一步:HTML

index.html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HTML5 Game Development - Lesson 6 | Script Tutorials</title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<script src="js/jquery-2.0.0.min.js"></script>
<script src="js/script.js"></script>
</head>
<body>
<header>
<h2>HTML5 Game Development - Lesson 6</h2>
<a href="http://www.script-tutorials.com/html5-game-development-lesson-6/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div class="container">
<canvas id="scene" width="800" height="600"></canvas>
</div>
</body>
</html>

第二步:CSS

css/main.css

我将不会把css文件内容发布出来,css文件里面仅仅是一些页面的层叠样式,你可以在源代码包中找到该文件。

第三步:JS

js/jquery-2.0.0.min.js(原文是1.5.2版本)

我们的代码使用了JQuery。JQuery文件在源代码包中。下面的js文件是最重要的对于我们的游戏,因为它实现了我们游戏所有的逻辑。

js/script.js

 //内部变量
var canvas, context; //画布和其上下文对象
var imgBrick, imgSteel, imgWater, imgForest, imgTank; //各种实体的图片
var aMap; //地图数组
var oTank; //坦克对象 var iCellSize = 24; //地图单元格的大小
var iXCnt = 26;
var iYCnt = 26; /**
* x: 坦克左上角x轴坐标
* y: 坦克左上角y轴坐标
* w: 坦克宽度
* h: 坦克高度
* image: 坦克图片
*/
function Tank(x, y, w, h, image) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.i = 0;
this.image = image;
} // 清除画布
function clear() {
context.clearRect(0, 0, canvas.width, canvas.height)
} //重绘画布
function drawScene() {
clear(); //填充背景
context.fillStyle = '#111';
context.fillRect(0, 0, canvas.width, canvas.height); context.save(); //画障碍物
for (var y = 0; y < iYCnt; y++) {
for (var x = 0; x < iXCnt; x++) {
switch (aMap[y][x]) {
case 0:
break;
case 1:
context.drawImage(imgBrick, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
break;
case 2:
context.drawImage(imgSteel, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
break;
case 3:
context.drawImage(imgForest, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
break;
case 4:
context.drawImage(imgWater, 0, 0, iCellSize, iCellSize, x * iCellSize, y * iCellSize, iCellSize, iCellSize);
break;
}
}
} context.restore(); //画坦克 这里可以看出坦克占4个单元格
context.drawImage(oTank.image, oTank.i * oTank.w, 0, oTank.w, oTank.h, oTank.x, oTank.y, oTank.w, oTank.h);
} $(function() {
canvas = document.getElementById('scene');
canvas.width = iXCnt * iCellSize;
canvas.height = iYCnt * iCellSize;
context = canvas.getContext('2d'); aMap = ([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0],
[0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 1, 1, 0, 0, 0, 0],
[0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
[3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
[3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2],
[3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2],
[0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 4, 4, 4, 4, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0],
[2, 2, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 4, 4, 4, 4, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 0]
]); //加载各个障碍物图片
imgBrick = new Image();
imgBrick.src = 'images/brick.png';
imgSteel = new Image();
imgSteel.src = 'images/steel.png';
imgWater = new Image();
imgWater.src = 'images/water.png';
imgForest = new Image();
imgForest.src = 'images/forest.png'; //初始化坦克
imgTank = new Image();
imgTank.src = 'images/tank.png';
oTank = new Tank(iCellSize * 9, iCellSize * 24, 48, 48, imgTank); $(window).keydown(function(event) {
switch (event.keyCode) {
case 38: // up key
oTank.i = 2; //碰撞检测
var iCurCelX = (2 * oTank.x) / 48; //得出目前坦克左上角所在的单元格
var iCurCelY = (2 * oTank.y) / 48;
if (iCurCelY) {
var iTest1 = aMap[iCurCelY - 1][iCurCelX];
var iTest2 = aMap[iCurCelY - 1][iCurCelX + 1]; if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
oTank.y -= 24;
if (oTank.y < 0) {
oTank.y = 0;
}
}
}
break;
case 40: //Down key
oTank.i = 3; var iCurCelX = (2 * oTank.x) / 48;
var iCurCelY = (2 * oTank.y) / 48;
if (iCurCelY + 2 < iYCnt) {
var iTest1 = aMap[iCurCelY + 2][iCurCelX];
var iTest2 = aMap[iCurCelY + 2][iCurCelX + 1]; if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
oTank.y += 24;
if (oTank.y > 576) { //576 = iCellSize * (iYCnt - 2)
oTank.y = 576;
}
}
}
break;
case 37: // Left key
oTank.i = 1; var iCurCelX = (2 * oTank.x) / 48;
var iCurCelY = (2 * oTank.y) / 48;
var iTest1 = aMap[iCurCelY][iCurCelX - 1];
var iTest2 = aMap[iCurCelY + 1][iCurCelX - 1]; if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
oTank.x -= 24;
if (oTank.x < 0) {
oTank.x = 0;
}
}
break;
case 39: //Right key
oTank.i = 0; var iCurCelX = (2 * oTank.x) / 48;
var iCurCelY = (2 * oTank.y) / 48;
var iTest1 = aMap[iCurCelY][iCurCelX + 2];
var iTest2 = aMap[iCurCelY + 1][iCurCelX + 2]; if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
oTank.x += 24;
if (oTank.x > 576) {
oTank.x = 576;
}
}
break;
}
});
setInterval(drawScene, 40);
});

我在很多地方加上了注释,依此希望这代码是容易理解的。

结论:

这次我们开发了一个完整的HTML5的游戏--坦克大战。我非常乐意看见你的谢意和评论。好运!

HTML5游戏开发系列教程6(译)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. cocos2d-x游戏开发系列教程-前言

    cocos2d-x游戏开发前景: 最近企业对于Cocos2D-X开发人才的用人需求很大,而且所提供的薪资相当可观. 为满足广大向往游戏开发行业同学的需求,特推出适合新手的Cocos2D-X手游开发教程 ...

  8. cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap

    背景 在上一篇博客中,我们提到CMGameScene,但是CMGameScene只是个框架,实际担任游戏逻辑的是CMGameMap类,这个博文就来了解下CMGameMap 头文件 class CMGa ...

  9. cocos2d-x游戏开发系列教程-超级玛丽06-CMGameScene

    背景 在CMMenuScene中,当用户点击开始游戏时,导演让场景进入到CMGameScene 头文件 class CMGameScene : public cocos2d::CCLayer,publ ...

随机推荐

  1. 学习:erlang用链表实现大容量的List或者数组。

    链表的内在实质. 效率未知,待测.

  2. mac zsh选择到行首的快捷键

    Mac OS X 下zsh切换窗口的快捷键:Shift-Command-←. 移动到当前命令行的行首,使用快捷键[Ctrl][A].移动到当前命令行的行尾,使用快捷键[Ctrl[E].

  3. myeclipse10中对象无法点出下面的方法和属性

    刚安装完最新的myeclipse4spring-10.6,发现通过对象无法点出下面的方法和属性,没有自动联想或自动补全,使用“Alt + /”也没得效果,解决方法如下: Window -> Pr ...

  4. MathType模板不见了如何处理

    MathType是一款在编辑公式方面非常好用的软件!并广泛应用在文档编辑与期刊排版中.但是新手用户在使用MathType编辑公式时会遇到一些处理不了的状况,这个时候就需要去找一些相关的教程来解决问题. ...

  5. Sokect异步连接发送

    客户端 static void Main(string[] args) { Console.WriteLine("this is a Client!"); Socket clien ...

  6. iOS 开发之 -- UDID和UUID的详解

    老实说,搞了几年的ios开发了,对基础的概念,还是不牢固,整天都是为了赶进度而码代码,这里记录一下这两者的区别: UDID的全名为 Unique Device Identifier :设备唯一标识符. ...

  7. Group By和Order By的总结

    1.Group By 语句中:select指定的字段必须是“分组依据字段”,其他字段若想出现在select中则必须包含在聚合函数中. 例如: select [col1], avg([col2])    ...

  8. Android下在onCreate中获取控件的宽度和高度(通过回调)

    有时候需要在onCreate方法中知道某个View组件的宽度和高度等信息, 而直接调用View组件的getWidth().getHeight().getMeasuredWidth().getMeasu ...

  9. PHP HTTP协议:防盗链

    test.html:主界面 <html> <head> <meta http-equiv="content-type" content="t ...

  10. 160419、CSS3实现32种基本图形

    CSS3可以实现很多漂亮的图形,我收集了32种图形,在下面列出.直接用CSS3画出这些图形,要比贴图性能更好,体验更加,是一种非常好的网页美观方式. 这32种图形分别为圆形,椭圆形,三角形,倒三角形, ...