// Create the canvas
var canvas = document.createElement("canvas")
var ctx = canvas.getContext("2d")
canvas.width = 512
canvas.height = 480
document.body.appendChild(canvas)
首先我们需要创建一张画布作为游戏的舞台。这里通过JS代码而不是直接在HTML里写一个<canvas>元素目的是要说明代码创建也是很方便的。有了画布后就可以获得它的上下文来进行绘图了。然后我们还设置了画布大小,最后将其添加到页面上。
准备图片
// 背景图片
var bgReady = false
var bgImage = new Image()
bgImage.onload = function () {
bgReady = true
}
bgImage.src = "images/background.png"
游戏嘛少不了图片的,所以我们先加载一些图片先。简便起见,这里仅创建简单的图片对象,而不是专门写一个类或者Helper来做图片加载。bgReady这个变量用来标识图片是否已经加载完成从而可以放心地使用了,因为如果在图片加载未完成情况下进行绘制是会报错的。
整个游戏中需要用到的三张图片:背景,英雄及怪物我们都用上面的方法来处理。
游戏对象
// 游戏对象
var hero = {
speed: 256, // 每秒移动的像素
x: 0,
y: 0
}
var monster = {
x: 0,
y: 0
}
var monstersCaught = 0
现在定义一些对象将在后面用到。我们的英雄有一个speed属性用来控制他每秒移动多少像素。怪物游戏过程中不会移动,所以只有坐标属性就够了。monstersCaught则用来存储怪物被捉住的次数。
处理用户的输入
// 处理按键
var keysDown = {}
addEventListener("keydown", function (e) {
keysDown[e.keyCode] = true
}, false)
addEventListener("keyup", function (e) {
delete keysDown[e.keyCode]
}, false)
现在开始处理用户的输入(对初次接触游戏开发的前端同学来说,这部分开始可能就需要一些脑力了)。在前端开发中,一般是用户触发了点击事件然后才去执行动画或发起异步请求之类的,但这里我们希望游戏的逻辑能够更加紧凑同时又要及时响应输入。所以我们就把用户的输入先保存下来而不是立即响应。
为此,我们用keysDown这个对象来保存用户按下的键值(keyCode),如果按下的键值在这个对象里,那么我们就做相应处理。
开始一轮游戏
// 当用户抓住一只怪物后开始新一轮游戏
var reset = function () {
hero.x = canvas.width / 2
hero.y = canvas.height / 2
// 将新的怪物随机放置到界面上
monster.x = 32 + (Math.random() * (canvas.width - 64))
monster.y = 32 + (Math.random() * (canvas.height - 64))
}
reset方法用于开始新一轮和游戏,在这个方法里我们将英雄放回画布中心同时将怪物放到一个随机的地方。
更新对象
// 更新游戏对象的属性
var update = function (modifier) {
if (38 in keysDown) { // 用户按的是↑
hero.y -= hero.speed * modifier
}
if (40 in keysDown) { // 用户按的是↓
hero.y += hero.speed * modifier
}
if (37 in keysDown) { // 用户按的是←
hero.x -= hero.speed * modifier
}
if (39 in keysDown) { // 用户按的是→
hero.x += hero.speed * modifier
}
// 英雄与怪物碰到了么?
if (
hero.x <= (monster.x + 32)
&&monster.x <= (hero.x + 32)
&&hero.y <= (monster.y + 32)
&&monster.y <= (hero.y + 32)
) {
++monstersCaught
reset()
}
}
这就是游戏中用于更新画面的update函数,会被规律地重复调用。首先它负责检查用户当前按住的是中方向键,然后将英雄往相应方向移动。
有点费脑力的或许是这个传入的modifier 变量。你可以在main 方法里看到它的来源,但这里还是有必要详细解释一下。它是基于1开始且随时间变化的一个因子。例如1秒过去了,它的值就是1,英雄的速度将会乘以1,也就是每秒移动256像素;如果半秒钟则它的值为0.5,英雄的速度就乘以0.5也就是说这半秒内英雄以正常速度一半的速度移动。理论上说因为这个update 方法被调用的非常快且频繁,所以modifier的值会很小,但有了这一因子后,不管我们的代码跑得快慢,都能够保证英雄的移动速度是恒定的。
现在英雄的移动已经是基于用户的输入了,接下来该检查移动过程中所触发的事件了,也就是英雄与怪物相遇。这就是本游戏的胜利点,monstersCaught +1然后重新开始新一轮。
渲染物体
// 画出所有物体
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)
}
// 计分
ctx.fillStyle = "rgb(250, 250, 250)"
ctx.font = "24px Helvetica"
ctx.textAlign = "left"
ctx.textBaseline = "top"
ctx.fillText("Monsterrs caught: " + monstersCaught, 32, 32)
}
之前的工作都是枯燥的,直到你把所有东西画出来之后。首先当然是把背景图画出来。然后如法炮制将英雄和怪物也画出来。这个过程中的顺序是有讲究的,因为后画的物体会覆盖之前的物体。
这之后我们改变了一下Canvas的绘图上下文的样式并调用fillText来绘制文字,也就是记分板那一部分。本游戏没有其他复杂的动画效果和打斗场面,绘制部分大功告成!
主循环函数
// 游戏主函数
var main = function () {
var now = Date.now()
var delta = now - then
update(delta / 1000)
render()
then = now
// 立即调用主函数
requestAnimationFrame(main)
}
上面的主函数控制了整个游戏的流程。先是拿到当前的时间用来计算时间差(距离上次主函数被调用时过了多少毫秒)。得到modifier后除以1000(也就是1秒中的毫秒数)再传入update函数。最后调用render 函数并且将本次的时间保存下来。
关于游戏中循环更新画面的讨论可参见「Onslaught! Arena Case Study」。
关于循环的进一步解释
// requestAnimationFrame 的浏览器兼容性处理
var w = window
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame
如果你不是完全理解上面的代码也没关系,我只是觉得拿出来解释一下总是极好的
为了循环地调用main函数,本游戏之前用的是setInterval。但现今已经有了更好的方法那就是requestAnimationFrame。使用新方法就不得不考虑浏览器兼容性。上面的垫片就是出于这样的考虑,它是Paul Irish 博客原版的一个简化版本。
启动游戏!
// 少年,开始游戏吧!
var then = Date.now()
reset()
main()
总算完成了,这是本游戏最后一段代码了。先是设置一个初始的时间变量then用于首先运行main函数使用。然后调用 reset 函数来开始新一轮游戏(如果你还记得的话,这个函数的作用是将英雄放到画面中间同时将怪物放到随机的地方以方便英雄去捉它)。
到此,相信你已经掌握了开发一个简单H5小游戏需要的基本功了。玩玩这个游戏或者下载代码自己研究研究吧 :)
Feel free to repost but keep the link to this page please!
很好用啊。下面列举一下优点吧:第一大原因: 它是未来,开始用吧!
最大的原因今天你就开始使用HTML5是因为它是未来,不要掉队了!HTML5不会往每个方向发展,但是更多的元素已经被很多公司采用,并且开始着手开发。HTML5其实更像HTML,它不是一个新的技术需要你重新学习!如果你开发XHTML strict的话你现在就已经在开发HTML5了。为什么不更完整的享受HTML5的功能呢?
你实际上没有任何借口不接受HTML5。事实上我唯一一个原因使用HTML5是因为它书写代码简单清晰。其它的特性其实我也没有真正使用。你可以考虑现在开始使用HTML5书写代码,它能帮助你改变书写代码的方式及其设计方式。开始用HTML5代码编写web应用吧,说不定下一个移动应用或者游戏应用就是用HTML5开发的!
第二大原因: 移动,移动还是移动
你可以称之为“直觉”,但是我认为移动技术将会变得更加的流行。我知道,这里有些非常疯狂的猜测,有些可能你也想到了– Mobile是一个时尚!移动设备将占领世界。更多的接受移动设备将会增长的非常迅速。这意味着更多的用户会选择使用移动设备访问网站或者web应用。HTML5是最移动化的开发工具。随着Adobe宣布放弃移动flash开发,你将会考虑使用HTML5来开发webp应用。当手机浏览器完全支持HTML5那么开发移动项目将会和设计更小的触摸显示一样简单。这里有很多的meta标签允许你优化移动:viewport: 允许你定义viewport宽度和缩放设置;全屏浏览器: ISO指定的数值允许Apple设备全屏模式显示;Home screen icons: 就像桌面收藏,这些图标可以用来添加收藏到IOS和Android移动设备的首页。
第三大原因:遗留及其跨浏览器支持
你的现代流行浏览器都支持HTML5(Chrome,Firefox,Safari,IE9和Opera),并且创建了HTML5 doctype这样所有的浏览器,即使非常老非常令人厌恶浏览器像IE6都可以使用。但是因为老的浏览器能够识别doctype并不意味它可以处理HTML5标签和功能。幸运的是,HTML5已经使得开发更加简单了,更多支持更多浏览器,这样老的IE浏览器可以通过添加javascript代码来使用新的元素:
<!--[iflt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
第四大原因:游戏开发
没错, 你可以使用HTML5的<canvas>开发游戏。HTML5提供了一个非常伟大的,移动友好的方式去开发有趣互动的游戏。如果你开发Flash游戏,你就会喜欢上HTML5的游戏开发。
Script-tutorials目前提供了4个不部分的HTML5游戏开发教程,这里看看他们开发的有趣游戏:
HTML5 Gaming Development Lesson One
HTML5 Gaming Development Lesson Two
HTML5 Gaming Development Lesson Three
HTML5 Gaming Development Lesson Four
第五大原因:更好的互动
我们都喜欢更好的互动,我们都喜欢对于用户有反馈的动态网站,用户可以享受互动的过程。输入<canvas>,HTML5的画图标签允许你做更多的互动和动画,就像我们使用Flash达到的效果。
除了<canvas>,HTML5同样也拥有很多API允许你创建更加好的用户体验并且更加动态的web应用程序。 这里有一个列表:
Drag and Drop (DnD)
Offline storage database
Browser history management
document editing
Timed media playback
第六大原因:更聪明的存储
HTML5中最酷的特性就是本地存储。有一点像比较老的技术cookie和客户端数据库的融合。它比cooke更好用因为支持多个windows存储,它拥有更好的安全和性能,即使浏览器关闭后也可以保存。
因为它是个客户端的数据库,你不用担心用户删除任何cookie,并且所有主流浏览器都支持。
本地存储对于很多情况来说都不错,它是HTML5工具中一个不需要第三方插件实现的。能够保存数据到用户的浏览器中意味你可以简单的创建一些应用特性例如:保存用户信息,缓存数据,加载用户上一次的应用状态。
第七大原因:更清晰的代码
如果你对于简答,优雅,容易阅读的代码有所偏好的话,HTML5绝对是一个为你量身定做的东西。HTML5允许你写出简单清晰富于描述的代码。符合语义学的代码允许你分开样式和内容。看看这个典型的简单拥有导航的heaer代码:<div id="header"><h1>Header Text</h1><div id="nav"><ul> <li><ahref="#">Link</a></li> <li><ahref="#">Link</a></li> <li><ahref="#">Link</a></li> </ul></div></div>是不是很简单?但是使用HTML5后会使得代码更加简单并且富有含义:<header><h1>Header Text</h1><nav><ul> <li><ahref="#">Link</a></li> <li><ahref="#">Link</a></li> <li><ahref="#">Link</a></li> </ul></nav></header>
使用HTML5你可以通过使用语义学的HTML header标签描述内容来最后解决你的div及其class定义问题。 以前你需要大量的使用div来定义每一个页面内容区域,但是使用新的<section>,<article>,<header>,<footer>,<aside>和<nav>标签,需要你让你的代码更加清晰易于阅读。
第八大原因:Doctype
没错,就是doctype,没有更多内容了。是不是非常简答?不需要拷贝粘贴一堆无法理解的代码,也没有多余的head标签。最大的好消息在于,除了简单,它能在每一个浏览器中正常工作即使是名声狼藉的IE6。
第九大原因:视频和音频支持
忘了flash和其它第三方应用吧,让你的视频和音频通过HTML5标签<video>和<audio>来访问资源。正确播放媒体一直都是一个非常可怕的事情,你需要使用<embed>和<object>标签,并且为了它们能正确播放必须赋予一大堆的参数。你的媒体标签将会非常复杂,大堆得令人迷惑的代码。而且HTML5视频和音频标签基本将他们视为图片:<video src=”"/>。但是其它参数例如宽度和高度或者自动播放呢?不必担心,只需要像其它HTML标签一样定义:<video src=”url”width=”640px” height=”380px” autoplay/>。
实际上这个过程非常简单,然而我们的老浏览器可能并不喜欢我们的HTML5,你需要添加更多代码来让他们正确工作。但是这个代码还是比<embed>和<object>来的简单的多。
第十大原因:易用性
俩个原因使得使用HTML5创建网站更加简单:语义上及其ARIA。新的HTML标签像<header>, <footer>,<nav>,<section>, <aside>等等,使得阅读者更加容易去访问内容。在以前,即使你定义了class或者ID你的阅读者也没有办法去了解给出的一个div究竟是什么。使用新的语义学的定义标签,你可以更好的了解HTML文档,并且创建一个更好的使用体验。
ARIA是一个W3C的标准主要用来对HTML文章中的元素指定“角色“,通过角色属性来创建重要的页面地形例如,header,footer,navigation或者aritcle很有必要。这一点曾经被忽略掉了并且没有被广泛使用,因为事实上并不验证。然而,HTML5将会验证这样属性。同时,HTML5将会内建这些角色并且无法不覆盖。