html游戏怎么做,HTML5 制做“游戏”的一个基本流程

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

为了让大家清楚HTML5制作游戏的简单流程,所以先了制作一个非常简单的游戏,来看一看这个过程。

游戏非常简单,无非就是英雄抓住怪物就得分,然后游戏重新开始,怪物出现在地图的随机位置,英雄初始化在地图的中间。点击这里,我们可以直接先玩玩这个游戏

20181011042712420982.png

1. 创建一个Canvas对象

这里相信大家都知道,当然代码里面是通过JS动态创建的画布,大家也可以直接在HTML页面上先创建画布,然后再通过document.getELementById()来获取,这两种方法没有什么区别,只是看你更习惯哪一种。

// 创建画布canvas,并获取画布上下文环境

var canvas = document.createElement("canvas");

var ctx = canvas.getContext("2d");

canvas.width = 512;

canvas.height = 480;

document.body.appendChild(canvas);

2. 载入图片

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

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

// 背景图片 bgImage

var bgReady = false;

var bgImage = new Image();

bgImage.onload = function () {

bgReady = true;

};

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

这里需要注意的一点,把bgImage.src写在bgImage.onload之后是为了解决IE显示的bug,所以建议大家都这么么写。

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

// 游戏对象

var hero = {

speed: 256, // 英雄每秒移动的速度,即256px/s

x: 0,

y: 0

};

var monster = {

x: 0,

y: 0

};

var monstersCaught = 0;

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

4. 处理玩家输入

// 键盘 输入处理

var keysDown = {};

addEventListener("keydown", function (e) {

keysDown[e.keyCode] = true;

}, false);

addEventListener("keyup", function (e) {

delete keysDown[e.keyCode];

}, false);

用户到底按下了哪个键,通过键盘事件来处理,将按下的键的keyCode保存在空对象KeysDown中。如果该变量中具有某个键编码,就表示用户目前正按下这个键。

5. 新游戏

// 当英雄捉住怪物之后重新开始游戏,英雄的位置在画布中间,怪物位置随机

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函数来开始新游戏。该函数将英雄(即玩家角色)放到屏幕中间,然后随机选择一个位置来安置怪物。

6. 更新对象

// 更新游戏对象

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

这和我们之前的做法是不一样的,我们之前的做法经常是向右移动 x += spped,向左移动 x -= speed,之前的这种做法,相当于已经给定了物体移动的速度,无论是什么机器,都必须保证,每次移动的距离是speed的长度。

我们已经实现了根据用户的输入来移动英雄,但我们还可以在移动英雄时对其进行检查,以确定是否有其他事件发生。例如:英雄是否与怪物发生了碰撞——当英雄与怪物发生碰撞时,我们为玩家进行计分(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);

};

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

想一想,每次如果英雄的位置改变,那么我们会把所有的场景包括背景都重新绘制一次,那么你在界面上看到的就好像是英雄走了一步

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

8. 游戏主循环

// 游戏主循环

var main = function () {

var now = Date.now();

var delta = now - then;

update(delta / 1000);

render();

then = now;

requestAnimationFrame(main);

};

var w = window;

requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;

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

游戏主循环是游戏中最重要的概念,无论游戏怎么变化,无非就是移动,消失。而移动消失,无非又是画布的重画,所以把移动或者消失的位置放在update函数里面,把画布重画放在render函数里面。而随着时间的变化,无非就是这两个函数函数一直在执行而已。

9. 开始游戏

var then = Date.now();

reset();

main();

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

原文:http://www.cnblogs.com/18200345061-hjl/p/4120719.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET 6 的 docker 镜像可以有多小

.NET 6 的 docker 镜像可以有多小?Intro最近写了一个小玩具&#xff0c;一个命令行调用 HTTP API 的工具&#xff0c;介绍可以参考&#xff1a;动手造轮子 —— dotnet-HTTPie&#xff0c;最近在使用 System.CommandLine 重构的同时&#xff0c;也在尝试减少 docker 镜像的大小…

