HTML5扫雷游戏
2016-01-17 12:04
811 查看
上周末突然想尝试着做一个扫雷游戏。扫雷游戏我是很喜欢玩的,更年轻时候,晚上晚上几点钟的时候都有。。。
虽然之前没有写过HTML5游戏,不过我感觉肯定能写出来的。虽然对于写H5游戏有哪些步骤什么的都不是很明了。
另外一点,写这个游戏,所有的算法都必须是自己思考出来,不能在写之前去参考别人的思路。
因为一旦参考了,就会受到别人思路左右,永远没有机会从无到有地去思考这个自己喜欢过的游戏了。
然后上周末完成了基本雏形,上周闲的时候又断断续续地完善。一个功能一个功能地实现。 中间还抽空做了一个贪吃蛇。 相比扫雷而言,贪吃蛇的逻辑就相当简单了。
先看几个过程中的版本:
完成版本,已经像模像样了呢!用了网上下的图片扫雷资源,数字,旗子之类的。
实现的功能,按完成步骤。
1.根据格子数量,初始化canvas画布。绘制格子。 初始化所需要的数组。包含格子信息的格子数组。
2.鼠标划过每一个格子改变格子。 需要判断鼠标在画布上的坐标。然后根据画布坐标判断格子。
3.随机生成雷。 do while循环,生成不重复的格子坐标保存到地雷数组和格子数组。
4.点击打开雷。显示周围雷的数量。如果雷的数量为0。则用一个递归计算这个雷周围8个格子里有没有周边雷数量为0的格子,如果有,再计算这个格子周围。。。直到把相连的所有周边雷数量为0的格子找出来,放入一个数组。然后再把这个数组里所有格子以及它们周围的8个格子显示出来,显示每个格子周围雷的数量 。雷的数量用不同颜色。
不过我感觉这个算法效率还不是很高。要优化。
5.被打开过的格子或被标记过的格子,没有hover事件。
6.标记格子。用旗子或问号。 屏蔽网页原本的右键事件。
7.加上时间,以及雷的数量的标记。以及点击的时候才生成雷。避免第一次点击 就点到雷。
8.双键同击事件。如果周边雷的数量等于周边标记的数量,就把周边没有打开没有标记的点开。不等于就动态展现周边剩下哪几个没打开的。
9.点中的雷以记错误的标记用不同的图像表达出来。
10.用网上下的资源美化。增加级别选择。高级,中级,初级,以及自定义。优化界面效果。
部门代码:
演示地址:
http://runningls.com/demos/2016/mine/mine.html
欢迎留言讨论。
转载注明出处:/article/3711603.html
虽然之前没有写过HTML5游戏,不过我感觉肯定能写出来的。虽然对于写H5游戏有哪些步骤什么的都不是很明了。
另外一点,写这个游戏,所有的算法都必须是自己思考出来,不能在写之前去参考别人的思路。
因为一旦参考了,就会受到别人思路左右,永远没有机会从无到有地去思考这个自己喜欢过的游戏了。
然后上周末完成了基本雏形,上周闲的时候又断断续续地完善。一个功能一个功能地实现。 中间还抽空做了一个贪吃蛇。 相比扫雷而言,贪吃蛇的逻辑就相当简单了。
先看几个过程中的版本:
完成版本,已经像模像样了呢!用了网上下的图片扫雷资源,数字,旗子之类的。
实现的功能,按完成步骤。
1.根据格子数量,初始化canvas画布。绘制格子。 初始化所需要的数组。包含格子信息的格子数组。
2.鼠标划过每一个格子改变格子。 需要判断鼠标在画布上的坐标。然后根据画布坐标判断格子。
3.随机生成雷。 do while循环,生成不重复的格子坐标保存到地雷数组和格子数组。
4.点击打开雷。显示周围雷的数量。如果雷的数量为0。则用一个递归计算这个雷周围8个格子里有没有周边雷数量为0的格子,如果有,再计算这个格子周围。。。直到把相连的所有周边雷数量为0的格子找出来,放入一个数组。然后再把这个数组里所有格子以及它们周围的8个格子显示出来,显示每个格子周围雷的数量 。雷的数量用不同颜色。
不过我感觉这个算法效率还不是很高。要优化。
5.被打开过的格子或被标记过的格子,没有hover事件。
6.标记格子。用旗子或问号。 屏蔽网页原本的右键事件。
7.加上时间,以及雷的数量的标记。以及点击的时候才生成雷。避免第一次点击 就点到雷。
8.双键同击事件。如果周边雷的数量等于周边标记的数量,就把周边没有打开没有标记的点开。不等于就动态展现周边剩下哪几个没打开的。
9.点中的雷以记错误的标记用不同的图像表达出来。
10.用网上下的资源美化。增加级别选择。高级,中级,初级,以及自定义。优化界面效果。
部门代码:
var Mine = function (ele,panewidth,paneheight,minenum,tagele,timeele) { this.PANE_SIZE = 16;//每个格子的像素px大小。 this.paneheight = paneheight;//有几行 this.panewidth = panewidth;//有几列 this.minenum = minenum;//有几个雷 this.ele = document.getElementById(ele); this.cxt = this.ele.getContext("2d"); this.tagele = tagele; this.timeele = timeele; }
init:function(){ //画格子 this.ele.width = this.PANE_SIZE * this.panewidth; this.ele.height = this.PANE_SIZE * this.paneheight; this.oldPos = [0,0];//鼠标上一个停留的位置。默认值。用于处理hover事件。 this.cellArr=[];//格子信息保存数组。保存每个格子是不是雷,当前是否有标记。 this.mineArr=[];//地雷位置数组。 this.time = 0;//操作时间 this.notTaged = this.minenum;//未标记数量 this.numToImage(this.notTaged,this.tagele);//将标记数字转成图片 this.numToImage(this.time,this.timeele);//将时间数字转成图片 this.mousedownArr='';//鼠标点下事件,是为了双键同击事件。 this.createCells();//初始化cellArr数组,并涂上颜色。 this.inited = false;//是否初始化过。 clearInterval(this.timer);//时间跳动 //绑定事件 this.onmousemove();//鼠标在上面移动,触发每个格子的 this.onmouseout();//鼠标移出canvas的事件。 this.onmousedown();//鼠标点下事件,是为了双键同击事件。 this.onclick();//点击方格事件 this.preRightMenu();//阻止右键菜单。 }
createMines:function(pos){ //生成雷的位置。保存到一个数组[[2,3],[4,6]]; var minenum = this.minenum; var mineArr = this.mineArr; var mineItem=''; var cellArr = this.cellArr; for (var i = 0; i < minenum; i++) { //如果生成的重复了就重新生成。 do{ mineItem = [getRandom(this.panewidth),getRandom(this.paneheight)]; }while(in_array(mineItem,mineArr)||pos.toString()== mineItem.toString()); cellArr[mineItem[0]][mineItem[1]].isMine = true; mineArr.push(mineItem); }; }
getCellArea:function(pos){//根据格子坐标返回一个格子左上角的像素坐标[32,666]; return [(pos[0]-1)*this.PANE_SIZE+1,(pos[1]-1)*this.PANE_SIZE+1]; }, getCellPos:function(coordinate){//根据像素坐标返回格子坐标。[3,5]; return [Math.ceil(coordinate.x/this.PANE_SIZE),Math.ceil(coordinate.y/this.PANE_SIZE)]; }
//获取坐标: function getEventPosition(ev){ var x, y; if (ev.layerX || ev.layerX == 0) { x = ev.layerX; y = ev.layerY; }else if (ev.offsetX || ev.offsetX == 0) { // Opera x = ev.offsetX; y = ev.offsetY; } return {x: x, y: y}; }
drawCell:function(pos,type){//绘制不同种类的格子。 var area = this.getCellArea(pos); var cxt = this.cxt; var image = new Image(); var src; var srcArr = ["res/blank.bmp","res/0.bmp","res/flag.bmp","res/ask.bmp","res/mine.bmp","res/blood.bmp","res/error.bmp"]; //1正常格 2mouseover格子 3旗子格 4问号格 5正常雷格 6点中雷格 7.错误标记 var index = type -1; image.src =srcArr[index]; image.onload = function(){ cxt.drawImage(image,area[0],area[1],16,16); } }, drawNum:function(pos,num){//绘制数字 var area = this.getCellArea(pos); var cxt = this.cxt; var image = new Image(); image.src = "res/"+num+".bmp"; image.onload = function(){ cxt.drawImage(image,area[0],area[1],16,16); } }
calZeroMine:function(pos,zeroArr){//使用递归求出周围所有的全为0的区域。算法效率还不是很高。 var cellArr = this.cellArr; // var aroundArr = [[pos[0]-1,pos[1]],[pos[0],pos[1]-1],[pos[0],pos[1]+1], [pos[0]+1,pos[1]]];//只保留上下左右 好像还是会有一点问题。 var aroundArr = [[pos[0]-1,pos[1]-1],[pos[0]-1,pos[1]],[pos[0]-1,pos[1]+1],[pos[0],pos[1]-1],[pos[0],pos[1]+1],[pos[0]+1,pos[1]-1],[pos[0]+1,pos[1]],[pos[0]+1,pos[1]+1]]; var aroundMineNum = 0; for (var i = 0; i < aroundArr.length; i++) { aroundMineNum = this.calAround(aroundArr[i]);//附近雷的数量 if(aroundMineNum == 0 && this.checkCell(aroundArr[i]) && cellArr[aroundArr[i][0]][aroundArr[i][1]].isMine == false &&!in_array(aroundArr[i],zeroArr)){ zeroArr.push(aroundArr[i]); this.calZeroMine(aroundArr[i],zeroArr);//调用自己,递归。 } }; return zeroArr; }
var mine1 = new Mine("mine1",30,16,99,"game-tag-images","game-time-images"); mine1.init();
演示地址:
http://runningls.com/demos/2016/mine/mine.html
欢迎留言讨论。
转载注明出处:/article/3711603.html
相关文章推荐
- html5的video标签插入mp4视频放在iis服务器访问无法播放解决方案
- HTML5 mobile 旋轉餅圖
- HTML5绘图基础_07_绘制第二个图形
- HTML5绘图基础_06_既填充区域又绘制线条
- HTML5绘图基础_05_填充区域
- HTML5绘图基础_04_绘制封闭线条
- HTML5绘图基础_03_绘制连续线条
- HTML5绘图基础_02_绘制线条
- HTML5绘图基础_01_Canvas的使用
- 使用html5 canvas实现漂亮时钟
- 用HTML5实现的各种排序算法的动画比较
- 重温html5的新增的标签和废除的标签
- HTML5中国象棋游戏源代码
- 04. Web大前端时代之:HTML5+CSS3入门系列~HTML5 表单
- HTML5定稿一周年,谈谈我与HTML5
- HTML5 应用程序缓存
- 整理的HTML5 CANVAS 定义、属性和方法
- html5和css3新特性
- html5的离线本地缓存
- html5 中常用的标签和属性