项目分析:
地图:
食物:
属性:width\height\backgroundColor\left\top
方法:
1、初始化:创建到地图上
2、食物随机移动:方便蛇吃食物的时候使用
蛇:
属性:width\height\backgroundColor\left\top
蛇是多节组成:因此还有一个数组属性存每节蛇的属性
方法:
1、蛇的初始化类似食物
2、蛇的移动(复杂)
game:
属性:蛇对象和食物对象
方式:是游戏开始和游戏的逻辑(1、蛇身增长、2、食物移动、3、游戏结束)
注意:
1、为了防止变量名冲突使用自调用函数(function(){})()这样外面就访问不到,但是外面访问不到又有问题对象不能在外面访问:把对象挂在在window上
2、在对象中调用对象的时候this不是指当前对象而是window–解决:用变量把this存起来即可使用
源代码
- html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>贪吃蛇</title>
<link rel="stylesheet" type="text/css" href="css/map.css"/>
</head>
<body>
<div id="map">
</div>
</body>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="js/tools.js"></script>
<script type="text/javascript" src="js/food.js"></script>
<script type="text/javascript" src="js/snake.js"></script>
<script type="text/javascript" src="js/game.js"></script>
<script type="text/javascript">
</script>
</html>
- 随机数工具js tools.js
var Tools={
getRandom:function(min,max){
return Math.floor(Math.random()*(max-min)+min);
}
}
- 建立食物对象food.js
//做项目的时候先思考需要上面对象每个对象需要上面属性方法
//它可以随意的更改位置
(function(){
//定位:
var direction='absolute';
function Food(options){
//options(宽,高,背景,位置)可以传参也可以不传参所以在写属性的时候考考虑添加默认值
var options=options||{};
this.width=options.x||20;
this.height=options.y||20;
this.backgroundColor=options.backgroundColor||'green';
this.x=Tools.getRandom(0,map.width()/this.width);
this.y=Tools.getRandom(0,map.height()/this.height);
}
Food.prototype.init=function(map)
{
//jquery创建标签
var div=$('<div>');
div.attr('id','food');//不可以用css
div.css({
width:this.width+'px',
height:this.height+'px',
background:this.backgroundColor,
position:direction,
left:this.x*this.width+'px',
top:this.y*this.height+'px'
});
map.append(div);
}
//当蛇碰到食物的时候,食物位置发生改变
//第二种是删除当前食物重新创建(太麻烦)
Food.prototype.move=function(){
var food=map.children("#food")[0];
//food不是jquery对象
this.x=Tools.getRandom(0,map.width()/this.width);
this.y=Tools.getRandom(0,map.height()/this.height);
console.log($(food));
$(food).css({
left:this.x*this.width+'px',
top:this.y*this.height+'px'
})
}
//封闭函数如何暴露自己的资源
window.Food=Food;
})()
//测试代码
//var map=$('#map');
//var Food=new Food();
//Food.init(map);
//setInterval(function(){
// Food.move();
//},500);
- 蛇对象 snake.js
(function(){
var absolute='absolute';
function Snake(options)
{
var options=options||{};
this.width=options.width||20;
this.height=options.y||20;
this.creatStatus=1;
// 蛇的方向
this.direction=options.direction||'right';
this.body=[{x:3,y:2,color:'red',div:null}
,{x:2,y:2,color:'green',div:null},
{x:1,y:2,color:'green',div:null}]
}
Snake.prototype.init=function(map){
for(let i=0,len=this.body.length;i<len;i++)
{
console.log(this.body[i].color);
if(this.body[i].div==null)
{
console.log(i);
var div=$('<div>');
div.attr('class','snake');
div.css({
width:this.width+'px',
height:this.height+'px',
backgroundColor:this.body[i].color,
position:absolute,
left:this.body[i].x*this.width+'px',
top:this.body[i].y*this.height+'px'
})
this.body[i].div=div;
// console.dir(this.body[i].div);
map.append(div);
}
this.body[i].div.css({
left:this.body[i].x*this.width+'px',
top:this.body[i].y*this.height+'px'
})
if(this.body[i].color==undefined)
{
this.body[i].div.css({
background:'pink'
})
}
}
}
Snake.prototype.move=function(e=0){
// 思考如何让蛇移动
//1、利用x y让舌头进行移动,蛇身后面跟着前面的移动即可----在用方向属性判断蛇移动的方向
//再利用键盘事件对方向进行判断
if(e!=0)
{
switch(e){
case 37:this.direction='left';break;
case 38:this.direction='up';break;
case 39:this.direction='right';break;
case 40:this.direction='down';break;
}
// alert(this.direction);
}
for(let i=this.body.length-1;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 'up':this.body[0].y-=1;break;
case 'down':this.body[0].y+=1;break;
case 'left':this.body[0].x-=1;break;
case 'right':this.body[0].x+=1;break;
}
// Snake.init(map);
// setInterval(function(){
// game.snake.move();
// },500);
}
// 暴露自调用的函数
window.Snake=Snake;
})()
测试代码
//var map=$('#map');
//var snake=new Snake();
//snake.init(map);
//setInterval(function(){
//
// snake.move();
// snake.init(map);
//},1000);
- 游戏逻辑game.js
//使用自调用函数,创建一个新的局部的作用域,防止命名冲突
(function(){
var that;
function Game(map){
this.food=new Food();
this.snake=new Snake();
this.map=map;
that=this;
}
Game.prototype.start=function(){
//1、把蛇和食物对象那个渲染到地图上
this.food.init(this.map);
this.snake.init(this.map);
}
//蛇移动 蛇死亡
Game.prototype.move1=function(){
$('body').keydown(function(e){
setTimeout(function(){
that.snake.move(e.keyCode);
that.snake.init(that.map);
},500);
});
var time=setInterval(function(){
that.snake.move();
that.snake.init(that.map);
//获取蛇头的位置判断
// console.log(that.map.width()/that.snake.width);
// console.log(that.snake.width);
//2、判断蛇的死亡情况
if(that.snake.body[0].x<0||that.snake.body[0].x>=(that.map.width()/that.snake.width)||that.snake.body[0].y<0||that.snake.body[0].y>=(that.map.height()/that.snake.height))
{
alert('Game over');
clearInterval(time);
}
//3、判断蛇吃的情况(吃掉食物更改位置,舍身加1)
if(that.snake.body[0].x==that.food.x&&that.snake.body[0].y==that.food.y)
{
that.food.move();
// alert(that.snake.body.length);{x:2,y:2,color:'green',div:null}
that.snake.body.push([{x:that.snake.body[that.snake.body.length-1].x,
y:that.snake.body[that.snake.body.length-1].y,
div:null,
color:'pink'
}
]);
that.snake.init(that.map);
console.log(that.snake.body[that.snake.body.length-1].color);//underfineed
}
},300);
}
window.Game=Game;
})();
//测试
var map=$('#map');
var game=new Game(map);
game.start();
game.move1();
//$('body').keydown(function(e){
alert();
// setTimeout(function(){
// game.snake.move(e.keyCode);
// game.snake.init(this.map);
// },500);
//});
// setInterval(function(){
// game.snake.move();
// game.snake.init(this.map);
// },500);