开源播放器 Banshee 发布 1.0 beta 2

Banshee也是个很是不错的开源播放器,同时也是SuSE的内置播放器,默许支持靠山播放,消息区域告诉,可以快速跳过以后曲目,评分等等,也支持全局热键,媒体库支持音频和视频.新版本提供了对网络视频和PodCast的优秀支持.SuSE/Ubuntu/Fedora Linux用户可以从源中直接安置,也可以下载安…

仓库每天的账怎样做_新年第一站,济南:仓储匠人仓库问题解决与实战力培训...

【时间地点】1月15-16日&#xff0c;济南站济南市天桥区无影山北路88号祥云酒店5楼(师范路西口)【报名方式】直接加微信号“taishan33976”&#xff0c;注明姓名公司名仓储匠人。如果您认识小编的任意一位同事&#xff0c;欢迎直接找他们报名。【培训价格】1960元/人&#xff0…

一对一指导怎么追喜欢的男生

1 它们是怎样达成平衡的2 OK. 对不起打扰了3 今天也要加油鸭&#xff01;4 以色列一个父亲&#xff0c;为她“坐没坐相”的女儿打造的椅子。5 这个床我爱了6 静冈花火大会上摄影师发现了一个有趣的角度7 怎么样学会了吗内容自奔现翻车现场你点的每个赞&#xff0c;我都认真当成…

android canvas_Android 如何实现气泡选择动画

作者&#xff1a;Irina Galata Android 开发者: Yulia Serbenenko UI/UX 设计师 译者&#xff1a;skyar2009链接&#xff1a;https://juejin.im/post/58e5ec838d6d8100616d82e2/跨平台用户体验统一正处于增长趋势&#xff1a;早些时候 iOS 和安卓有着不同的体验&#xff0c;但是…

MVC中的验证规则

前面的博客中曾经提到过ModelBing机制&#xff0c;也在Demo中体现过&#xff0c;在MVC中更吊的是封装了自定义的验证规则。下面来一个Demo来展现一下&#xff0c;看了后&#xff0c;你一定会爱上它的&#xff0c;能让你少写很多JS语句。 1.View层 [html] view plaincopyprint…

网络——在网络上发送,接收数据

问题 创建并加入一个网络会话是一回事&#xff0c;但如果不能发送或接收任何数据那么网络会话有什么用呢&#xff1f; 解决方案 当玩家连接到会话时&#xff0c;你可以在一个PacketWriter流中存储所有想要发送的数据。完成这个操作后&#xff0c;你可以使用LocalNetworkPlayer.…

微服务之 EShop on dapr概览

????欢迎点赞 &#xff1a;???? 收藏 ⭐留言 ???? 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;????本文作者&#xff1a;由webmote 原创&#xff0c;首发于 【掘金】????作者格言&#xff1a;生活在于折腾&#xff0c;当你不折…

苹果android 对比,苹果安卓旗舰差距有多少?看了这份对比,果粉傻眼了

最近&#xff0c;身边不少小伙伴都在换机&#xff0c;有的换了最新的 iPhone 12 系列&#xff0c;有的则是换成安卓旗舰&#xff0c;毕竟现在的安卓旗舰与 iPhone 之间的体验已经十分接近&#xff0c;甚至在一些方面安卓旗舰还有着不小的优势。下面&#xff0c;我们以最新的 iP…

python画画用哪库好_Python我要学画画-turtle库

上帝说&#xff1a;“要有光&#xff01;” 于是&#xff0c;就有了光。 ---《圣经》旧约创世纪篇 我要学画画&#xff0c;Python便有了turtle库。 turtle库是一个点线面的简单图像库。画布中心为坐标系原点&#xff0c;小海龟起始位置就在原点方向向右。turtle界面 Python与库…

