** js 面向对象实现简单贪吃蛇效果**
运行效果:
html代码:
<div class="map"></div>
css代码:
<style>
.map {
width: 800px;
height: 600px;
background-color: #ccc;
position: relative;
margin: 0 auto;
}
</style>
js代码:
<script>
// 自定义自调用函数,创建对象
// 自调用函数--食物
var map = document.querySelector(".map");
(function () {
// 创建数组
var elements = [] //用来保存食物
// 食物是一个对象,高度,宽度,颜色
// 创建食物的构造函数
function Food(x, y, width, height, color, borderRadius) {
// 设置坐标
this.x = x || 0;
this.y = y || 0;
// 设置宽高
this.width = width || 20;
this.height = height || 20;
// 设置背景色
this.color = color;
this.borderRadius = borderRadius;
}
// 食物显示在地图上---通过原型方法进行添加
// 因为食物显示在地图上---把地图参数传入
Food.prototype.init = function (map) {
var div = document.createElement("div")
// 创建新的食物之前先删除这个食物
remove()
// 把div添加到map中
map.appendChild(div)
// 设置div样式
div.style.width = this.width + "px";
div.style.height = this.height + "px"
div.style.backgroundColor = this.color || "red";
div.style.borderRadius = this.borderRadius + "px";
// 设置div定位,脱标
div.style.position = "absolute"
// 设置div的纵横坐标
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"
// 把食物放到数组中
elements.push(div)
console.log(elements)
}
// 删除食物
function remove() {
for (var i = 0; i < elements.length; i++) {
var ele = elements[i]
// 找到这个元素和它的父元素,然后删除这个元素--页面中的元素
ele.parentNode.removeChild(ele)
// 删除数组中的元素
elements.splice(i, 1)
}
}
// 把Food暴露给window对象
window.Food = Food
// window.food = new Food(0, 0, 20, 20, "red")
})();
// 创建蛇
(function () {
// 蛇的构造方法
var elements = []; //存放蛇的身体
// 蛇的构造函数
function Snake(width, height, direction) {
// 蛇的宽
this.width = width || 20;
this.height = height || 20;
// 蛇的身体
this.body = [
{ x: 3, y: 2, color: "orange" }, //头
{ x: 2, y: 2, color: "blue" }, //身体
{ x: 1, y: 2, color: "blue" } //身体
];
// 蛇的方向
this.direction = direction || "right";
}
// 蛇的初始化
// 为原型添加init方法--- 小蛇的初始化方法
Snake.prototype.init = function (map) {
// 每次先删除蛇
remove();
// 循环遍历创建div,创建蛇的身体
for (var i = 0; i < this.body.length; i++) {
// 数组中的每个元素都是对象
// 蛇的每一部分都是div
var obj = this.body[i]
// 创建div
var div = document.createElement("div");
// 把div添加到map中
map.appendChild(div);
// 设置div样式
div.style.position = "absolute";
div.style.width = this.width + "px";
div.style.height = this.height + "px";
// 纵横坐标
div.style.left = obj.x * this.width + "px"
div.style.top = obj.y * this.height + "px"
// 背景颜色
div.style.backgroundColor = obj.color
// 把div加到数组中
elements.push(div);
// console.log(elements)
}
}
// 蛇的移动--- 为原型添加方法
Snake.prototype.move = function (map, food) {
// 蛇的身体长度
var 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.direction) {
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
}
// 判断蛇有没有吃到食物
// 当蛇头的坐标和食物的坐标一致时,吃到食物
// 身体长度+1
// 蛇头横纵坐标
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() {
//删除map中的小蛇的每个div,同时删除elements数组中的每个元素,从蛇尾向蛇头方向删除div
var i = elements.length - 1;
for (; i >= 0; i--) {
//先从当前的子元素中找到该子元素的父级元素,然后再弄死这个子元素
var ele = elements[i];
//从map地图上删除这个子元素div
ele.parentNode.removeChild(ele);
elements.splice(i, 1); // 从当前遍历到的元素删除,长度为1
}
}
// 把Snake暴露给window对象
window.Snake = Snake;
})();
// 自调用函数---游戏对象
(function () {
var that = null; // 保存Game的实例对象
// 游戏的构造函数
function Game(map) {
// 创建食物对象
this.food = new Food()//食物对象
this.snake = new Snake()//蛇对象
this.map = map
that = this
}
Game.prototype.init = function () {
// 食物初始化
this.food.init(this.map)
// 蛇初始化
this.snake.init(this.map)
/* // var that = this;
// 创建定时器,开启蛇动
setInterval(function () {
that.snake.move(that.map, that.food)
that.snake.init(that.map)
}, 1000)
// 调用按键的方法,修改蛇的移动方向
// bindKey(); */
this.runSnake();
// 调用按键方法,修改蛇的移动方向
this.bindKey();
}
//原型中添加方法,让蛇自己动
Game.prototype.runSnake = function () {
// 创建定时器
var timeId = setInterval(function () {
this.snake.move(this.map, this.food)
this.snake.init(this.map)
// 判断蛇不能超出地图范围
var maxX = map.offsetWidth / this.snake.width;
var maxY = map.offsetHeight / this.snake.height;
// 蛇头的坐标
var headX = this.snake.body[0].x;
var headY = this.snake.body[0].y;
// 判断横纵坐标是否超出范围
if (headX < 0 || headX >= maxX || headY < 0 || headY >= maxY) {
// 蛇超出了地图范围
clearInterval(timeId);
alert("Game Over")
}
}.bind(that), 150)
}
// 为原型添加方法 ---按键设置,控制蛇的移动方向
Game.prototype.bindKey = function () {
// 获取用户按键,改变蛇运动方向
document.addEventListener("keydown", function (e) {
// this指向
// console.log("this")
// 获取按键值
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 gm = new Game(map)
gm.init();
gm.bindKey()
// 测试代码
// 初始化食物
// var fd = new Food(0, 0, 20, 20, "red", 50)
// fd.init(map)
</script>