<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
.map {
width: 800px;
height: 600px;
background-color: #ccc;
position: relative;
}
</style>
</head>
<body>
<div class="map"></div>
</body>
<script>
//产生随机数
(function () {
function Random() {}
Random.prototype.getRandom = function (min, max) {
return Math.floor(Math.random() * (max - min + min));
};
//将random暴露到全局对象
window.random = new Random();
})();
//随机生成食物
(function () {
//获取地图
let elements = [];
const map = document.querySelector(".map");
//创建食物的构造函数
function Food(width = 20, height = 20, color = "green") {
this.width = width;
this.height = height;
this.color = color;
(this.x = 0),
(this.y = 0),
(this.element = document.createElement("div"));
}
//初始化食物方法
Food.prototype.init = function (map) {
//创建前先删除之前的食物
if (elements.length === 1) {
remove();
}
//设置食物的样式
const div = this.element; //这里赋值的是div对象的地址
div.style.position = "absolute";
div.style.width = this.width + "px";
div.style.height = this.height + "px";
div.style.backgroundColor = this.color;
map.appendChild(div);
this.render(map); //调用随机位置方法
};
//食物随机位置方法
Food.prototype.render = function (map) {
//随机产生横纵坐标
const x =
random.getRandom(0, map.offsetWidth / this.width) * this.width;
const y =
random.getRandom(0, map.offsetHeight / this.height) * this.height;
this.x = x;
this.y = y;
const div = this.element; //这里赋值的也是div对象的地址
div.style.left = this.x + "px";
div.style.top = this.y + "px";
//将食物加到数组elements中
elements.push(div);
};
//删除食物
function remove() {
for (i in elements) {
let ele = elements[i];
ele.parentNode.removeChild(ele);
elements.slice(i, 1);
}
}
window.Food = Food; //把食物的构造函数暴露到全局对象
})();
//小蛇的构造函数
(function () {
let elements = []; //用于存放小蛇的每个身体部分
function Snake(width = 20, height = 20, deration = "right") {
//小蛇每部分的宽高
this.width = width;
this.height = height;
this.deration = deration; //方向
this.body = [
{ x: 3, y: 2, color: "red" }, //头
{ x: 2, y: 2, color: "orange" }, //身体
{ x: 1, y: 2, color: "orange" } //身体
];
}
//添加初始化方法
Snake.prototype.init = function (map) {
//创建之前先删除之前的蛇
remove();
for (i in this.body) {
let obj = this.body[i]; //获取身体
let div = document.createElement("div"); //创建对象
map.appendChild(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";
elements.push(div); //保存蛇的身体
}
};
Snake.prototype.move = function (food, map) {
//先身体的移动
let 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.deration) {
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;
}
//判断小蛇吃到食物---头和食物的坐标重叠
let headX = this.body[0].x * this.width;
let headY = this.body[0].y * this.height;
if (headX == food.x && headY == food.y) {
let last = this.body[this.body.length - 1]; //获取到小蛇的最后一节
this.body.push({
x: last.x,
y: last.y,
color: last.color
}); //将最后一节复制一份,加长蛇身
food.init(map); //删除并重新随机生成食物
}
};
//删除小蛇的方法
function remove() {
let i = elements.length - 1;
for (; i >= 0; i--) {
const ele = elements[i];
ele.parentNode.removeChild(ele);
elements.splice(i, 1);
}
}
window.Snake = Snake; //把小蛇暴露到全局对象
})();
//游戏的构造函数
(function () {
function Game() {
this.food = new Food();
this.snake = new Snake();
this.map = document.querySelector(".map");
}
//游戏的初始化
Game.prototype.init = function () {
this.food.init(this.map);
this.snake.init(this.map);
this.runSnake(this.food, this.snake, this.map);
this.bindKey();
};
//小蛇开始动
Game.prototype.runSnake = function (food, snake, map) {
//获取最大横纵坐标
const maxX = map.offsetWidth / snake.width;
const maxY = map.offsetHeight / snake.height;
let timeId = setInterval(() => {
//这里使用箭头函数解决this指向问题
snake.init(map); //初始化蛇到地图上
snake.move(food, map);
//持续获取蛇头的坐标
let headX = snake.body[0].x;
let headY = snake.body[0].y;
if (headX < 0 || headX > maxX) {
clearInterval(timeId);
alert("游戏结束");
} else if (headY < 0 || headY > maxY) {
clearInterval(timeId);
alert("游戏结束");
}
}, 100);
};
//小蛇操控方向方法
Game.prototype.bindKey = function () {
//添加监听键盘事件方法
document.addEventListener(
"keydown",
e => {
switch (
e.keyCode //判断用户按了上下左右哪个键
) {
case 37:
this.snake.deration = "left";
break;
case 38:
this.snake.deration = "top";
break;
case 39:
this.snake.deration = "right";
break;
case 40:
this.snake.deration = "bottom";
break;
}
},
false
);
};
//暴露游戏对象到全局
window.Game = Game;
})();
const game = new Game();
game.init();
</script>
</html>
原生JS使用面向对象思想实现贪吃蛇
最新推荐文章于 2021-05-31 22:04:19 发布