HTML5游戏 看你有多“色” 开发
所有文章搬运自我的个人主页:sheilasun.me
在极客学院看到了这个游戏,在网上找到这个游戏玩了好久真的比较上瘾,于是自己也试着做了一下,可以戳这里试玩→看你有多色
游戏规则:
找出颜色不同的方块
梳理界面:
界面应该至少有三个部分:
1. 开始界面
提示玩法,以及游戏入口
2. 游戏界面
需要提供:
进行操作的地方(游戏区)
当前得分
当前剩余时间
游戏设计者特意设置了一分钟的时间限制,因为这款游戏真的很很很很很耗眼睛,我费尽力气也就玩了个“超级色魔lv44”级别,眼珠子都快瞪飞了。每一分钟让眼睛能休息下很科学。
暂停按钮
3. dialog界面
比如点了暂停会跳转到这里,这时应提供“继续游戏”按钮。
比如游戏结束了也会跳转到这里,这时应提供游戏结果,例如"经鉴定您是【瞎子lv2】",以及"再来一次"按钮。
以上的“界面”在html中可以用div实现,三个同样大小的div,position均为absolute,重叠在一起放置,通过隐藏或显示来完成“跳转”效果。
梳理细节:
上面这些是大致的框架,下面梳理细节部分。
首先是游戏区的实现,是一个正方形区块,有n*n个方块,n的值由当前关卡确定,越到后面的关卡,n值越大,要在2*2的格局中找出不同颜色的那个,轻而易举,在9*9的格局就不那么容易了。
而且,这个“不同颜色”的设置也有讲究,我们把每一关中出现的两种颜色称为“普通颜色”和“不同颜色”,如图,只有一个方块是“不同颜色”,其他方块涂的都是“普通颜色”,找出这特殊的一个就过关了。
每关的“普通颜色”随机获取(是黑色或白色就剔除重选),“不同颜色”就是在“普通颜色”上加点亮度,如亮度提升10%,这个提升的比例每关也有差别,越到后面值越小,越难分辨。
![此处输入图片的描述][2]
代码实现:
html以及css部分这里就不说细节了,关键的点就是:
三个界面的position要设为absolute,位置完全重合,叠叠乐,这样只要简单的隐藏或显示就行了。
刚加载时,显示“开始界面”div,游戏开始,显示“游戏界面”,暂停或游戏结束,显示“dialog”界面,继续游戏或再玩一次,又回到“游戏界面”。
主要是说一说js部分:
- 第一个问题,小方块们是如何画上去的?
其实一开始,我是想用a或span标签的,但是越到后面关卡,小方块越多,比如说9*9就能产生81个标签,这样的话,dom节点似乎有点多啊。于是我就想用canvas,我又想代码写起来可以简便些,于是我就找上了createjs家的easeljs,说干就干,赶紧奔到createjs官网上大致看了一下用法,赶紧开工,API不会用反正可以随时回来查。下面是easeljs绘制圆的示例用法:
var stage = new createjs.Stage("demoCanvas");//参数传入canvas对象或者其id
var circle = new createjs.Shape();
circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
stage.addChild(circle);
stage.update();
说个插曲,一开始我也在想是不是有必要引入createjs,后来我突然想起来我在网上玩这个游戏的时候,似乎看到别人的方块都是圆角的,比不加圆角好看好多,我,也想这么做。但是依稀记得canvas似乎并没有现成的画圆角矩形的方法,难道我要用arc加line去拼合?还有,我还得为那个特殊的小方块添加点击事件呢,如果就用原生的api,我需要这样做:
- 用一个变量a保存那个特殊的小方块覆盖的坐标范围
- 给canvas对象添加click事件
- 在click事件中判断click的位置与a中范围是否交叉,是的话,那么恭喜自己,点中啦
这太麻烦了,而用createjs的话,我可以直接使用drawRoundRectangle方法,我还可以在画小方块的时候就给它(仅给它)绑上click事件,特别方便。
- 第二个问题,如何随着关卡增加,同时增加游戏难度?
前面说过,难度的增加是通过增加"小方块的个数"和减少"不同颜色相对普通颜色增加的亮度比例",那么如何反映到代码上呢?
可以用一个数组保存每关的每行小方块个数(列方向上也是这个数),如:
var levs= [2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9]
这样每关的小方块总数就分别是:2*2,3*3,4*4,4*4......
每次要画小方块的时候,就从这个数组里取值,如第三关就是每行levs[2]个,每列也是levs[2]个,即共4*4个。
...
drawRects:function() {
gameView.removeAllChildren();//移除上次绘制
var num = this.levs[this.curLev];//当前关卡每行列应有的方块数
//计算每个小方块的宽度,所有小方块宽度加上两两之间的间隔构成整个stage(绘制舞台)的宽度
var width = (stage.canvas.width - gap * (num - 1)) / num;
var height = (stage.canvas.height - gap * (num - 1)) / num;
var color = randomColor();//获取随机色
var pickedX = _randomPick(0, num - 1);//随机指定特殊方块的位置
var pickedY = _randomPick(0, num - 1);
for (var i = 0; i < num; i++) {
for (var j = 0; j < num; j++) {
var rec;
if (i === pickedX && j === pickedY) {
rec = new Rectangle(width, height, color, .5, Rectangle.TYPE_PICKED);//创建特殊方块
(function (me) {
rec.addEventListener('click', function () {
me.nextLevel();//进入下一关
})
})(this);//注意闭包
} else {
rec = new Rectangle(width, height, color, .5, Rectangle.TYPE_NORMAL);//创建普通方块
}
gameView.addChild(rec);
rec.x = (width + gap) * i;//偏移&&铺开
rec.y = (height + gap) * j;
}
}
}
...
需要注意添加监听事件的地方,一开始写的时候没注意直接用的this.nextLevel(),直接去window对象上找了,结果nextLevel方法自然是undefined。解决的办法是创建一个立即执行函数,传入this。
那么如何设置亮度提升比例呢?
当然也可以用类似上面的方法,用另一个数组保存这些比例。但是我不想写那么死,还是用一个函数实现吧:
在20%与60%间取值。
...
getLightenRatio: function () { //由当前关卡数获取亮度增加比例
var minValue = 0.2, maxValue = 0.6;
return maxValue - (maxValue - minValue) / (this.levs.length - 1) * this.curLev;
}
...
- 第三个问题,如何计算得分?如何结束游戏?如何获得鉴定级别(或者说头衔)?
关于得分这里我都是做的简单处理,过一关则加一分。
关于结束方式,因为这个游戏里没有僵尸没有炸弹,唯一的结束方式就只能是时间用完啦。
关于鉴定级别,如我们玩的时候看到的“色狼lv23”是如何得到的呢?
还是定义一个数组,保存了这些级别的名称。
var title=["瞎子", "色盲", "色郎", "色狼", "色鬼", "色魔", "超级色魔", "变态色魔", "孤独求色"];
显示游戏结果的时候,就是从这个数组里取出某值,具体取哪个值,就看自己定义的规则了。
比如说,我认为得分15分或以下的基本就算瞎子了,之后每加五分晋级一次,比如15分对应“瞎子”,16-20分对应“色盲”,21-25对应“色狼”,以此类推下去。
唯一需要注意的就是边界控制,不要超出数组最大索引。
- 第四个问题,暂停以及继续游戏应该做些什么?
用一个变量保存剩余时间leftTime,缺省值是60,即一分钟后游戏结束.
如果没有暂停功能,那么处理起来很简单,游戏刚进入时,初始化计时器,一秒tick一次,只要在计时器的tick事件里递减这个leftTime即可,当leftTime小于0,结束。
但加入暂停功能也不麻烦,只要手动设置一个标记isPaused,在tick事件的最开始判断这个标记的值,false则执行事件的递减。暂停按钮的点击即是改变这个变量的值为true,继续游戏按钮的点击即是改变其为false。
...
pause: function () { //暂停游戏
this.isPaused = true;
},
resume: function () { //继续游戏
this.isPaused = false;
},
...
tick事件内部:
if (!me.isPaused) {
--me.leftTime;
if (me.leftTime === 0) {
me.gameover();
}
}
- 第五个问题,“再来一次”该做些什么?
应该回到游戏界面并将环境重置,所以之前的代码中应该提供一个reset方法,这里调用这个方法即可。
好了,这样下来,整个游戏差不多就完成了,还是戳这里可以玩~→看你有多色
戳这里有代码~→github-sheila1227,代码遵循AMD规范,入口文件如下:
<script src="http://libs.tan14.net/require.js/2.1.14/require.min.js" data-main="js/app.js"></script>
入口文件中做一下配置:
requirejs.config({
"baseUrl": "./js",
"paths": {
"app": "app",
"jquery": "//libs.baidu.com/jquery/2.0.0/jquery.min" ,//结尾不要加.js扩展名
"createjs": "easeljs.min"
}
});
// Load the welcome module to start the app
requirejs(["welcome"], function(welcome) {
welcome.init('.page-welcome.page');
});
这里有个问题是,因为jQuery支持AMD,所以我可以直接require,但是createjs不支持AMD,所以我直接用script标签直接引入,但我感觉是不是应该用define包一下,让它也可以支持requirejs的方式。这个问题,留着后面查查资料再解决吧~
有任何不妥之处或错误欢迎各位指出,不胜感激~
HTML5游戏 看你有多“色” 开发的更多相关文章
- H5小游戏——看你有多色
使用了封装了canvas的create.js库来实现的. 最终效果: 工程: Rect.js /* * 方块类 */ function Rect(n,color,specialColor){ crea ...
- JAVASCRIPT开发HTML5游戏--斗地主(网络对战PART4)
继之前用游戏引擎(青瓷引擎)做了斗地主单机版游戏之后,这里分享下使用socket.io来实现网络对战,代码可已放到github上,在此谈谈自己整个的开发思路吧. 客户端代码 服务端代码 (点击图片进入 ...
- javascript开发HTML5游戏--斗地主(单机模式part3)
最近学习使用了一款HTML5游戏引擎(青瓷引擎),并用它尝试做了一个斗地主的游戏,简单实现了单机对战和网络对战,代码可已放到github上,在此谈谈自己如何通过引擎来开发这款游戏的. 客户端代码 服务 ...
- 2016年 最火的 15 款 HTML5 游戏引擎
HTML5游戏从2014年Egret引擎开发的神经猫引爆朋友圈之后,就开始一发不可收拾,今年<传奇世界>更是突破流水2000万!从两年多的发展来看,游戏开发变得越来越复杂,需要制作各种炫丽 ...
- 模仿开发H5游戏,看你有多色
开发记录 前言 之前跟着慕课网学习开发H5小游戏开心鱼,勾起我的兴趣. 在写代码的过程中,不怎么会遇到问题.虽然代码是亲手敲出来的,但是由于并没有对游戏的整体思路,所以并不知道开发与优化的过程. 为了 ...
- HTML5游戏开发引擎,初识CreateJS
CreateJS为CreateJS库,可以说是一款为HTML5游戏开发的引擎.打造 HTML5 游戏,构建新游戏,提供构建最新 HTML5 的技术.你可以通过这个网站学习如何构建跨平台和跨终端游戏.这 ...
- JS开发HTML5游戏《神奇的六边形》(二)
近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
- HTML5游戏开发进阶指南(亚马逊5星畅销书,教你用HTML5和JavaScript构建游戏!)
HTML5游戏开发进阶指南(亚马逊星畅销书,教你用HTML5和JavaScript构建游戏!) [印]香卡(Shankar,A.R.)著 谢光磊译 ISBN 978-7-121-21226-0 201 ...
- JS开发HTML5游戏《神奇的六边形》(四)
近期出现一款魔性的消除类HTML5游戏<神奇的六边形>,今天我们一起来看看如何通过开源免费的青瓷引擎(www.zuoyouxi.com)来实现这款游戏. (点击图片可进入游戏体验) 因内容 ...
随机推荐
- CentOS6.8下Jenkins+maven+tomcat+git+shell自动构建、部署web应用环境的搭建
参考资料:http://www.cnblogs.com/cheng95/p/6542036.html http://www.cnblogs.com/software-test/p/7068278.ht ...
- Java编程思想 学习笔记9
九.接口 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 1.抽象类和抽象方法 抽象类是普通的类与接口之间的一种中庸之道.创建抽象类是希望通过这个通用接口操纵一系列类. Java提 ...
- 神级程序员通过两句话带你完全掌握Python最难知识点——元类!
千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
- 宕机不等于关机,阴魂不散的vm
今天早上刚到公司,就发现研发环境的机器连不上了. 公司研发环境的部署比较简单,物理机上装VMware Esxi 6 ,然后在esxi上装虚机. 检查发现:esxi ping不通,客户端也连不上:物理机 ...
- Java SE之Java中堆内存和栈内存[转/摘]
[转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...
- vue单页应用中 返回列表记住上次滚动位置、keep-alive缓存之后更新列表数据 那点事
实践场景需求 产品列表中,滚动到一定位置的时候,点击查看产品信息,后退之后,需要回到原先的滚动位置,这是常见的需求 所有页面均在router-view中,暂时使用了keep-alive来缓存所有页面, ...
- mysql 案例~mysql元数据的sql统计
一 简介:今天我们来收集下提取元数据的sql 二 前沿: information_schema 引擎 memory 元数据收集表 三 sql语句: 1#没有使用索引的表统计 SELECT t.TAB ...
- MR架构
MapReduce框架结构 Map/Reduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的,Google已经将它完整的MapReduce论文公开发布了.其中对它 ...
- 【Mysql sql inject】【入门篇】sqli-labs使用 part 3【15-17】
Less-15- Blind- Boolian Based- String 1)工具用法: sqlmap -u --batch --technique BEST 2)手工注入 时间盲注放弃用手工了 ...
- 【vim】跳转到上/下一个修改的位置
当你编辑一个很大的文件时,经常要做的事是在某处进行修改,然后跳到另外一处.如果你想跳回之前修改的地方,使用命令: Ctrl+o 来回到之前修改的地方 类似的: Ctrl+i 会回退上面的跳动.