目录
  1. 1. 模拟贪吃蛇游戏
    1. 1.1. 食物对象
    2. 1.2. 蛇对象
    3. 1.3. 游戏对象
面向对象实现贪吃蛇

模拟贪吃蛇游戏

食物对象

(function (win) {
var elements = []
// 创建食物对象
/**
* */
function Foods(x, y, width, height, color) {
this.x = x
this.y = y
this.width = width || 20 // 默认20
this.height = height || 20 // 默认20
this.color = color || 'green' // 默认green
}
// 为原型添加初始化方法(在页面显示)
Foods.prototype.init = function (map) {
// 先删除食物
remove()
// 将食物渲染到地图上
var div = document.createElement('div')
map.appendChild(div)
// 设置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'

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);
}
}
// 将Foods暴露给window
win.Foods = Foods

}(window));

食物—-div元素

elements—->存储div的数组(将来删除的食物div时候,先从map中删除div,再从数组中移除div)

1.食物的构造函数—->创建食物对象

2.食物的显示的方法—>通过对象调用方法,显示食物,设置相应的样式

2.1.1 因为食物要被小蛇吃掉,吃掉后应该再次出现食物,原来的食物就删除了

2.1.2 每一次初始化食物的时候先删除原来的食物,然后重新的初始化食物

2.1.3 通过一个私有的函数(外面不能调用的函数)删除地图上的食物,同时最开始的时候食物也相应的保存到一个数组中,再从这个数组中把食物删除

最后的时候,把食物的构造函数给window下的属性,这样做,外部就可以直接使用这个食物的构造函数了

蛇对象

/**
创建小蛇
*/
(function (win) {
var elements = [] // 存放小蛇每个身体部分
// 蛇构造函数
function Snake(width, height, direction) {
this.width = width || 20
this.height = height || 20
// 小蛇的身体
this.body = [{
x: 3,
y: 2,
color: 'red'
}, // 头
{
x: 2,
y: 2,
color: 'orange'
}, // 身体
{
x: 1,
y: 2,
color: 'orange'
} // 身体
]
this.direction = direction || 'right'
}
Snake.prototype.init = function (map) {
// 删除前一个蛇
remove();
// 循环遍历创建div
for (var i = 0; i < this.body.length; i++) {
var obj = this.body[i]
var div = document.createElement('div') // 创建div
map.appendChild(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
// 方向

elements.push(div)
}
}

Snake.prototype.move = function (food, map) {
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
}

// 判断蛇是否有吃到食物---- 判断蛇头坐标与食物坐标是否一致
var headX = this.body[0].x * this.width
var headY = this.body[0].y * this.height

if (headX == food.x && headY == food.y) {
console.log(headX + '吃到了' + food.x);
var snakeLast = this.body[this.body.length - 1]
// 复制蛇尾,重新加入
this.body.push({
x: snakeLast.x,
y: snakeLast.y,
color: snakeLast.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)
}

}
win.Snake = Snake

}(window));

小蛇就是一个对象

* 属性: 每个身体都有宽,高,方向

* 属性:身体分三个部分,每个部分都是一个对象,每个部分都有横纵坐标,背景颜色

小蛇要想显示在地图上,先删除之前的小蛇,然后再初始化小蛇(小蛇要移动)--方法

游戏对象

/**
游戏对象
*/
(function (win) {
var that = null

function Game(map) {
this.food = new Foods()
this.snake = new Snake()
this.map = map;
that = this
}
// 初始化游戏
Game.prototype.init = function () {
// 初始化食物
this.food.init(this.map)
// 初始化蛇
this.snake.init(this.map)
this.run(this.food, this.map)
this.bingKey()
}
// 蛇自动移动
Game.prototype.run = function (food, map) {
var runTime = setInterval(function () {
this.snake.move(this.food, this.map)
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) {
clearInterval(runTime)
alert('Game over')
}
if (headY < 0 || headY >= maxY) {
clearInterval(runTime)
alert('Game over')
}

}.bind(that), 150)
}
// 蛇根据键盘按下方向改变位置
Game.prototype.bingKey = 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)
}
win.Game = Game

}(window))

单独控制游戏的初始化与逻辑

  • 主页面
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.map {
width: 800px;
height: 600px;
background-color: #CCC;
position: relative;
}
</style>

<body>
<!--画出地图,设置样式-->
<div class="map"></div>
<script src="food.js"></script>
<script src="Snake.js"></script>
<script src="Game.js"></script>
</body>

<script>
var map = document.querySelector('.map');
var gm = new Game(map)
gm.init()

// fd.init(map);
</script>

</html>

游戏地图:

宽,高,背景颜色,因为小蛇和食物都是相对于地图显示的,这里小蛇和食物都是地图的子元素,随机位置显示,脱离文档流的,地图也需要脱离文档流—css需要设置:宽,高,背景颜色,脱标

文章作者: Jachie Xie
文章链接: https://xjc5772.github.io/2020-07/07/%E5%AD%A6%E4%B9%A0/%E5%89%8D%E7%AB%AF%E5%AD%A6%E4%B9%A0/JS/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E5%AE%9E%E7%8E%B0%E8%B4%AA%E5%90%83%E8%9B%87/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 XJC&Blog
打赏
  • 微信
  • 支付宝

评论