HTML5小游戏贪吃蛇分析与实现
2016-01-13 21:28
711 查看
昨天下午研发中心总结大会,晚上大家一起吃饭。 多少面孔成了曾经,多人新人充满憧憬,明年又会是如何。年年岁岁花相似,岁岁年年人不同。
晚上大家吃饭,我们桌不喝酒。 口味虽然淡了点,勉强也还算尽兴。
8点多回到家想起下午开会时想到的贪吃蛇小游戏,就准备动手写一个。
先上效果图:
贪吃蛇的逻辑非常简单,稍微动一下脑子就能想出来。
规则:1、撞到墙壁或撞到自己。判输。
2、撞到幸运点,自身长大一格。
3、每长大一格,分数增加10。分数每增加100,速度提升一个级别。
逻辑:
1.首先要理解蛇的运动。很容易发现蛇每往前走一步。本质就是增加一个头部点,去掉原来的尾巴点。中间的所有点都是不动的。 用程序化的表达,整条贪吃蛇可以是一个类似这样[[1,2],[1,3]]的带位置信息的数组,每移动一步,我们往数组推入一个新的坐标点,并移除第一个坐标点。
2.如何获取下一个点的坐标。我们的蛇理论上可以往上下左右四个方向移动。可以根据现在蛇头的坐标和方向计算出合适的x,y坐标。就是新的蛇头坐标。 比如[1,2]往右边移动一下就变成[2,2],往右边移动的本质是x坐标增加1。
3.控制方向。 监控键盘事件。 注意:当前是向右的时候,下一步只可能是往上或往下或往右,不会出现倒退的情况。
4.生成幸运点。 一要随机。二不能生成在贪吃蛇身上。 也就是幸运点坐标不能在贪吃蛇身体的坐标组中就可以。
5.吃掉幸运点。 贪吃蛇坐标数组中添加幸运点到数组尾部。并且不移除蛇尾。
6.判断输。 如果新生成的头部的坐标,是蛇身坐标组是的一个值。说明撞到自己了。 如果新生成的头部坐标的x,y值超出了边界值。判输。
7.分数和速度。 速度就是控制蛇运动的 timer执行的时间间隔而已。
核心代码:
初始化:
方法(部分):
调用:
演示地址:http://runningls.com/demos/2016/snake/snake.html
欢迎留言交流。转载注明出处:/article/3620720.html
晚上大家吃饭,我们桌不喝酒。 口味虽然淡了点,勉强也还算尽兴。
8点多回到家想起下午开会时想到的贪吃蛇小游戏,就准备动手写一个。
先上效果图:
贪吃蛇的逻辑非常简单,稍微动一下脑子就能想出来。
规则:1、撞到墙壁或撞到自己。判输。
2、撞到幸运点,自身长大一格。
3、每长大一格,分数增加10。分数每增加100,速度提升一个级别。
逻辑:
1.首先要理解蛇的运动。很容易发现蛇每往前走一步。本质就是增加一个头部点,去掉原来的尾巴点。中间的所有点都是不动的。 用程序化的表达,整条贪吃蛇可以是一个类似这样[[1,2],[1,3]]的带位置信息的数组,每移动一步,我们往数组推入一个新的坐标点,并移除第一个坐标点。
2.如何获取下一个点的坐标。我们的蛇理论上可以往上下左右四个方向移动。可以根据现在蛇头的坐标和方向计算出合适的x,y坐标。就是新的蛇头坐标。 比如[1,2]往右边移动一下就变成[2,2],往右边移动的本质是x坐标增加1。
3.控制方向。 监控键盘事件。 注意:当前是向右的时候,下一步只可能是往上或往下或往右,不会出现倒退的情况。
4.生成幸运点。 一要随机。二不能生成在贪吃蛇身上。 也就是幸运点坐标不能在贪吃蛇身体的坐标组中就可以。
5.吃掉幸运点。 贪吃蛇坐标数组中添加幸运点到数组尾部。并且不移除蛇尾。
6.判断输。 如果新生成的头部的坐标,是蛇身坐标组是的一个值。说明撞到自己了。 如果新生成的头部坐标的x,y值超出了边界值。判输。
7.分数和速度。 速度就是控制蛇运动的 timer执行的时间间隔而已。
核心代码:
初始化:
var Snake = function(ele,scoreele,speedele,x,y){ this.cellWidth = 10;//每个格子的大小 this.ele = document.getElementById(ele); this.cxt = this.ele.getContext("2d"); this.x=x; this.y=y; this.scoreele = document.getElementById(scoreele); this.speedele = document.getElementById(speedele); //生成canvas大小。边框。 this.ele.width = this.cellWidth * this.x; this.ele.height = this.cellWidth * this.y; this.ele.style.border ="1px solid #000"; this.changeDiretion();//绑定方向事件。 }
方法(部分):
Snake.prototype = { init:function(){ //初始化,重置。恢复js数据以及dom。 this.direction = 1;//向右 2下 3左 4 上 this.nextDirection = ''; this.snakeArr = [[0,parseInt(this.y/2)],[1,parseInt(this.y/2)]]; this.speed = 1; this.score = 0; this.cxt.fillStyle ='#fff'; this.cxt.fillRect(0,0,this.cellWidth*this.x,this.cellWidth*this.y); this.scoreele.innerHTML="得分:0"; this.speedele.innerHTML="速度:1"; this.createCoolPoint(); this.drawCell(this.coolPoint,2); this.drawSnake(); this.setTimer(); }, getCellArea:function(pos){//返回一个格子左上角的像素坐标[32,666]; return [(pos[0]-1)*this.cellWidth+1,(pos[1]-1)*this.cellWidth+1]; }, setTimer:function(){ var speedArr = [900,800,700,600,500,400,300,200,100]; var speed = this.speed; if(speed>8){ speed = 8; } (function(theThis){ var that = theThis; that.timer = setTimeout(function() { that.moveSnake(); }, speedArr[speed]); })(this); }, moveSnake:function(){ //移动蛇的逻辑。数组处理。 this.direction = this.nextDirection == ''?this.direction:this.nextDirection;//当前移动方向,和下一个移动方向。这样处理能避免一个bug. var direction = this.direction; var snakeArr = this.snakeArr; var snakeHead = snakeArr[snakeArr.length-1]; switch(direction){ case 1 ://向右 snakeHead = [snakeHead[0]+1,snakeHead[1]]; break; case 2 ://向下 snakeHead = [snakeHead[0],snakeHead[1]+1]; break; case 3 ://向左 snakeHead = [snakeHead[0]-1,snakeHead[1]]; break; case 4 ://向上 snakeHead = [snakeHead[0],snakeHead[1]-1]; break; } //超界,或撞上自己。结束,重置。 if(in_array(snakeHead,snakeArr) || snakeHead[0]<0 || snakeHead[0]>this.x || snakeHead[1]<0 || snakeHead[1]>this.y){ window.clearInterval(this.timer); alert('胜败乃兵家常事 大侠请重新来过。得分:'+this.score); this.init(); return; } snakeArr.push(snakeHead);//将蛇头放入数组 this.drawCell(snakeHead,1); if(snakeHead.toString() != this.coolPoint.toString()){ var tail = snakeArr.shift();//移除蛇尾。 this.drawCell(tail,0); }else{//撞到coolPoint this.createCoolPoint(); this.drawCell(this.coolPoint,2); this.score = this.score + 10; this.scoreele.innerHTML="得分:"+this.score; this.speed = Math.ceil((this.score + 1)/100); this.speedele.innerHTML="速度:"+this.speed; console.log(this.score); console.log(this.speed); } this.setTimer(); }, createCoolPoint:function(){//随机生成coolPoint,不在代表snakeArr的数组中。 do{ this.coolPoint = [getRandom(this.x),getRandom(this.y)]; }while(in_array(this.coolPoint,this.snakeArr)); }, changeDiretion:function(){ //更换移动方向。下一步的移动方向。 var that = this; document.onkeydown=function(event){ var e = event || window.event || arguments.callee.caller.arguments[0]; var direction = that.direction; var keyCode = e.keyCode; switch(keyCode){ case 39://右 if(direction!=1 && direction !=3){ that.nextDirection = 1; } break; case 40://下 if(direction!=2 && direction !=4){ that.nextDirection = 2; } break; case 37://左 if(direction!=1 && direction !=3){ that.nextDirection = 3; } break; case 38://上 if(direction!=2 && direction !=4){ that.nextDirection = 4; } break; default: break; } }; }, drawSnake:function(){ //绘制初始小蛇。 var snakeArr = this.snakeArr; for (var i = 0,sLen=snakeArr.length; i < sLen; i++) { this.drawCell(snakeArr[i],1); }; }, drawCell:function(pos,type){//绘制会用到的几种颜色的图。 var colorArr = ['#fff','rgb(0,140,202)',"red"]; var cxt = this.cxt; var area; cxt.fillStyle = colorArr[type]; area = this.getCellArea(pos); cxt.fillRect(area[0],area[1],this.cellWidth-1,this.cellWidth-1); } }
调用:
var snake = new Snake("snake","score","speed",15,15); snake.init();
演示地址:http://runningls.com/demos/2016/snake/snake.html
欢迎留言交流。转载注明出处:/article/3620720.html
相关文章推荐
- 【HTML5】DOMContentLoaded事件
- 怎么利用CSS实现HTML5响应式导航栏
- Modernizr——为HTML5和CSS3而生!
- HTML5开发精要 元素
- HTML5学习笔记(2):input type file的特性
- 我们都忽略了Html5的力量,如果只看成一种技术就大错特错了!
- 我们都忽略了Html5的力量,如果只看成一种技术就大错特错了!
- HTML5 WebSocket简介
- html5的一些表单属性
- selenium处理HTML5的视频播放
- 使用 HTML5、CSS3 和 MathML 在 EPUB 3 中制作版式丰富的出版物
- HTML5 CSS3专题 纯CSS打造相冊效果
- 使用CDH5.3.0中Hadoop安装包进行伪分布模式安装
- 网页加入HTML5时钟的快捷方式
- HTML5学习笔记(1):HTML5介绍与语法
- HTML5的学习(二)HTML5标签
- 03.Web大前端时代之:HTML5+CSS3入门系列~H5功能元素
- 不介绍html5,那html都有些什么内容
- 四,JavaWeb简略的谈下前端技术<一>HTML5的各个标记
- 网页版HTML5愤怒的小鸟在线效果