这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game。

下面是正文:

自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML5 Canvas制作游戏的入门教程。花了一点时间考虑怎么着手写这篇文章后,我决定先实现一个我觉得最最简单的游戏,然后一行代码一行代码地进行讲解。

让我们开始吧,首先看看game.js,当然你也可以先玩玩这个游戏(译注:附件是游戏源码,用浏览器打开其中的index.html就可以玩了,或者也可以到lostdecadegames官网上去玩)。

附件下载地址:simple_canvas_game

1. 创建一个Canvas对象

    // Create the canvasvar canvas = document.createElement("canvas");var ctx = canvas.getContext("2d");canvas.width = 512;canvas.height = 480;document.body.appendChild(canvas);

我们首先要做的是创建一个canvas对象。可以用JavaScript或HTML来做,都非常简单。此处我用的是JS。当创建了canvas之后,我们就可以获取它的上下文对象(context)、设置尺寸,并且把它加到当前文档中。

2. 载入图片

    // Background imagevar bgReady = false;var bgImage = new Image();bgImage.onload = function () {bgReady = true;};bgImage.src = "images/background.png";

游戏需要图像,所以让我们载入一些图片吧。我想尽量简单化,所以只用了Image对象来做,当然,还可以将载入图像的功能封装成一个类或别的任何形式。代 码中的bgReady用来标识图片是否已完全载入,只有当图片载入完成后,我们才能使用它,如果在载入完成前就对其进行绘制或渲染,JS将会报一个DOM error的错误。

我们会用到三张图片(背景、英雄、怪物),每张图片都需要这样处理。

3. 定义游戏要使用的对象

    // Game objectsvar hero = {speed: 256, // movement in pixels per secondx: 0,y: 0};var monster = {x: 0,y: 0};var monstersCaught = 0;

定义一些变量,稍后会用到。hero对象的speed属性表示英雄的移动速度(像素/秒);monster对象不会移动,所以仅仅具有一对坐标;monstersCaught表示玩家抓住的怪物数量。

4. 处理玩家输入

// Handle keyboard controls
var keysDown = {};
addEventListener("keydown", function (e) {keysDown[e.keyCode] = true;
}, false);
addEventListener("keyup", function (e) {delete keysDown[e.keyCode];
}, false);

现在进行输入的处理。(对具有web开发背景的人来说,这是目前为止第一个具有挑战性的部分)对一般的网页来说,当用户开始输入时,可能需要马上开始播放 动画或请求数据。但在这里,我们想让游戏逻辑在一个单独的地方对游戏中发生的事情进行处理。为此我们需要将用户输入保存下来以备稍后处理,而不是立即处 理。
我们通过简单地将事件对应的键编码(keyCode)保存在keysDown变量中来实现。如果该变量中具有某个键编码,就表示用户目前正按下这个键。简单吧!

5. 新游戏

    // Reset the game when the player catches a monstervar reset = function () {hero.x = canvas.width / 2;hero.y = canvas.height / 2;// Throw the monster somewhere on the screen randomlymonster.x = 32 + (Math.random() * (canvas.width - 64));monster.y = 32 + (Math.random() * (canvas.height - 64));};

通过调用reset函数来开始新游戏。该函数将英雄(即玩家角色)放到屏幕中间,然后随机选择一个位置来安置怪物。

6. 更新对象

    // Update game objectsvar update = function (modifier) {if (38 in keysDown) { // Player holding uphero.y -= hero.speed * modifier;}if (40 in keysDown) { // Player holding downhero.y += hero.speed * modifier;}if (37 in keysDown) { // Player holding lefthero.x -= hero.speed * modifier;}if (39 in keysDown) { // Player holding righthero.x += hero.speed * modifier;}// Are they touching?if (hero.x <= (monster.x + 32)&& monster.x <= (hero.x + 32)&& hero.y <= (monster.y + 32)&& monster.y <= (hero.y + 32)) {++monstersCaught;reset();}};

这是update函数,游戏每隔一定时间会调用它一次。它所做的第一件事情是检查用户是否按下了上下左右四个箭头键。如果是,就将我们的英雄向相应的方向移动。

update有一个modifier参数,这看起来好像有点奇怪。你会在游戏的主函数即main函数中看到它,不过我在这 儿先解释一下。modifier参数是一个从1开始的与时间相关的数。如果间隔刚好为1秒时,它的值就会为1,英雄移动的距离即为256像素(英雄的速度 为256像素/秒);而如果间隔是0.5秒,它的值就为0.5,即英雄移动的距离为其速度的一半,以此类推。通常update函数调用的间隔很短,所以 modifier的值很小,但用这种方式能够确保不管代码执行的速度怎么样,英雄的移动速度都是相同的。

我们已经实现了根据用户的输入来移动英雄,但我们还可以在移动英雄时对其进行检查,以确定是否有其他事件发生。例如:英雄是否与怪物发生了碰撞——当英雄与怪物发生碰撞时,我们为玩家进行计分(monstersCaught加1)并重置游戏(调用reset函数)。

7. 渲染对象

    // Draw everythingvar render = function () {if (bgReady) {ctx.drawImage(bgImage, 0, 0);}if (heroReady) {ctx.drawImage(heroImage, hero.x, hero.y);}if (monsterReady) {ctx.drawImage(monsterImage, monster.x, monster.y);}// Scorectx.fillStyle = "rgb(250, 250, 250)";ctx.font = "24px Helvetica";ctx.textAlign = "left";ctx.textBaseline = "top";ctx.fillText("Goblins caught: " + monstersCaught, 32, 32);};

