贪吃蛇小案例
知识点:面向对象的分析,原型的使用,this指针的使用,自调用函数的使用
-
对象的分析
游戏对象
食物对象
小蛇对象 -
分析对象创建对应的对象构造函数
-
食物对象
利用原型创建食物初始化函数(每次初始化之前先要删除之前的食物利用子元素查找父级元素的方法删除),然后利用随机数确定食物的位置 -
小蛇对象
(全部通过坐标变化实现)
初始化,利用一个数组存储小蛇的属性是关键
小蛇的移动(游戏对象是如何控制小蛇移动的)
小蛇与墙壁的检测
小蛇与食物的检测
小蛇长度的添加
对于利用到window对象是需要注意this指针的指向问题也是一个关键,利用好bind()函数
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
.map{
width:800px;
height:600px;
background-color: darkgray;
position: relative;
}
</style>
</head>
<body>
<!--地图的创建-->
<div class="map">
</div>
<script>
//自调用函数---食物的创建
((function(){
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";
}
//为原型添加初始化的方法(作用:在页面上显示这个食物)
//因为食物要在地图上显示,需要地图的这个参数()
Food.prototype.init=function(map)
{
//先删除食物
//外部无法访问的函数
remove();
//创建div
var div=document.createElement("div");
//把div加到map中
map.appendChild(div);
//设置div的样式
div.style.width=this.width+"px";
div.style.height=this.height+"px";
div.style.backgroundColor=this.color;
//先脱离文档流
div.style.position="absolute";
//随机横纵坐标
this.x=parseInt(Math.random()*(map.offsetWidth/this.width))*this.width;
this.y=parseInt(Math.random()*(map.offsetHeight/this.height))*this.height;
div.style.left=this.x+"px";
div.style.top=this.y+"px";
//把div加入到数组elements中
elements.push(div);
};
//私有的函数--删除食物的
function remove(){
//elements数组中有这个食物
for (var i=0;i<elements.length;i++) {
var ele=elements[i];
//找到这个子元素的父级元素,然后删除这个子元素
ele.parentNode.removeChild(ele);
//再次把elements中的这个子元素也要删除
elements.splice(i,1);
}
}
//把Food暴露给window,外部可以使用
window.Food=Food;
})());
//自调用小蛇
(function(){
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:"orange"},//身体
{x:1,y:2,color:"orange"}//身体
];
//方向
this.direction=direction||"right";
}
//蛇的初始化
Snake.prototype.init=function(map){
//先删除之前的小蛇
remove();
//循环遍历创建div
for (var i=0;i<this.body.length;i++)
{
//数组中的每个元素创建对象
var obj=this.body[i];
//创建div
var div=document.createElement("div");
//加入到map中
map.appendChild(div);
//设置div的样式
div.style.position="absolute";
div.style.width=this.width+"px";
div.style.height=this.height+"px";
//颜色。和位置
div.style.backgroundColor=obj.color;
div.style.left=obj.x*this.width+"px";
div.style.top=obj.y*this.height+"px";
//方向暂时不定
//把div加入到elelments数组中---目的是为了删除
elements.push(div);
}
};
//小蛇move方法
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 "right":
this.body[0].x+=1;
break;
case "left":
this.body[0].x-=1;
break;
case "top":
this.body[0].y-=1;
break;
case "bottom":
this.body[0].y+=1;
break;
}
//判断有没有吃到食物
//蛇头的坐标和食物的坐标一致
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.init(map);
}
};
//删除小蛇的私有函数
function remove(){
//获取数组
var i=elements.length-1;
for (;i>=0;i--)
{
//先从当前的子元素中找到该子元素的父级元素,然后再删除子元素
var ele=elements[i];
//从map地图上删除这个子元素div
ele.parentNode.removeChild(ele);
//数组删除
elements.splice(i,1);
}
}
//暴露对象
window.Snake=Snake;
}());
//自调用函数--游戏对象
(function(){
var that=null;//为了保存游戏Game的实例对象
//游戏对象的构造函数
function Game(map){
this.food=new Food();//食物对象
this.snake=new Snake();//小蛇对象
this.map=map;
that=this;//保存当前的实例对象到that变量中
}
//初始化游戏--可以设置小蛇和食物显示出来
Game.prototype.init=function(){
//初始化游戏
//食物初始化
this.food.init(this.map);
//小蛇初始化
this.snake.init(this.map);
//小蛇移动
this.runSnake(this.food,this.map);
this.Click();
}
/* //小蛇移动的定时器
setInterval(function(){
that.snake.move(that.food,that.map);
that.snake.init(that.map);
},150);*/
//小蛇自己移动的代码
Game.prototype.runSnake=function(food,map)
{
var timeID=setInterval(function(){
this.snake.move(this.food,this.map);
this.snake.init(this.map);
//移动的最大横坐标
var maxX=map.offsetWidth/this.snake.width;
//console.log(maxX);
//移动的最大纵坐标
var maxY=map.offsetHeight/this.snake.height;
console.log(maxY);
//蛇头的横坐标
var headX=this.snake.body[0].x;
//console.log(headX);
//蛇头的纵坐标
var headY=this.snake.body[0].y;
//判断结束的条件
if(headX>=maxX||headX<0)
{
clearInterval(timeID);
alert("游戏结束");
}
if(headY>=maxY||headY<0)
{
clearInterval(timeID);
alert("游戏结束");
}
}.bind(that),50);
//bind()的作用将this对象指向bind中的对象
}
//创建鼠标点击事件
Game.prototype.Click=function()
{
document.addEventListener("keydown",function(e){
//这里的this应该是触发keydown的事件的对象--doucment
//所以,这里的this就是doument,需要修改为游戏对象
//获取游戏按键的值
switch (e.keyCode){
case 37:this.snake.direction="left";break;
case 38:this.snake.direction="top";break;
case 39:this.snake.direction="right";break;
case 40:this.snake.direction="bottom";break;
}
}.bind(that),false)
}
//暴露对象
window.Game=Game;
}());
//测试的代码块
var game=new Game(document.querySelector(".map"));
game.init();
/*var fd=new Food();
fd.init(document.querySelector(".map"));
//初始化小蛇
var sn=new Snake();
sn.init(document.querySelector(".map"));
sn.move(fd,document.querySelector(".map"));
sn.init(document.querySelector(".map"));*/
</script>
</body>
</html>