手写简易版贪吃蛇

手写一个简易版贪吃蛇,只是简易版,有bug很正常。

逻辑梳理:

1、画格子。固定xy(两个数组)长度,采用数组坐标[ [ { food:false,snake:false}, { }, { } ],[  ], ] 得到一个装有对象的二维数组。

2、点击开始游戏,使用随机数生成食物与小蛇。随机数最大值为当前xy的值。生成小蛇与食物即将对应坐标对象的food和snake属性改为true,且将当前坐标对象{   x:" ", y:" "}  存入单独的小蛇数组。

3、监听键盘按键。↑→↓(键盘按钮code,左:37,上:38,右:39,下:40)。按下之后,将数组当前坐标的snake改为true。 小蛇数组第一个坐标对象永远为蛇头,且从小蛇数组

(3.1).如果蛇头撞到食物,重新生成食物

(3.2).否则蛇头未撞到食物,删除数组最后一个对象,且把对应坐标的小蛇点亮。

(3.3).撞到墙重新开始游戏

逻辑导图

4、代码

<template>
	<div class="height100">
		<div class="flex jc_c">
			<div>
				请输入行数: <input v-model="rows" placeholder="请输入每行个数" type="number" :max="30"
					style="width: 200px;"></input>
				请输入列数: <input v-model="columns" placeholder="请输入列数" type="number" :max="30"
					style="width: 200px;"></input>
			</div>
			<div>
				<button @click="start">开始</button>
			</div>
		</div>
		<div class="big_div">
			<div class="div_row" v-for="(row,rowIndex) in tableArr">
				<div class="row_content" v-for="(data,$index) in row">
					<div v-show="data.food" class="food_">食</div>
					<div v-if="snakeArr.length>0" class="snke_" v-show="data.snake"
						:class="{'snke_head':$index==snakeArr[0].x && rowIndex==snakeArr[0].y}">蛇</div>
				</div>
			</div>
		</div>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				rows: 20,
				columns: 20,
				tableArr: [],
				now: undefined, // 当前操作
				snakeArr: [],
				foodObj: {
					x: "",
					y: "",
				},
				interval: undefined
			}
		},
		watch: {
			columns() {
				this.initTable();
			},
			rows() {
				this.initTable();
			},
		},
		mounted() {
			this.initTable();
		},
		created() {
			//当前页面监视键盘输入
			document.onkeydown = e => {
				//键盘按键判断:左箭头-37;上箭头-38;右箭头-39;下箭头-40
				if (e && e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40) {
					clearInterval(this.interval);
					this.now = e.keyCode;
					this.snakeMove();
					this.interval = setInterval(this.snakeMove, 500)
				} else {
					return;
				}
			}
		},
		methods: {

			// 初始化生成表格
			initTable() {
				this.tableArr = [];
				for (let a = 0; a < this.rows; a++) {
					let rowArr = [];
					for (let i = 0; i < this.columns; i++) {
						let rowObj = {
							snake: false,
							food: false
						};
						rowArr.push(rowObj);
					}
					this.tableArr.push(rowArr);
				}
			},

			start() {
				this.initTable();
				this.food();
				this.snake();
			},
			// 生成食物
			food() {
				let XR = Math.round(Math.random() * this.rows);
				let YR = Math.round(Math.random() * this.columns);
				this.tableArr[YR][XR].food = true;
				this.foodObj = {
					x: XR,
					y: YR
				}
			},
			// 生成短小的蛇
			snake() {
				let XR = Math.round(Math.random() * (this.rows - 2) + 1);
				let YR = Math.round(Math.random() * (this.columns - 2) + 1);
				let newArr = [];
				this.tableArr[YR][XR].snake = true;
				newArr.push({
					x: XR,
					y: YR,
				})
				this.snakeArr = newArr;
			},
			// 小蛇蛇动起来
			snakeMove() {
				let [...newSnakeArr] = this.snakeArr; // 深拷贝避免数据混乱
				let snakeObj = {};

				if (this.now == 37) {
					// 当前是否最边上格子
					if (newSnakeArr[0].x == 0) {
						alert("你gg了");
						clearInterval(this.interval);
						this.start();
						return
					}
					snakeObj = {
						x: newSnakeArr[0].x - 1,
						y: newSnakeArr[0].y
					}
				}
				if (this.now == 38) {
					// 当前是否最边上格子
					if (newSnakeArr[0].y == 0) {
						alert("你gg了");
						clearInterval(this.interval);
						this.start();
						return
					}
					snakeObj = {
						x: newSnakeArr[0].x,
						y: newSnakeArr[0].y - 1
					}
				}
				if (this.now == 39) {

					// 当前是否最边上格子
					if (newSnakeArr[0].x == this.rows - 1) {
						alert("你gg了");
						clearInterval(this.interval);
						this.start();
						return
					}
					snakeObj = {
						x: newSnakeArr[0].x + 1,
						y: newSnakeArr[0].y
					}
				}
				if (this.now == 40) {
					
					// 当前是否最边上格子
					if (newSnakeArr[0].y == this.columns - 1) {
						alert("你gg了");
						clearInterval(this.interval);
						this.start();
						return
					}
					snakeObj = {
						x: newSnakeArr[0].x,
						y: newSnakeArr[0].y + 1
					}
				}
				this.snakeArr.unshift(snakeObj); //在头部添加跑起来的小蛇蛇
				this.tableArr[snakeObj.y][snakeObj.x].snake = true; // 点亮跑起来的小蛇

				// 当当前坐标与食物坐标重合,表示吃到了,重新生成食物
				if (snakeObj.x == this.foodObj.x && snakeObj.y == this.foodObj.y) {
					this.tableArr[snakeObj.y][snakeObj.x].food = false; // 
					this.food();
				} else {
					let deletedSnake = this.snakeArr.pop(); // 删除小蛇蛇最后一个,并返回被删除的对象
					this.tableArr[deletedSnake.y][deletedSnake.x].snake = false; // 取消小蛇蛇最后一个格子
				}

			},

		}
	}
</script>
<style lang="less" scoped>
	.width100 {
		width: 100%;
	}

	.flex {
		display: flex;
	}

	.jc_c {
		justify-content: center;
	}

	.big_div {
		width: 100%;
		height: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		flex-direction: column;

		.div_row {
			font-size: 0;
			overflow: hidden;
			display: flex;

			.row_content {
				display: flex;
				width: 24px;
				height: 24px;
				border: 1px solid rgba(230, 230, 230);
			}

			.snke_ {
				background-color: blue;
				width: 100%;
				color: white;
				display: flex;
				align-items: center;
				justify-content: center;
			}

			.snke_head {
				background-color: red;
				width: 100%;
			}

			.food_ {
				background-color: aquamarine;
				width: 100%;
				color: white;
				display: flex;
				align-items: center;
				justify-content: center;
			}
		}
	}
</style>

5、效果视频

贪吃蛇

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邹田聪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值