原文连接:

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 canvas

var 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 image

var bgReady = false;

var bgImage = new Image();

bgImage.onload = function () {

bgReady = true;

};

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

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

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

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

// Game objects

var hero = {

speed: 256, // movement in pixels per second

x: 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 monster

var reset = function () {

hero.x = canvas.width / 2;

hero.y = canvas.height / 2;

// Throw the monster somewhere on the screen randomly

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

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

};

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

6. 更新对象

// Update game objects

var update = function (modifier) {

if (38 in keysDown) { // Player holding up

hero.y -= hero.speed * modifier;

}

if (40 in keysDown) { // Player holding down

hero.y += hero.speed * modifier;

}

if (37 in keysDown) { // Player holding left

hero.x -= hero.speed * modifier;

}

if (39 in keysDown) { // Player holding right

hero.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 everything

var 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);

}

// Score

ctx.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 loop

var main = function () {

var now = Date.now();

var delta = now - then;

update(delta / 1000);

render();

then = now;

};

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

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来开发游戏的基础知识了。建议最好是能够自己亲自试一把!

html5上色游戏制作,怎样用HTML5 Canvas制作一个简单的游戏相关推荐

  1. 游戏编程笔记-起步(一)一个简单的游戏-贪吃蛇

    二 游戏编程起步 1.一个简单的游戏-贪吃蛇 1.贪吃蛇游戏剖析 1)游戏的目标.在不被撞死的前提下,吃掉奖子增加自己的长度,来完成升级. 2)游戏中的物体.蛇,墙壁,奖子. 3)动作.蛇移动,蛇吃奖 ...

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

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

  3. python编程制作接金币游戏_pygame学习笔记(6):完成一个简单的游戏

    学了这么长时间的Pygame,一直想写个游戏实战一下.看起来很简单的游戏,写其来怎么这么难.最初想写个俄罗斯方块,想了很长时间如何实现,想来想去,也没写出来,于是干脆下载别人的代码来读.后来,要想写一 ...

  4. 如何制作一个简单的游戏 Cocos2d x 2 0 4

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本文实践 ...

  5. 如何制作一个简单的游戏 Cocos2d-x 2.0.4

    本文实践自 Ray Wenderlich 的文章< How To Make A Simple iPhone Game with Cocos2D 2.X Tutorial>,文中使用Coco ...

  6. 本文将引导你使用XNA Game Studio Express一步一步地创建一个简单的游戏

    本文将引导你使用XNA Game Studio Express一步一步地创建一个简单的游戏 第1步: 安装软件 第2步: 创建新项目 第3步: 查看代码 第4步: 加入一个精灵 第5步: 使精灵可以移 ...

  7. 一个简单的游戏源代码

    一个简单的游戏源代码 作者:陈跃峰 出自: http://blog.csdn.net/mailbomb 实现一个简单的翻牌游戏,每次最多翻开两个数字,如果数字相同则消失,否则两个数字不显示,可以继续游 ...

  8. rust如何在木板上上传图片_通过编写一个简单的游戏来学习 Rust | Linux 中国

    导读:你可以尝试以多种语言编程一个简单的游戏来开始编程之路. 本文字数:4068,阅读时长大约: 5分钟 https://linux.cn/article-12979-1.html 作者:Moshe ...

  9. 用python 编写一个简单的游戏

    This blog will memory my work and process with the interesting skill. 用python 编写一个简单的游戏 这是一个非常简单的游戏, ...

  10. 用python做一个简单的游戏,用python写一个小游戏

    大家好,本文将围绕如何用python做一个简单的小游戏展开说明,python编写的入门简单小游戏是一个很多人都想弄明白的事情,想搞清楚用python做一个简单的游戏需要先了解以下几个事情. 1.Pyt ...

最新文章

  1. icop java,java基于spring注解AOP的异常处理的方法
  2. python去除英文字符中的数字和标点符号
  3. java 枚举 循环_java – 在枚举中实现内部接口时的循环继承
  4. 【机器学习算法专题(蓄力计划)】七、机器学习中数据的相关分析
  5. CSS让文字在元素内绝对居中!!!【ie和谷歌】
  6. 每输入四个字符添加一个中划线
  7. Microsoft Teams的Outgoing Webhook开发入门
  8. CentOS7的yum安装mysql
  9. 安全技术可以采用计算机安全,2017年计算机三级《信息安全技术》习题
  10. 基于阿里云服务器使用宝塔面板搭建 Typecho 博客
  11. C++ string类相关函数
  12. Paper Read: Robust Deep Multi-modal Learning Based on Gated Information Fusion Network
  13. android 开源 音乐播放器,Android 开源在线音乐播放器
  14. 只查看ett.txt文件(100行)内第20行到30行的内容
  15. ANSVC无功补偿装置在南京某高等院校中的应用-安科瑞华楠
  16. Python常见问题解决办法汇总
  17. 软件工程心得之——产品经理与项目经理的区别
  18. Java-JDK下载过慢的问题解决方案
  19. 二进制、八进制、十进制、十六进制之间的互相转化
  20. 自定义控件 自定义属性_自定义您的外壳

热门文章

  1. 投资理财-要有家国情怀
  2. 代理模式——Proxy
  3. OBS Studio显示器捕捉黑屏解决方法亲测有效
  4. 梦魂萦绕,依然是故乡
  5. 路由器无线网速正常,有线网速慢的解决办法
  6. java文本框输出_java实现文本框和文本区的输入输出
  7. BootstrapValidator delay属性无效不管用
  8. [机缘参悟-10]:儒家的主要思想与分层架构
  9. out.println()方法与%表达式
  10. mt5 mysql数据库_MySQL数据库配置主从复制