看完这15张动图,秒懂万有引力与航天难点!

全世界只有3.14 % 的人关注了爆炸吧知识椭圆的画法大质量天体使周围天体绕其运转模拟太阳系星球轨迹非常接近圆火箭运载卫星升空卫星飞行过程中可以点火调整姿态同步卫星必须在赤道上空北斗全球卫星导航轨道半径越大&#xff0c;卫星越慢人类发射的卫星越来越多嫦娥沿椭圆轨道奔…

物联网工程专业的迷茫与抉择

大家好&#xff0c;我是阿辉&#xff0c;很高兴在这里和你讲述所思所想。周末了&#xff0c;就聊点比较轻松的话题。正文共1633字&#xff0c;预计阅读时间5分钟。想必很多朋友是通过#毕业四年&#xff0c;我当初是如何走上编程这条路的&#xff01;#这篇文章才熟知我的吧&…

html二级页面内容滑动,jQuery+CSS实现的网页二级下滑菜单效果

本文实例讲述了jQueryCSS实现的网页二级下滑菜单效果。分享给大家供大家参考。具体如下&#xff1a;这是一款简洁型的 jQueryCSS网页二级下滑菜单&#xff0c;练手写的&#xff0c;有需要的自己拿去美化吧&#xff0c;基本的动画效果和菜单下滑效果和渐变效果已经做出来了&…

parentElement,srcElement 使用

代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equiv"Content-T…

哈哈哈,程序员没有女朋友的原因,我终于找到了!

全世界只有3.14 % 的人关注了爆炸吧知识程序员没有女朋友的原因▼程序员大脑里想的▼每天要学习太多语言&#xff0c;程序员太忙了▼女朋友 VS 编译器▼程序员sao起来&#xff0c;还需要女朋友吗&#xff1f;▼电脑才是程序员的女朋友▼互道晚安后&#xff0c;会不会偶遇在同一…

基于事件驱动架构构建微服务第7部分:在仓储上实现事件溯源

原文链接&#xff1a;https://logcorner.com/building-microservices-through-event-driven-architecture-part7-implementing-eventsourcing-on-repositories/在本文中&#xff0c;我将讨论Repository上的Event Sourcing实现。仓储负责将事件添加到事件存储并从事件存储中检索…

python选择题题目_Python接口测试题(持续更新中)

1、json和字典的区别&#xff1f; Json是轻量级的数据交互格式&#xff0c;以key-value的键值对形式来保存数据&#xff0c;结构清晰&#xff0c;可以说是目前互联网项目开发中最常用的一种数据交互格式。 字典&#xff0c;同样是以key-value的键值对来保存数据&#xff0c;是p…

html5 ajax数据显示,html5的ajax学习(二)

一、基础知识点1.ajax可以做事情&#xff1a;局部刷新 浏览器搜索列表记录 加载更多的数据2.登录页面同步网络请求&#xff1a;页面全部刷新&#xff0c;用户量大体验很不好3.ajax的详解&#xff1a;ajax的get和post请求 同步还是异步&#xff0c;true为异步ajax.open("ge…

ISA Server服务器故障恢复一例系统盘符更换之后的应对方法

周四下午的时候&#xff0c;某政府信息中心领导打电话告诉我&#xff0c;ISA Server服务器不能开机了。随后公司的技术员到达现场&#xff0c;经过检查&#xff0c;发现服务器显卡损坏。在更换显卡后&#xff0c;服务器可以开机&#xff0c;但却不能进入系统—-服务器在经过BIO…

扩展Windows Mobile模拟器存储空间的方法

在Windows Mobile应用程序开发的初期&#xff0c;可以使用SDK自带的模拟器来进行调试&#xff0c;这给我们开发人员提供了一种方便的途径。一般的应用程序&#xff0c;占用空间的大小也就几 百K&#xff0c;或者几M&#xff0c;这在模拟器上调试起来一点问题也没有。但是有的时…