canvas入门级小游戏《开关灯》思路讲解
游戏很简单,10行10列布局,每行每列各10盏灯,游戏初始化时随机点亮其中一些灯,点击某盏灯,其上下左右的灯及本身状态反转,如果点击前是灭着的,点击后即点亮,将所有灯全部点亮才算过关。游戏试玩:
下面说说大概思路:
生成画布
创建canvas画布,先是生成10*10阵列的100盏灯,每盏灯之间的间隔为margin = 5px,第一盏灯圆心坐标为它的半径"R, R",第一行第二盏灯坐标为3R+margin,以此类推得出灯坐标计算公式:第一行第i盏灯横坐标(2*i + 1)*R + i*margin,同理第一列第j行纵坐标为(2*j + 1)*R + j*margin
为其中灯开关的状态是随机的,很自然的想到利用随机数Math.random()去和0.5比较大小,随机数大于0.5则灯熄灭,否则点亮。为了便于游戏扩展和维护,游戏中灯的半径、所有灯的坐标、颜色、数量、是否点亮等数据用变量存起来。
<canvas id="canvas" width="445" height="445">
您的浏览器不支持canvas!
</canvas>
<script>
var lightOff = {
gameData : [], // 灯开关状态
r : 20, // 灯半径
margin: 5, // 灯间距
padding: 20, // canvas内边距
onColor: "#0077AA", // 灯亮的颜色
offColor: "#E0E0E0", // 灯灭的颜色
row : 10, // 10行
col : 10, // 10列
canvas : document.getElementById("canvas"),
ctx : this.canvas.getContext("2d"),
reDraw: function(p){
for (var i = 0; i < this.row; i++) {
for (var j = 0; j < this.col; j++) {
this.ctx.beginPath();
this.ctx.fillStyle = this.gameData[i][j] ? this.onColor : this.offColor;
this.ctx.arc( i*this.margin+(2*i+1)*this.r, j*this.margin+(2*j+1)*this.r, this.r, 0, 2*Math.PI );
this.ctx.fill();
}
}
return this;
},
// 随机生成100盏灯的状态
createMap: function(){
for (var i = 0; i < this.row; i++) {
this.gameData[i] = [];
for (var j = 0; j < this.col; j++) {
this.gameData[i].push( Math.random() > 0.5 ? false : true );
}
}
return this;
}
}
</script>
添加点击事件
众所周知,canvas是一个整体,如何给其中某一盏灯添加点击事件?事实上,可以给整个canvas对象添加点击事件,将event对象下的event.layerX, event.layerY传入isPointInPath(x, y)方法判断点击的坐标event.layerX, event.layerY是否在灯上从而触发回调函数。
示例:
需要注意的是:isPointInPath(x, y)方法只能判断坐标x, y是否在最近的上下文所绘制的图形内,如果canvas一次性绘制了100盏灯,isPointInPath(x, y)只能判断x, y是否在第100盏灯内,要想判断x, y是否在所点击的某盏灯内,就应该在每次点击的时候重绘这100盏灯(调用reDraw方法),每绘制一盏灯触发一次isPointInPath(x, y)方法,如果在灯上,将gameData对应灯的数据状态反转。如当前绘制第i行第j盏灯,调用isPointInPath(x, y)返回true,则反转该灯状态game[i][j] = !game[i][j]之后再次调用reDraw方法重绘。每次点击需要重绘两次。
综上所述,代码修改为:
var lightOff = {
gameData : [],
r : ,
margin: ,
padding: ,
onColor: "#0077AA",
offColor: "#E0E0E0",
row : ,
col : ,
canvas : document.getElementById("canvas"),
ctx : this.canvas.getContext("2d"),
init: function(){
var This = this;
// 判断是否点击了该圆点
this.canvas.addEventListener("click", function(ev){
This.reDraw(ev);
This.reDraw();
})
this.createMap().reDraw();
return this;
},
reDraw: function(p){
this.count = ;
this.ctx.clearRect(, , this.canvas.width, this.canvas.height);
for (var i = ; i < this.row; i++) {
for (var j = ; j < this.col; j++) {
this.ctx.beginPath(); this.ctx.fillStyle = this.gameData[i][j] ? this.onColor : this.offColor;
this.ctx.arc( i*this.margin+(*i+)*this.r, j*this.margin+(*j+)*this.r, this.r, , *Math.PI );
this.ctx.fill();
if( p && this.ctx.isPointInPath(p.layerX-this.padding, p.layerY-this.padding) ){
this.gameData[i][j] = !this.gameData[i][j];
i > && (this.gameData[i-][j] = !this.gameData[i-][j]);
i < && (this.gameData[i+][j] = !this.gameData[i+][j]);
j > && (this.gameData[i][j-] = !this.gameData[i][j-]);
j < && (this.gameData[i][j+] = !this.gameData[i][j+]);
}
this.gameData[i][j] && this.count++;
}
} if(this.count === ){
alert("成功了")
} return this;
},
createMap: function(){
for (var i = ; i < this.row; i++) {
this.gameData[i] = [];
for (var j = ; j < this.col; j++) {
this.gameData[i].push( Math.random() > 0.5 ? false : true );
}
}
return this;
}
} lightOff.init();
作者:古德God
出处:http://www.cnblogs.com/wangmeijian
本文版权归作者和博客园所有,欢迎转载,转载请标明出处。
如果您觉得本篇博文对您有所收获,请点击右下角的 [推荐],谢谢!
canvas入门级小游戏《开关灯》思路讲解的更多相关文章
- cocosCreator微信小游戏排行榜思路
cocosCreator制作微信小游戏排行榜实现方案: 游戏认知:项目分为主域和子域,主域就是游戏主程部分,子域为单独处理微信排行榜公共域数据的. 游戏主域里创建一个节点,添加WXSubContext ...
- 用Canvas制作小游戏——贪吃蛇
今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ...
- 微信小程序红包开发思路 微信红包小程序开发思路讲解
之前公司开发小程序红包,将自己在开发的过程中遇到的一些坑分享到了博客里.不少人看了以后,还是不明白怎么开发.也加了我微信咨询.所以今天,我就特意再写一篇文章,这次就不谈我开发中遇到的坑了.就主要给大家 ...
- 尝试用canvas写小游戏
还是习惯直接开门见山,这个游戏是有一个老师抓作弊的学生,老师背身,点学生开始加分,老师会不定时回头,如果老师回头还在点学生在,就会被抓住,游戏game over. 1.写游戏首先是loading条,于 ...
- C/C++入门级小游戏——开发备忘录
很多工科的学生在大一都有一门课程,叫C语言程序设计.大概就是装个IDE然后和一个黑乎乎的窗口打交道,期末到了考完试就结束了.然而很多人可能都有一个疑惑:C语言究竟能干什么?除开嵌入式单片机这些高大上的 ...
- java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
画笔Graphics Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图. Graphics常用的画图方法如下: drawLine(): ...
- 第一个leapmotion的小游戏
自从看过leapmotion的宣传视频,就被吸引住了.觉得这东西迟早要替代鼠标,然后关注了一年多leapmotion的动态,终于在今年8月份入手了一只.//675大洋啊,心疼~ 一直想写份评测,一直想 ...
- 微信小游戏开发之四:使用three.js引擎
一.前言 微信小游戏中最魔性的'跳一跳'就是基于three.js 引擎开发的 源码放到github上了:GitHub地址 请自行下载. 二.下载 three.min.js 打开页面,复制代码到本地 ...
- JS练习实例--编写经典小游戏俄罗斯方块
最近在学习JavaScript,想编一些实例练练手,之前编了个贪吃蛇,但是实现时没有注意使用面向对象的思想,实现起来也比较简单所以就不总结了,今天就总结下俄罗斯方块小游戏的思路和实现吧(需要下载代码也 ...
随机推荐
- node.js 开发简易的小爬虫
node.js 开发简易的小爬虫 最近公司开发一款医药类的软件,所以需要一些药品的基础数据,所以本人就用node.js写一个简易的小爬虫,并写记录这个Demo以供大家参考. 一.开发前的准备: 1, ...
- linux c 编程 ------ 串口编程
http://blog.csdn.net/specialshoot/article/details/50707965 对于串口的打开操作,必须使用O_NOCTTY参数.O_NOCTTY如果路径名指向终 ...
- P3959 宝藏
P3959 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nn 个深埋在地下的宝藏屋, 也给出了这 nn 个宝藏屋之间可供开发的 mm 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- bzoj千题计划200:bzoj3106: [cqoi2013]棋盘游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=3106 白棋如果第一步不能赢,那么一定输 因为可以黑棋走的距离比白棋大,黑棋可以下一步吃掉白棋,也可以 ...
- POJ 3537 multi-sg 暴力求SG
长为n的一列格子,轮流放同种棋子,率先使棋子连成3个者胜. 可以发现每次放一个棋子后,后手都不能放在[x-2,x+2]这个区间,那么相当于每次放棋将游戏分成了两个,不能放棋者败. 暴力求SG即可 /* ...
- (一)Git时间--初识版本控制工具
//配置一下你的身份 git config --global use.name "Douzi" git config --global use.email "jdouzi ...
- jQuery1.11源码分析(3)-----Sizzle源码中的浏览器兼容性检测和处理[原创]
上一章讲了正则表达式,这一章继续我们的前菜,浏览器兼容性处理. 先介绍一个简单的沙盒测试函数. /** * Support testing using an element * @param {Fun ...
- 20155318 2016-2017-2 《Java程序设计》第五周学习总结
20155318 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 try...catch 键盘输入利用java.util.Scanner,Scanner 名 ...
- 洛谷 P1525 【关押罪犯】种类并查集
题解 P1525 [关押罪犯]:种类并查集 前言: 在数据结构并查集中,种类并查集属于扩展域并查集一类. 比较典型的题目就是:食物链(比本题难一些,有三个种类存在) 首先讲一下本题的贪心,这个是必须要 ...
- python 的print和特殊方法 __str__和__repr__
先提出一个疑问,为什么print函数可以直接打印参数呢?即使是数字?例如print 1,就会打印1.我们知道1的类型是整型(题外话,在python中1是常量,也是类int的对象,而java中1只是常量 ...