<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.map {
width: 800px;
height: 600px;
background-color: #cccccc;
position: relative; /*让子元素相对于父元素进行定位*/
}
</style>
</head>
<body>
<div class="map"></div>
</body>
<script>
//自调用函数----->食物的
(function () {
var elements = [];//用来存放食物的数组
//食物的构造函数
function Food(width, height, x, y, color) {
this.width = width || 20;//默认宽度设置20
this.height = height || 20;
this.color = color || "green";
//横纵坐标
this.x = x || 0;
this.y = y || 0;
}
//食物的初始化,显示在地图上
Food.prototype.init = function (map) {
remove();//先删除地图上的小方块,在添加,只能出现一个小方块
//创建小方块元素
var div = document.createElement("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";
//追加到地图当中
map.appendChild(div);
//追加到数组中
elements.push(div);
}
//因为希望地图上只出现一个小方块,所以需要删除地图上的元素,同时删除数组中元素
function remove() {
for (var i = 0; i < elements.length; i++) {
//删除地图上的小方块元素
var ele = elements[i];
//找到他爹,然后他爹把他干掉了
ele.parentNode.removeChild(ele);
//删除数组中的小方块
elements.splice(i, 1);
}
}
//把构造函数暴露给window,外部可以访问到
window.Food = Food;
}());
//自调用函数——>小蛇的
(function () {
var elements = [];//用来保存蛇的各个部分
//小蛇的构造函数
function Snake(width, height, direction) {
this.width = width || 20;//设置宽度默认20
this.height = height || 20;
this.direction = direction || "right";
//设置小蛇的蛇头、蛇中、蛇尾部分的横纵坐标颜色
this.body = [
{x: 3, y: 2, color: "red"},
{x: 2, y: 2, color: "orange"},
{x: 1, y: 2, color: "orange"}
]
}
//小蛇的初始化,因为要显示在地图上,所以传一个map地图参数
Snake.prototype.init = function (map) {
remove();//移除已存在的部分
//因为蛇的部分有三份,遍历每一份的身体
for (var i = 0; i < this.body.length; i++) {
var div = document.createElement("div");//创建元素
//设置蛇各个部分的样式
div.style.width = this.width + "px";
div.style.height = this.height + "px";
div.style.backgroundColor = this.body[i].color;//背景颜色
//脱离文档流
div.style.position = "absolute";
//设置各个部分的横坐标、纵坐标
div.style.left = this.body[i].x * this.width + "px";
div.style.top = this.body[i].y * this.height + "px";
//追加到div当中
map.appendChild(div);
//追加到数组当中
elements.push(div);
}
}
//小蛇的移动
Snake.prototype.move = function (food, map) {
//先让蛇尾和蛇中部分移动
var i = this.body.length - 1;//2
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;
}
//获取蛇头和横纵坐标和食物的横纵坐标
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];
ele.parentNode.removeChild(ele);
//移除数组上该元素
elements.splice(i, 1);
}
}
//将小蛇的私有函数暴露给window
window.Snake = Snake;
}());
//子调用函数——>游戏的
(function () {
var that = null;
//游戏对象的构造函数
function Game(map) {
this.food = new Food();//食物的
this.snake = new Snake();//小蛇的
this.map = map;//地图的
that = this;//实例对象保存在window中
}
//游戏的初始化
Game.prototype.init = function () {
this.food.init(this.map);//食物的初始化
this.snake.init(this.map);//小蛇的初始化
this.snake.move(this.food,this.map);//小蛇的初始化
this.runSnake();//让小蛇跑起来
this.bindKey();//用户按键移动小蛇
};
//小蛇的移动,让小蛇动起来
Game.prototype.runSnake = function () {
var timeId = setInterval(function () {
//注意:定时器里的this是window
this.snake.move(this.food,this.map);//小蛇移动起来
this.snake.init(this.map);//小蛇的初始化
//获取蛇头的最大横纵坐标
var headX = this.map.offsetWidth / this.snake.width;
var headY = this.map.offsetHeight / this.snake.height;
//判断蛇头横坐标是否撞墙
if (this.snake.body[0].x < 0 || this.snake.body[0].x >= headX) {
alert("撞墙了,游戏结束");
clearInterval(timeId);//清理定时器
}
//判断蛇头的纵坐标是否撞墙
if (this.snake.body[0].y < 0 || this.snake.body[0].y >= headY) {
alert("撞墙了,游戏结束");
clearInterval(timeId);//清理定时器
}
}.bind(that), 200);
}
//原型对象添加方法:绑定按键改变蛇的方向
Game.prototype.bindKey = function () {
//为文档注册键盘按下事件事件
document.addEventListener("keydown", function (e) {
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();
</script>
</html>
11-02