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,想编一些实例练练手,之前编了个贪吃蛇,但是实现时没有注意使用面向对象的思想,实现起来也比较简单所以就不总结了,今天就总结下俄罗斯方块小游戏的思路和实现吧(需要下载代码也 ...
随机推荐
- yolo-v2只识别person
一.修改源代码 (1)修改cfg/voc.data classess=20 改成 classes = 1 (2)修改data/voc.names 只留下person这一类 (3)修改exampl ...
- C#创建基本图表(Chart Controls)
在.NET环境下微软提供了强大了图表控件,并给多了很多实例,关于图表的基本元素如下: 并且MSDN给出了创建图表的示例步骤,原文地址:http://msdn.microsoft.com/en-us/l ...
- java基础-多线程应用案例展示
java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...
- Java基础-hashMap原理剖析
Java基础-hashMap原理剖析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是哈希(Hash) 答:Hash就是散列,即把对象打散.举个例子,有100000条数 ...
- docker mysql authentication_string client does not support authentication 连接问题
docker安装mysql后,本地navicat连接报错client does not support authentication 解决办法: 1. docker ps -a 查找到容器id 2. ...
- 数据库类型与JDBC TYPE 和Java类型对应关系
https://blog.csdn.net/seelye/article/details/40105969
- bzoj千题计划258:bzoj3123: [Sdoi2013]森林
http://www.lydsy.com/JudgeOnline/problem.php?id=3123 启发式合并主席树 #include<cmath> #include<cstd ...
- 前三章 man手册 查看文件
1 – 3章 1.1 man手册: 分1 - 9个区域,可以认为是一个一个小节 把man手册理解为一本书 第一节:可执行程序或shell命令 第二节:系统调用 第三节:库调用 第四节:特殊文件 第五节 ...
- 将网页设置为允许 XMLHttpRequest 跨域访问
在非IE下,使用XMLHttpRequest 不能跨域访问, 除非要访问的网页设置为允许跨域访问. 将网页设置为允许跨域访问的方法如下: Java Response.AddHeader("A ...
- Myeclipse 工具优化 [内存一直增加, jsp,javascript 编辑很卡]
首先看这篇随笔 地址: Myeclipse/STS 首次在本地部署配置一个Spring MVC 项目 (十二) [http://www.cnblogs.com/editor/p/3915239.htm ...