#map { width: 1350px; height: 640px; background-color: #ccc; position: relative; }
游戏对象
蛇对象
食物对象
var position='absolute'; var elements=[]; function Food(x,y,width,height,color){ this.x=x || 0; this.y=y || 0; this.width=width || 20; this.height=height || 20; this.color=color || 'green'; }
通过原型设置render方法,实现随机产生食物对象,并渲染到map上
//通过原型设置render方法,实现随机产生食物对象,并渲染到map上 Food.prototype.render=function (map){ // 随机食物的位置,map.宽度/food.宽度, //总共有多少分food的宽度,随机一下。 //然后再乘以food的宽度 this.x=parseInt(Math.random()*map.offsetWidth/this.width)*this.width; this.y=parseInt(Math.random()*map.offsetHeight/this.height)*this.height; // 动态创建食物对应的div var div=document.createElement('div'); map.appendChild(div); div.style.position=position; div.style.left=this.x+'px'; div.style.top=this.y+'px'; div.style.width=this.width+'px'; div.style.height=this.height+'px'; div.style.backgroundColor = this.color; elements.push(div); }
通过自调用函数,进行封装,通过window暴露Food对象
window.Food = Food;
-
width 蛇节的宽度 默认20
-
height 蛇节的高度 默认20
-
body 数组,蛇的头部和身体,第一个位置是蛇头
-
direction 蛇运动的方向 默认right 可以是 left top bottom
(function(){ var position='absolute'; var elements=[]; function Snake(width,height,direction){ this.width=width || 20; this.height=height || 20; this.body=[ {x:3,y:2,color:'red'}, {x:2,y:2,color:'blue'}, {x:1,y:2,color:'blue'} ]; this.direction=direction || 'right'; } Snake.prototype.render=function(map){ for(var i=0;i<this.body.length;i++){ var obj=this.body[i]; var div=document.createElement('div'); map.appendChild(div); div.style.left=obj.x*this.width+'px'; div.style.top=obj.y*this.height+'px'; div.style.position=position; div.style.backgroundColor=obj.color; div.style.width=this.width+'px'; div.style.height=this.height+'px'; } }
在自调用函数中暴露Snake对象
window.Snake = Snake;
//构造函数 (function(){ var that=null; function Game(map){ this.Food=new Food(); this.Snake=new Snake(); this.map=map; that=this; } //开始游戏,渲染食物对象和蛇对象 Game.prototype.start=function(){ this.Food.render(this.map); this.Snake.render(this.map); this.Snake.move(this.Food,this.map); this.Snake.render(this.map); runSnake(this.Snake, this.map); bindKey(); }
写蛇的move方法
/*- 在蛇对象(snake.js)中,在Snake的原型上新增move方法 1. 让蛇移动起来,把蛇身体的每一部分往前移动一下 2. 蛇头部分根据不同的方向决定 往哪里移动 */ Snake.prototype.move=function(Food,map){ // 让蛇身体的每一部分往前移动一下 var i=this.body.length-1; for(;i>0;i--){ this.body[i].x=this.body[i-1].x; this.body[i].y=this.body[i-1].y; } // 根据移动的方向,决定蛇头如何处理 switch(this.direction) { case 'left': this.body[0].x -= 1; break; case 'right': this.body[0].x += 1; break; case 'top': this.body[0].y -= 1; break; case 'bottom': this.body[0].y += 1; break; }
//添加runSnake的私有方法,开启定时器调用蛇的move和render方法,让蛇动起来 //判断蛇是否撞墙 function runSnake(){ var timerId=setInterval(function(){ // 在渲染前,删除之前的蛇 this.Snake.render(this.map); // 判断蛇是否撞墙 var maxX=this.map.offsetWidth/this.Snake.width; var maxY=this.map.offsetHeight/this.Snake.height; var headX=this.Snake.body[0].x; var headY=this.Snake.body[0].y; if(headX<0 || headX>=maxX){ clearInterval(timerId); alert('Game Over'); } if (headY < 0 || headY >= maxY) { clearInterval(timerId); alert('Game Over'); } }.bind(that),150) } //通过键盘控制蛇的移动方向 function bindKey(){ document.addEventListener('keydown',function(e){ switch (e.keyCode) { case 37: // left this.Snake.direction = 'left'; break; case 38: // top this.Snake.direction = 'top'; break; case 39: // right this.Snake.direction = 'right'; break; case 40: // bottom this.Snake.direction = 'bottom'; break; } }.bind(that),false); } window.Game = Game; }())
// 在移动的过程中判断蛇是否吃到食物 // 如果蛇头和食物的位置重合代表吃到食物 // 食物的坐标是像素,蛇的坐标是几个宽度,进行转换 var headX=this.body[0].x*this.width; var headY=this.body[0].y*this.height; if(headX===Food.x && headY===Food.y){ var last=this.body[this.body.length-1]; this.body.push({ x:last.x, y:last.y, color:last.color }) // 把现在的食物对象删除,并重新随机渲染一个食物对象 food.render(map); } } //添加删除蛇的私有方法,在render中调用 function remove(){ // 删除渲染的蛇 var i=elements.length-1; for(;i>=0;i--){ // 删除页面上渲染的蛇 elements[i].parentNode.removeChild(elements[i]); // 删除elements数组中的元素 elements.splice(i,1); } }
避免html中出现js代码
自调用函数的参数
(function (window, undefined) {
var document = window.document;
}(window, undefined))
-
传入window对象
将来代码压缩的时候,可以吧 function (window) 压缩成 function (w)
-
传入undefined
在将来会看到别人写的代码中会把undefined作为函数的参数(当前案例没有使用)因为在有的老版本的浏览器中 undefined可以被重新赋值,防止undefined 被重新赋值
心得:
虽然这是第一个模仿的小游戏,相信以后会有更多属于自己的小程序