当你能够看到你的行动时游戏才会变得更有趣,所以让我们在屏幕上绘制吧。首先我们将背景图片绘制到canvas,然后是英雄和怪物。注意顺序很重要,因为任何位于表层的图片都会将其下面的像素覆盖掉。

接下来是文字,这有些不同,我们调用fillText函数显示玩家的分数。因为不需要复杂的动画或者对文字进行移动,所以只是绘制一下就ok了。

8. 游戏主循环

   // The main game loopvar main = function () {var now = Date.now();var delta = now - then;update(delta / 1000);render();then = now;};

游戏的主循环用来控制游戏流程。首先我们要获得当前的时间,这样我们才能计算时间差(自上次循环以来经过的时间)。然后计算modifier的值并交给update(需要将delta除以1000以将其转换为毫秒)。最后调用render并更新记录的时间。

更多关于游戏循环的内容见“Onslaught! Arena Case Study”。

9. 开始游戏吧

// Let's play this game!
reset();
var then = Date.now();
setInterval(main, 1); // Execute as fast as possible

快完成了,这是最后一段代码。首先调用reset来开始新游戏。(还记得吗,这会将英雄置中并随机安放怪物)。然后将起始时间保存到变量then中并启动游戏的主循环。

OK!(但愿)你现在已经理解了在HTML5 Canvas中用JS来开发游戏的基础知识了。建议最好是能够自己亲自试一把!

转载于:https://www.cnblogs.com/antineutrino/p/3301880.html

[译]怎样用HTML5 Canvas制作一个简单的游戏相关推荐

  1. html5上色游戏制作,怎样用HTML5 Canvas制作一个简单的游戏

    原文连接: How To Make A Simple HTML5 Canvas Game 自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML ...

  2. 怎样用HTML5 Canvas制作一个简单的游戏

    为了让大家清楚HTML5制作游戏的简单流程,所以先了制作一个非常简单的游戏,来看一看这个过程.   游戏非常简单,无非就是英雄抓住怪物就得分,然后游戏重新开始,怪物出现在地图的随机位置,英雄初始化在地 ...

  3. 用html5 Canvas制作一个简单的游戏 英雄抓小怪物(上)

    1.创建一个Canvas对象 先在HTML页面上创建画布,然后再通过document.getElementById()来获取. //创建画布canvas,并获取画布上下文环境 var  canvas ...

  4. html5 游戏制作教程,利用HTML5 Canvas制作一个简单的打飞机游戏

    之前在当耐特的DEMO里看到个打飞机的游戏,然后就把他的图片和音频扒了了下来....自己凭着玩的心情重新写了一个.仅供娱乐哈......我没有用框架,所有js都是自己写的......所以就可以来当个简 ...

  5. 网页游戏制作html5,利用HTML5 Canvas制作一个简单的打飞机游戏

    之前在当耐特的DEMO里看到个打飞机的游戏,然后就把他的图片和音频扒了了下来....自己凭着玩的心情重新写了一个.仅供娱乐哈......我没有用框架,所有js都是自己写的......所以就可以来当个简 ...

  6. html5 canvas 实现一个简单的叮当猫头部

    html5 canvas 实现一个简单的叮当猫头部 原文:html5 canvas 实现一个简单的叮当猫头部 html5的canvas是很强大的,今天也是温习了一下之前的基础知识,然后学着做了一个简单 ...

  7. 使用Dreamweaver/利用HTML5/CSS/制作一个简单的文字logo

    一.制作一个简单的logo 1. 结构与样式分析 首先我们根据logo的图片分析logo的效果,该logo由6个字母组成.在使用"数码测色计"测出logo的颜色,这里我们测出log ...

  8. (译)如何使用GameCenter制作一个简单的多人游戏教程:第一部分

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  9. (译)如何使用cocos2d制作一个塔防游戏:引子

    原文链接地址:http://www.iphonegametutorials.com/2011/04/11/cocos2d-game-tutorial-how-to-build-a-tower-defe ...

最新文章

  1. maven(一 基本操作 命令 标签)
  2. 华为路由器的常用命令
  3. Hbuilder MUI里面使用java.net.URL发送网络请求,操作cookie
  4. Ubuntu18.04安装rabbitmq
  5. 1.15 Python基础知识 - 函数
  6. 高斯滤镜模糊CSS3
  7. centos7 安装mysql_Centos7安装最新版本的MySQL
  8. 有关编译嵌入式android的swap空间不够导致的编译错误和解决办法
  9. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
  10. vb 关于commondialog的多选
  11. UE4 C++头文件
  12. QQ概念版酿杯具,头条下载竟是病毒
  13. Excel画饼图(立体的哦)
  14. 彻底阻止、禁用google chrome浏览器自动更新、升级
  15. UT000010: Session is invalid
  16. 目标检测一阶段和二阶段对比图
  17. 基于tensorflow和卷积神经网络的电影推荐系统的实现
  18. 华硕主板反复进入BIOS以及无法识别固态硬盘?
  19. 全卷积网络FCN与卷积神经网络CNN的区别
  20. 51单片机15单片机 温度传感器DS18B20

热门文章

  1. Servlet应用之细节
  2. CentOS下安装semanage
  3. PhD representive Punting and Dinner Plan
  4. brain teasers
  5. logistics and sigmoid
  6. 东方和西方的两个视角的摘抄
  7. 亲测有用的音乐推荐网站
  8. 图书馆预约在线课程方法
  9. 我希望的未来职业发展!!!!!!!!!!想了半年的最终的结果~好像又没有变化哈哈哈哈
  10. U3D 编辑器中sceneview下相机操作相关