Title
#map {
width: 800px;
height: 600px;
background: #cccccc;
position: relative;
top: 0px;
left: 0px;
}
<div id="map"></div>
<script src="./line.js"></script>
<script src="./Food.js"></script>
<script src="./Snake.js"></script>
<script src="./Game.js"></script>
<script>
new Game().start();
// var game = new Game();
// game.start();
</script>
/* 闭包实现沙箱模式 */
(function (w) { //(1)食物构造函数 function Food(width, height, left, top, bgc) { this.width = width || 20; this.height = height || 20; this.left = left || 0; this.top = top || 0; this.bgc = bgc || getRandomColor(); };
//(2)每一个食物都可以显示到页面,应该添加到原型中
Food.prototype.render = function (map) {
//this : 指向调用这个方法的每一个食物对象
//1.创建空标签 div
var div = document.createElement('div');
//2.设置样式
div.style.width = this.width + 'px';
div.style.height = this.height + 'px';
div.style.position = 'absolute';
//求随机格子数
var geziX = map.offsetWidth / this.width;
var geziY = map.offsetHeight / this.height;
var x = Math.floor(Math.random() * geziX);
var y = Math.floor(Math.random() * geziY);
div.style.left = this.left || x * this.width + 'px';
div.style.top = this.top || y * this.height + 'px';
div.style.backgroundColor = this.bgc;
//3.添加到页面
map.appendChild(div);
this.ele = div;//把dom元素存到对象的属性中(用于移除)
};
function getRandomColor() {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
};
//暴露接口
w.Food = Food;
})(window);
game.js: (function (w) { //1.构造函数 : 游戏对象: 地图 蛇 食物 function Game() { this.food = new Food(); this.snake = new Snake(); this.map = document.getElementById('map');
this.food.render(this.map);
this.snake.render(this.map);
}
//2. start:开始游戏 监听键盘按键
Game.prototype.start = function () {
//一级链 : this : game对象
window.onkeydown = function (e) {
//二级链 this : window
console.log(e.keyCode);
switch (e.keyCode) {// 细节: 蛇不能倒着移动
case 37:
//左
console.log('左');
if (this.snake.direction != 'right') {
this.snake.direction = 'left';
};
break;
case 38:
//上
console.log('上');
if (this.snake.direction != 'bottom') {
this.snake.direction = 'top';
};
break;
case 39:
//右
console.log('右');
if (this.snake.direction != 'left') {
this.snake.direction = 'right';
};
break;
case 40:
//下
console.log('下');
if (this.snake.direction != 'top') {
this.snake.direction = 'bottom';
};
break;
default:
return;//如果是其他的按钮,则不做任何处理
break;
};
console.log('蛇移动');
//3.事件处理
//(1)蛇移动
this.snake.move(this.map);
//(2)蛇边界检测(只能在地图移动)
if (this.snake.body[0].x < 0 || this.snake.body[0].x > this.map.offsetWidth / this.snake.width - 1) {
this.end();
};
if (this.snake.body[0].y < 0 || this.snake.body[0].y > this.map.offsetHeight / this.snake.height - 1) {
this.end();
};
//(3)蛇吃食物
//蛇头的位置和食物位置完全重叠
if (this.snake.snakeElements[0].offsetLeft == this.food.ele.offsetLeft && this.snake.snakeElements[0].offsetTop == this.food.ele.offsetTop) {
//alert('迟到东西了');
this.snake.eat(this.food, this.map);
//(4)刷新食物 : 只有迟到东西才刷新
this.map.removeChild(this.food.ele);
this.food = new Food();
this.food.render(this.map);
};
}.bind(this);//将二级链中的this:window,修改成一级链中的this:game
}
//3. end:结束游戏 刷新页面
Game.prototype.end = function () {
alert('Game Over');
window.location.reload();
};
//4.暴露接口
w.Game = Game;
})(window);
snake.js: /* 沙箱模式 */ (function (w) {
//1.蛇对象构造函数
function Snake(width, height, direction) {
this.width = width || 20;
this.height = height || 20;
this.direction = direction || 'right';
this.body = [{
x: 3,
y: 2,
bgc: 'red'
}, {
x: 2,
y: 2,
bgc: getRandomColor()
}, {
x: 1,
y: 2,
bgc: getRandomColor()
}];
};
//2. render: 渲染到页面
Snake.prototype.render = function (map) {
// this : 调用这个方法的每一个蛇对象
this.snakeElements = [];//声明数组存储每一节身体div(用于移除)
for (var i = 0; i < this.body.length; i++) {
var section = this.body[i];
console.log(section);
//1.创建空标签
var div = document.createElement('div');
//2.设置样式
div.style.width = this.width + 'px';
div.style.height = this.height + 'px';
div.style.position = 'absolute';
div.style.left = section.x * this.width + 'px';
div.style.top = section.y * this.height + 'px';
div.style.backgroundColor = section.bgc;
//3.添加到页面
map.appendChild(div);
this.snakeElements.push(div);
};
};
/* 3. move:蛇移动 */
Snake.prototype.move = function (map) {
//this : 调用这个方向得蛇对象
//1.倒着遍历蛇的身体,每一节都是前一节位置
for (var i = this.body.length - 1; i > 0; i--) {// i > 0 蛇头不用遍历的
console.log(this.body[i]);
this.body[i].x = this.body[i - 1].x;
this.body[i].y = this.body[i - 1].y;
};
//2.蛇头位置取决于移动方向
switch (this.direction) {
case 'left':
this.body[0].x--;
break;
case 'top':
this.body[0].y--;
break;
case 'right':
this.body[0].x++;
break;
case 'bottom':
this.body[0].y++;
break;
}
//3.移除旧蛇(脱皮)
this.remove();
//4.显示新蛇
this.render(map);
};
/* 4.remove:蛇移除 */
Snake.prototype.remove = function () {
//this: 调用这个方法蛇对象
for (var i = 0; i < this.snakeElements.length; i++) {
this.snakeElements[i].parentNode.removeChild(this.snakeElements[i]);
};
};
/* 5.eat 蛇吃食物 food: 吃到的食物 map:要显示的父元素
*/
Snake.prototype.eat = function (food, map) {
//this : 调用这个方法的蛇对象
//1. 记录当前蛇尾巴的位置 :将食物添加到蛇的尾巴位置
var lastX = this.body[this.body.length - 1].x;
var lastY = this.body[this.body.length - 1].y;
this.body.push({
x: lastX,
y: lastY,
bgc: food.bgc
});
//2. 移除旧蛇
this.remove();
//3. 显示新蛇
this.render(map);
};
function getRandomColor() {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
return 'rgb(' + r + ',' + g + ',' + b + ')';
};
//暴露接口
w.Snake = Snake;
})(window)