我正在参加掘金社区游戏创意投稿大赛个人赛,详情请看:游戏创意投稿大赛
前言
贪吃蛇并不难,思路如下:
- 建一个小蛇可以移动的棋盘;
- 游戏开始后,棋盘中任何格子都可以作为小蛇身体的一部分或小方块;
- 使用定时器来连续地让小蛇移动;
- 判断小蛇的头部位置如果与小方块的位置一致,那么小方块被吃掉成为小蛇身体的一部分;
- 小方块被吃掉以后,立马随机生成下一个方块;
- 如果小蛇的头部超出棋盘的边界位置,则提示游戏结束。
实现
HTML代码
<div class="game-title">Qiuの贪吃小蛇</div>
<div class="game-container">
<table id="tableLat">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div class="controller">
<button id="startBtn" class="btnStyle">开始游戏</button>
<button id="endBtn" class="btnStyle">结束游戏</button>
<div id="showInfo"></div>
</div>
</div>
CSS代码
/*标题*/
.game-title {
text-align: center;
line-height: 80px;
font-size: 30px;
color: #03a9f4;
font-weight: bold;
}
/* 游戏整体 */
.game-container {
width: 600px;
height: 450px;
margin: 0 auto;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
background-color: #ffeb3b;
}
table tr td {
width: 40px;
height: 40px;
border: solid gray 1px;
background-color: #fff;
}
/* 按钮 */
.controller {
width: 150px;
height: 370px;
margin-left: 20px;
padding: 10px;
box-sizing: border-box;
background-color: #feffb1;
}
.btnStyle {
width: 100%;
height: 30px;
margin-top: 20px;
text-align: center;
background-color: aquamarine;
}
/* 消息提示框 */
#showInfo {
font-size: 12px;
margin-top: 20px;
padding: 10px;
height: 190px;
overflow: auto;
border: 2px solid black;
background-color: aquamarine;
}
渲染效果如下
JS代码
// 各节点参数
var lattices = document.getElementById('tableLat').children[0];//格子合集
var startBtn = document.getElementById('startBtn');//开始游戏按钮
var endBtn = document.getElementById('endBtn');//结束游戏按钮
var rowsLen = document.getElementById('tableLat').children[0].rows.length;//行数
var cellsLen = document.getElementById('tableLat').children[0].rows[0].cells.length;//每行格子数
var showInfo = document.getElementById('showInfo')//提示面板
var timer = null;//定时器
var message = '小蛇撞到墙了,游戏结束!请点击“开始游戏”按钮重新开始游戏!'
//小蛇
const Snake = {
//蛇身位置
snakeBody: [
{ sbX: 0, sbY: 0 },
],
//蛇移动方向(默认向下)
direction: 'down',
//蛇头位置
snakeHeadX: 0,
snakeHeadY: 0,
//是否继续移动
moveContinue: true,
//小蛇移动
snakeMove: function () {
//判断蛇移动方向
switch (Snake.direction) {
case 'left':
// 判断是否超出棋盘边界,超出结束游戏并提示,没有超出则继续移动
if (Snake.snakeHeadX <= 0) {
Snake.snakeHeadX = 0
Snake.moveContinue = false
endGame()
showInfo.innerHTML = message
} else {
Snake.snakeHeadX--;
Snake.moveContinue = true
}
break;
case 'up':
if (Snake.snakeHeadY <= 0) {
Snake.snakeHeadY = 0
Snake.moveContinue = false
endGame()
showInfo.innerHTML = message
} else {
Snake.snakeHeadY--;
Snake.moveContinue = true
}
break;
case 'right':
if (Snake.snakeHeadX >= 7) {
Snake.snakeHeadX = 7;
Snake.moveContinue = false
endGame()
showInfo.innerHTML = message
} else {
Snake.snakeHeadX++;
Snake.moveContinue = true
}
break;
case 'down':
if (Snake.snakeHeadY >= 7) {
Snake.snakeHeadY = 7
Snake.moveContinue = false
endGame()
showInfo.innerHTML = message
} else {
Snake.snakeHeadY++;
Snake.moveContinue = true
}
break;
}
if (Snake.moveContinue) {
//蛇身移动
Snake.snakeBody.push({ sbX: Snake.snakeHeadY, sbY: Snake.snakeHeadX })
if (lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].getAttribute('isblock') === 'y') {
//下一格是方块,蛇身加长,继续创建方块
lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].setAttribute('isblock', 'n');
lattices.rows[Snake.snakeHeadY].cells[Snake.snakeHeadX].style.background = 'white';
Block.createBlock();
} else {
//原来蛇尾,移动一格后删除蛇尾
lattices.rows[Snake.snakeBody[0].sbX].cells[Snake.snakeBody[0].sbY].style.background = 'white';
Snake.snakeBody.splice(0, 1);
}
//蛇身位置
Snake.snakeBody.forEach(function (item, index, arr) {
lattices.rows[item.sbX].cells[item.sbY].style.background = 'green';
})
}
}
}
//方块
const Block = {
//方块的初始位置
blockPos: { blockX: 0, blockY: 0 },
//随机位置生成方块
createBlock: function () {
Block.blockPos.blockX = Math.floor(Math.random() * 8)
Block.blockPos.blockY = Math.floor(Math.random() * 8)
console.log(Block.blockPos.blockX, Block.blockPos.blockY)
//判断随机位置是否在蛇身位置上
lattices.rows[Block.blockPos.blockX].cells[Block.blockPos.blockY].setAttribute('isblock', 'y');
lattices.rows[Block.blockPos.blockX].cells[Block.blockPos.blockY].style.background = 'red'
}
}
//开始游戏
var startGame = function () {
// 生成小蛇
lattices.rows[0].cells[0].style.background = 'green'
// 移动定时器
timer = setInterval(Snake.snakeMove, 1000)
//生成方块
Block.createBlock();
}
//结束游戏
var endGame = function () {
//清除定时器
clearInterval(timer);
//蛇头位置重置
Snake.snakeHeadX = 0;
Snake.snakeHeadY = 0;
//蛇身重置
Snake.snakeBody.splice(0, Snake.snakeBody.length, { sbX: 0, sbY: 0 })
//重置棋盘格子背景为白色
for (var i = 0; i < rowsLen; i++) {
for (var j = 0; j < cellsLen; j++) {
lattices.rows[i].cells[j].style.background = 'white'
}
}
}
//键盘控制改变方向
var changeDirect = function () {
switch (event.keyCode) {
case 37:
Snake.direction = 'left';
break;
case 38:
Snake.direction = 'up';
break;
case 39:
Snake.direction = 'right';
break;
case 40:
Snake.direction = 'down';
break;
default:
Snake.direction = 'right';
break;
}
}
// 按钮点击事件
startBtn.addEventListener('click', startGame) //开始游戏
endBtn.addEventListener('click', endGame)//结束游戏
// 键盘控制方向
document.addEventListener('keydown', changeDirect)