我用端午假期写了个贪吃蛇,学弟玩的不亦乐乎!附(思路注释+源码)
Posted 贪吃ღ大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我用端午假期写了个贪吃蛇,学弟玩的不亦乐乎!附(思路注释+源码)相关的知识,希望对你有一定的参考价值。
学弟玩法:(蚯蚓找妈)
我的玩法:(王母摇头)
模块化开发
为什么要用面向对象写,有三大特性:封装、继承、多态。
为什么要封装 : 实现模块化开发,封装为一个块一个块的,利于维护,有某个模块出现bug只用修改这个模块,其他模块不受影响。在工作中,开发速度快,同时开发模块。
分三个模块写:地图,食物,蛇。
蛇模块分为:定义蛇、蛇移动、蛇死亡、蛇吃食物、蛇移动方向、蛇显示。
地图模块:
创建地图板块,设置样式
function Map() {
// 创建一个div
this.map = document.createElement('div')
this.setStyle(this.map, {
width: "700px",
height: '500px',
border: "10px solid #ccc",
backgroundColor: "#abcdef",
position: "relative"
})
// 将div放到body中
document.body.appendChild(this.map)
}
// 添加一个设置样式的函数
Map.prototype.setStyle = function (ele, styleObj) {
for (var attr in styleObj) {
ele.style[attr] = styleObj[attr]
}
}
// 添加一个获取随机数的方法
Map.prototype.getRandom = function (a, b = 0) {
var max = Math.max(a, b);
var min = Math.min(a, b)
return Math.floor(Math.random() * (max - min)) + min
}
var m = new Map()
食物模块:
- 创建食物div
- 放入到地图中
- 随机产生食物的范围,随机位置函数
function Food() {
// 创建一个小div
this.food = document.createElement('div')
m.setStyle(this.food, {
width: "10px",
height: "10px",
backgroundColor: "blue",
position: "absolute",
left: parseInt(m.getRandom(m.map.clientWidth - 10) / 10) * 10 + 'px',
top: parseInt(m.getRandom(m.map.clientHeight - 10) / 10) * 10 + 'px',
})
// 放到地图中
m.map.appendChild(this.food)
}
var f = new Food()
定义蛇模块:
- 蛇由多个div组成,蛇头样式和蛇身区分设置
- 初始蛇大小由三个div组成,蛇移动以后,创建三个新的div给蛇,删除原有的三个div
- 随着蛇吃食物,组成蛇的div越多,根据原来的身体的位置,多加相应的div
- 每个div都是一个对象组成,由left top坐标组成
- 蛇移动方向默认是向右移动
function Snake() {
// 属性
// 身体
this.body = [
{
x: 0,
y: 0
},
{
x: 10,
y: 0
},
{
x: 20,
y: 0
},
{
x: 30,
y: 0
},
{
x: 40,
y: 0
},
{
x: 50,
y: 0
}
]
this.direction = 'right'
this.timer = null
// 让蛇显示的方法
this.show()
// 改变蛇移动的方向方法
this.changeDirection()
}
// 初始化方法
Snake.prototype.init = function () {
// 移动方法
this.timer = setInterval(() => {
this.move()
}, 100)
}
// 蛇移动的方法
Snake.prototype.move = function () {
// 根据方向移动
// 先移动除了蛇头的其他身体
for (var i = 0; i < this.body.length - 1; i++) { // 少循环一次,把蛇头排除了
// 注意:这里是复杂数据类型赋值,赋的是地址
// this.body[i] = this.body[i+1]
this.body[i].x = this.body[i + 1].x
this.body[i].y = this.body[i + 1].y
}
蛇移动模块:
- 移动时,当前蛇div坐标就是上一个蛇div的坐标
- 先移动其他身体,最后再移动蛇头,身体不能跑到蛇头的位置
- 改变蛇头方向
Snake.prototype.move = function () {
// 根据方向移动
// 先移动除了蛇头的其他身体
for (var i = 0; i < this.body.length - 1; i++) { // 少循环一次,把蛇头排除了
// 注意:这里是复杂数据类型赋值,赋的是地址
// this.body[i] = this.body[i+1]
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[this.body.length - 1].x += 10
break;
case 'left':
this.body[this.body.length - 1].x -= 10;
break;
case 'up':
this.body[this.body.length - 1].y -= 10
break;
case 'down':
this.body[this.body.length - 1].y += 10
break;
}
this.show()
// 检测是否迟到食物
this.eat()
// 检测是否死亡
this.die()
}
蛇死亡模块:
- 蛇撞墙死、和蛇撞自己身体死
- 蛇的left 和top 大于地图的右边界和下边界,判断撞墙
- 身体div的x和蛇头div的x相等 或 身体div的y和蛇头div的y相等,蛇撞自己
Snake.prototype.die = function () {
// 撞墙
if (this.body[this.body.length - 1].x < 0 || this.body[this.body.length - 1].y < 0 || this.body[this.body.length - 1].x > m.map.clientWidth - 10 || this.body[this.body.length - 1].y > m.map.clientHeight - 10) {
clearInterval(this.timer)
alert('GAME OVER')
}
// 撞自己身体
for (var i = 0; i < this.body.length - 1; i++) {
if (this.body[i].x === this.body[this.body.length - 1].x && this.body[i].y === this.body[this.body.length - 1].y) {
clearInterval(this.timer)
alert('GAME OVER')
break;
}
}
}
// 蛇吃食物的方法
Snake.prototype.eat = function () {
// 蛇头和食物的坐标重合就是吃到了
if (this.body[this.body.length - 1].x === f.food.offsetLeft && this.body[this.body.length - 1].y === f.food.offsetTop) {
// 从开头添加一节身体
this.body.unshift({
x: this.body[0].x,
y: this.body[0].y
})
// 让食物删除并重新创建食物
m.map.removeChild(f.food)
// 重新创建食物
f = new Food()
}
}
蛇吃食物模块:
- 蛇头如果和食物重叠,就吃到食物了,
- 注意设置蛇移动大小的像素和食物生成位置的坐标,需要让蛇和食物能重叠
- 蛇吃到食物后,删除食物div,再生成随机坐标的新食物
Snake.prototype.eat = function () {
// 蛇头和食物的坐标重合就是吃到了
if (this.body[this.body.length - 1].x === f.food.offsetLeft && this.body[this.body.length - 1].y === f.food.offsetTop) {
// 从开头添加一节身体
this.body.unshift({
x: this.body[0].x,
y: this.body[0].y
})
// 让食物删除并重新创建食物
m.map.removeChild(f.food)
// 重新创建食物
f = new Food()
}
}
https://blog.csdn.net/weixin_44070254/article/details/117846779
改变蛇移动方向模块:
- 设置蛇移动方向对应的键盘按键码
Snake.prototype.changeDirection = function () {
document.onkeydown = e => {
var e = e || window.event;
var keycode = e.keyCode || e.which;
// console.log(keycode);
var keyword = String.fromCharCode(keycode).toLowerCase()
switch (keyword) {
case 'a':
this.direction = 'left'
break;
case 'd':
this.direction = 'right';
break;
case 'w':
this.direction = 'up';
break;
case 's':
this.direction = 'down';
break;
}
}
}
蛇显示模块:
- 每一节身体div设置大小10个像素,应该和食物一样大
- 设置蛇的样式 蛇头蛇身颜色和坐标
- 蛇放入地图中
- 先删除原来的身体,再显示新的身体
Snake.prototype.show = function () {
// 先删除原来的身体再显示新的身体
var snakes = document.querySelectorAll('.snake')
if (snakes.length) {
for (var i = 0; i < snakes.length; i++) {
m.map.removeChild(snakes[i])
}
}
// 根据身体数组创建div,设置坐标
for (var i = 0; i < this.body.length; i++) {
var div = document.createElement('div')
div.className = 'snake'
m.setStyle(div, {
width: "10px",
height: "10px",
backgroundColor: "#000",
position: "absolute",
left: this.body[i].x + "px",
top: this.body[i].y + "px"
})
// 放到地图中
m.map.appendChild(div)
if (i === this.body.length - 1) {
m.setStyle(div, {
backgroundColor: "red",
borderRadius: "50%"
})
}
}
}
源码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>document</title>
</head>
<body>
<button>开始</button>
</body>
<script>
// 地图
function Map() {
// 创建一个div
this.map = document.createElement('div')
this.setStyle(this.map, {
width: "700px",
height: '500px',
border: "10px solid #ccc",
backgroundColor: "#abcdef",
position: "relative"
})
// 将div放到body中
document.body.appendChild(this.map)
}
// 添加一个设置样式的函数
Map.prototype.setStyle = function (ele, styleObj) {
for (var attr in styleObj) {
ele.style[attr] = styleObj[attr]
}
}
// 添加一个获取随机数的方法
Map.prototype.getRandom = function (a, b = 0) {
var max = Math.max(a, b);
var min = Math.min(a, b)
return Math.floor(Math.random() * (max - min)) + min
}
var m = new Map()
// 食物
function Food() {
// 创建一个小div
this.food = document.createElement('div')
m.setStyle(this.food, {
width: "10px",
height: "10px",
backgroundColor: "blue",
position: "absolute",
left: parseInt(m.getRandom(m.map.clientWidth - 10) / 10) * 10 + 'px',
top: parseInt(m.getRandom(m.map.clientHeight - 10) / 10) * 10 + 'px',
})
// 放到地图中
m.map.appendChild(this.food)
}
var f = new Food()
// 蛇
function Snake() {
// 属性
// 身体
this.body = [
{
x: 0,
y: 0
},
{
x: 10,
y: 0
},
{
x: 20,
y: 0
},
{
x: 30,
y: 0
},
{
x: 40,
y: 0
以上是关于我用端午假期写了个贪吃蛇,学弟玩的不亦乐乎!附(思路注释+源码)的主要内容,如果未能解决你的问题,请参考以下文章
表弟打把王者的时间,我就用python写了个自动玩贪吃蛇的程序