index.html
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>贪吃蛇游戏</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div id="map"></div>
<script src="js/index.js"></script>
</body>
</html>
style.css
#map {
width: 800px;
height: 600px;
background-color: lightgray;
position: relative;
}
index.js
//-----------tools.js-----------
;(function(){
var Tools = {
getRandom: function(min,max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
//暴露Tools给window
window.Tools = Tools;
})()
//-----------food.js-----------
;(function(){
var position = 'absolute';
//记录上一次创建的食物,为删除做准备
var elements = [];
function Food(options){
options = options || {};
this.x = options.x || 0;
this.y = options.y || 0;
this.width = options.width || 20;
this.height = options.height || 20;
this.color = options.color || 'green';
}
Food.prototype.render = function(map){
//删除之前创建的食物
remove();
this.x = Tools.getRandom(0,map.offsetWidth/this.width - 1) * this.width;
this.y = Tools.getRandom(0,map.offsetHeight/this.height - 1) * this.height;
//动态创建食物,页面上显示的div
var div = document.createElement("div");
map.appendChild(div);
elements.push(div);
//设置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;
}
function remove(){
for(var i = elements.length - 1;i >= 0;i--){
//删除div
elements[i].parentNode.removeChild(elements[i]);
//删除数组中的元素
elements.splice(i,1);
}
}
window.Food = Food;//让外部可访问
})()
//-----------snake.js-----------
;(function(){
var position = 'absolute';
//记录之前创建的蛇
var elements = [];
function Snake(options){
options = options || {};
//蛇节大小
this.width = options.width || 20;
this.height = options.height || 20;
//蛇移动的方向
this.direction = options.direction || 'right';
//蛇的身体(蛇节)第一个元素是蛇头
this.body = [
{x: 3,y: 2,color: 'red'},
{x: 2,y: 2,color: 'blue'},
{x: 1,y: 2,color: 'blue'},
];
}
Snake.prototype.render = function(map){
//删除之前创建的蛇
remove();
for(var i = 0,len = this.body.length;i < len;i++){
//把每一个蛇节渲染到地图上
var object = this.body[i];
var div = document.createElement('div');
map.appendChild(div);
elements.push(div);
//设置样式
div.style.position = position;
div.style.width = this.width + 'px';
div.style.height = this.height + 'px';
div.style.left = object.x * this.width + 'px';
div.style.top = object.y * this.height + 'px';
div.style.backgroundColor = object.color;
}
}
function remove(){
for(var i = elements.length - 1;i >= 0;i--){
//删除div
elements[i].parentNode.removeChild(elements[i]);
//删除数组中的元素
elements.splice(i,1);
}
}
//控制蛇移动的方法
Snake.prototype.move = function(food,map){
//控制蛇的身体移动
for(var 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;
}
//控制蛇头移动
var head = this.body[0];
switch(this.direction){
case 'right':
head.x += 1;
break;
case 'left':
head.x -= 1;
break;
case 'top':
head.y -= 1;
break;
case 'bottom':
head.y += 1;
break;
}
//当前蛇头的位置是否和食物的坐标重合
var headX = head.x * this.width;
var headY = head.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);
}
}
window.Snake = Snake;
})()
//-----------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(){
//把蛇和食物对象渲染到地球上
this.food.render(this.map);
this.snake.render(this.map);
//游戏逻辑
//让蛇移动起来
runSnake();
//通过键盘控制蛇的移动方向
bindKey();
//蛇遇到食物时,蛇吃掉食物
}
function bindKey(){
document.addEventListener('keydown',function(e){
//console.log(e.keyCode);
//left-37,right-39,top-38,bottom-40
switch(e.keyCode){
case 37:
that.snake.direction = 'left';
breake;
case 38:
that.snake.direction = 'top';
breake;
case 39:
that.snake.direction = 'right';
breake;
case 40:
that.snake.direction = 'bottom';
breake;
}
});
}
function runSnake(){
var timerId = setInterval(function(){
//让蛇走一格,在定时器的function中this是指向window对象
//要获取游戏对象中蛇属性
that.snake.move(that.food,that.map);
that.snake.render(that.map);
//获取蛇头坐标,遇到边界,游戏结束
var maxX = that.map.offsetWidth / that.snake.width;
var maxY = that.map.offsetHeight / that.snake.height;
var headX = that.snake.body[0].x;
var headY = that.snake.body[0].y;
if(headX < 0 || headX >= maxX){
alert('Game Over!!!');
clearInterval(timerId);
}
if(headY < 0 || headY >= maxY){
alert('Game Over!!!');
clearInterval(timerId);
}
},150);
}
window.Game = Game;
})()
//-----------调用.js-----------
;(function(){
var map = document.getElementById('map');
var game = new Game(map);
game.start();
})()
自调用函数会开启一个新的作用域,避免命名冲突;