今天给大家分享一个游戏,用我们所熟悉的JS实现一个贪吃蛇小游戏,自娱自乐一下
首先先整理一下思路:
点击开始游戏 startpage消失 游戏开始
随机出现食物,出现三节蛇开始运动
上下左右 改变方向运动
判断吃到食物 食物消失,蛇加一
判读游戏结束,弹出框
如下图中的一些效果:
接下我们用我们所熟悉的JS实现贪吃蛇小游戏
首先我们基本HTML页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>贪吃蛇</title>
<link rel="stylesheet" href="css/demo.css">
</head>
<body>
<!-- 开始层 -->
<div class="startpage" id="startPage">
<div class="startBtn" id="startBtn">开始游戏</div>
</div>
<!-- 游戏层 -->
<div class="wrapper">
<!-- 开始按钮 -->
<div class="left-side">
<span id="startP">开始</span>
</div>
<div class="main">
<div class="header">
<div class="score">
分数:
<span id="score">0</span>
</div>
</div>
<div class="content" id="content"></div>
</div>
</div>
<!-- 游戏结束层 -->
<div class="loser" id="lose">
<div class="con">
<span class="goal">当前得分</span>
<div class="close" id="close">×</div>
<span class="loserScore" id="loserScore"></span>
</div>
</div>
<script src="js/demo.js"></script>
</body>
</html>
这里页面我们就不多说,相信大家都能看懂;
然后我们是好看的样式CSS:(这里我只是用了一些色块,大家可以用一些好看的图片)
*{
margin: 0;
padding: 0;
}
/* 开始层 */
.startPage{
width: 100%;
z-index: 999;
height: 1000px;
position: absolute;
top: 0;
left: 0;
/* display: none; */
}
/* 开始按钮 */
.startBtn{
width: 200px;
height: 60px;
z-index: 998;
background-color: #008c8c;
cursor: pointer;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
text-align: center;
line-height: 60px;
color: #fff;
font-size: 24px;
border-radius: 5px;
}
/* 游戏层 */
.wrapper{
width: 100%;
height: 1000px;
/* background-color: #fefefe; */
position: relative;
}
/* 游戏左边区域 */
.left-side{
width: 24%;
position: absolute;
height: 1000px;
/* border-right: 1px solid #000; */
}
/* 开始,暂停按钮 */
.left-side span{
width: 100px;
height: 100px;
background-color: #008c8c;
border-radius: 50%;
text-align: center;
line-height: 100px;
color: #fff;
margin-left: 100px;
margin-top: 100px;
display: none;
}
/* 游戏界面 */
.main {
position: absolute;
left: 25%;
width: 50%;
height: 90%;
/* border:1px solid #000; */
}
/* 游戏界面顶部 */
.header{
width: 100%;
height: 80px;
text-align: center;
}
/* 分数 */
.score{
line-height: 80px;
color: #999;
font-size: 20px;
font-weight: bolder;
}
/* 游戏区域 */
.content{
position: absolute;
width: 79.5%;
height: 36.5%;
left: 10%;
top: 34%;
/* border: 1px solid #f40; */
background-color: #000;
}
/* 弹出层 */
.loser{
display: none;
position: 100%;
height: 1000px;
top: 0;
left: 0;
}
/* 弹出框 */
.con{
background-color: #008c8c;
height: 300px;
width: 400px;
position: absolute;
margin: auto;
left: 0;
top: 0;
right: 0;
bottom: 0;
border-radius: 20px;
}
/* 弹出框说明 */
.con .goal{
width: 400px;
height: 50px;
position: absolute;
top: 10px;
left: 0;
text-align: center;
line-height: 50px;
font-size: 30px;
color: #fff;
}
/* 游戏得分 */
.loserScore{
display: block;
height: 30px;
width: 40px;
position: absolute;
top: 42%;
left: 40%;
color: #222;
font-size: 30px;
font-weight: bold;
}
/* 弹出框关闭按钮 */
.close{
position: absolute;
top: 0;
right: 0;
height: 40px;
width: 40px;
background-color: #999;
border-radius: 50px;
margin: 5px;
text-align: center;
line-height: 40px;
font-size: 30px;
color: #fff;
cursor: pointer;
}
/* 食物 */
.food{
background-color: #f40;
border-radius: 50px;
}
/* 蛇的头部 */
.head{
background-color: #f0f;
border-radius: 50px;
}
/* 蛇的身体 */
.body{
background-color: #ff0;
border-radius: 50px;
}
接下来是我们最重要的JS部分
在这里补充一点:
如果大家使用的是VScode编辑器,大家可以装一个插件:Document This(添加注释块)
Document This
添加注释块 连续两次Ctrl+alt+d 出现如下注释
/**
* @class App
* @extends {Component}
*/
注意如有热键冲突,记得将热键冲突关闭
//思路:
//点击开始游戏 startpage消失 游戏开始
//随机出现食物,出现三节蛇开始运动
//上下左右 改变方向运动
//判断吃到食物 食物消失,蛇加一
//判读游戏结束,弹出框
var content = document.getElementById('content')
var startPage = document.getElementById('startPage')
var scoreBox = document.getElementById('score')
var lose = document.getElementById('lose')
var loserScore = document.getElementById('loserScore')
var close = document.getElementById('close')
var startP = document.getElementById('startP')
var startBtn = document.getElementById("startBtn")
var snakeMove;
var speed = 200;
var startGameBool = true;
var startPaushBool = true;
init();
/**
* 存放初始化的参数
* 这里我们设置一个初始化函数,存放一些初始化的参数
*/
function init() {
//地图
this.mapW = parseInt(getComputedStyle(content).width);
this.mapH = parseInt(getComputedStyle(content).height);
this.mapDiv = content;
//食物的坐标
this.foodW = 20;
this.foodH = 20;
this.foodX = 0;
this.foodY = 0;
//蛇的坐标
this.snakeW = 20;
this.snakeH = 20;
this.snakeBody = [[3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body']];
// this.snakeBody = [[4, 3, 'head'], [3,3, 'body'], [3, 2, 'body']];
//游戏属性 上下左右
this.direct = 'right';
this.left = false;
this.right = false;
this.up = true;
this.down = true;
this.score = 0;
bindEvent();
}
function startGame() {
startPage.style.display = 'none'
startP.style.display = 'block'
food();
snake();
}
/**
* 随机生成食物
* 在画布内随机位置生成一个食物(小圆点)
*/
function food() {
var food = document.createElement('div');
food.style.width = this.foodW + 'px';
food.style.height = this.foodH + 'px';
food.style.position = 'absolute';
this.foodX = Math.floor(Math.random() * (this.mapW / 20));
this.foodY = Math.floor(Math.random() * (this.mapH / 20));
food.style.left = this.foodX * 20 + 'px';
food.style.top = this.foodY * 20 + 'px';
this.mapDiv.appendChild(food).setAttribute('class', 'food')
}
/**
* 出现一条蛇
*/
function snake() {
for (var i = 0; i < this.snakeBody.length; i++) {
var snake = document.createElement('div');
snake.style.width = this.snakeW + 'px';
snake.style.height = this.snakeH + 'px';
snake.style.position = 'absolute';
snake.style.left = this.snakeBody[i][0] * 20 + 'px';
snake.style.top = this.snakeBody[i][1] * 20 + 'px';
snake.classList.add(this.snakeBody[i][2]);
this.mapDiv.appendChild(snake).classList.add('snake');
//判断蛇头自身的方向
// 这里是判断用图片的情况下的,如果大家使用的也是色块,大家可以吧这一块去掉
switch (this.direct) {
case 'right':
break;
case 'up':
snake.style.transform = 'rotate(270deg)'
break;
case 'left':
snake.style.transform = 'rotate(180deg)'
break;
case 'down':
snake.style.transform = 'rotate(90deg)'
break;
default:
break;
}
}
}
/**
* 默认运动轨迹
*/
function move() {
for (var i = this.snakeBody.length - 1; i > 0; i--) {
this.snakeBody[i][0] = this.snakeBody[i - 1][0];
this.snakeBody[i][1] = this.snakeBody[i - 1][1];
}
// 假设已经运动,存放方向
switch (this.direct) {
case 'right':
this.snakeBody[0][0] += 1;
break;
case 'up':
this.snakeBody[0][1] -= 1;
break;
case 'left':
this.snakeBody[0][0] -= 1;
break;
case 'down':
this.snakeBody[0][1] += 1;
break;
default:
break;
}
removeClass('snake');
snake();
if (this.snakeBody[0][0] == this.foodX && this.snakeBody[0][1] == this.foodY) {
//吃到食物后自身数量加一
var snakeEndX = this.snakeBody[this.snakeBody.length - 1][0];
var snakeEndY = this.snakeBody[this.snakeBody.length - 1][1];
switch (this.direct) {
case 'right':
this.snakeBody.push([snakeEndX + 1, snakeEndY, 'body']);
break;
case 'up':
this.snakeBody.push([snakeEndX, snakeEndY - 1, 'body']);
break;
case 'left':
this.snakeBody.push([snakeEndX - 1, snakeEndY, 'body']);
break;
case 'down':
this.snakeBody.push([snakeEndX, snakeEndY + 1, 'body']);
break;
default:
break;
}
//吃到食物
this.score += 1;
scoreBox.innerHTML = this.score;
removeClass('food');
food();
}
if (this.snakeBody[0][0] < 0 || this.snakeBody[0][0] >= this.mapW / 20) {
// console.log(1)
relodGame();
}
if (this.snakeBody[0][1] < 0 || this.snakeBody[0][1] >= this.mapH / 20) {
// console.log(1)
relodGame();
}
var snakeHX = this.snakeBody[0][0];
var snakeHY = this.snakeBody[0][1];
for (var i = 1; i < this.snakeBody.length; i++) {
if (snakeHX == snakeBody[i][0] && snakeHY == snakeBody[i][1]) {
// console.log(111)
relodGame();
}
}
}
/**
* 游戏结束,初始化游戏
* 碰撞墙壁时,超出画布范围,重新开始游戏
*/
function relodGame() {
removeClass('snake');
removeClass('food');
clearInterval(snakeMove);//清除定时器
//默认坐标
this.snakeBody = [[3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body']];
this.direct = 'right';
this.left = false;
this.right = false;
this.up = true;
this.down = true;
lose.style.display = 'block';//弹出框
loserScore.innerHTML = this.score;//弹出框内容更改
this.score = 0;
scoreBox.innerHTMl = this.score;//顶部分数
//重新开始游戏
startGameBool = true;
startPaushBool = true;
startP.innerHTML = '开始'
}
/**
* 删除具有className 的元素
* @param {*} className
*/
function removeClass(className) {
var ele = document.getElementsByClassName(className);
while (ele.length > 0) {
ele[0].parentNode.removeChild(ele[0]);
}
}
/**
* 判断上下左右方向
* @param {*} code
*/
function setDerict(code) {
//判断游戏中,上下左右方向
switch (code) {
case 37:
if (this.left) {
this.direct = 'left';
this.left = false;
this.right = false;
this.up = true;
this.down = true;
}
break;
case 38:
if (this.up) {
this.direct = 'up';
this.left = true;
this.right = true;
this.up = false;
this.down = false;
}
break;
case 39:
if (this.right) {
this.direct = 'right';
this.left = false;
this.right = false;
this.up = true;
this.down = true;
}
break;
case 40:
if (this.down) {
this.direct = 'down';
this.left = true;
this.right = true;
this.up = false;
this.down = false;
}
break;
default:
break;
}
}
/**
* 监听页面
*/
function bindEvent() {
//弹出框关闭按钮u
close.onclick = function () {
lose.style.display = 'none'
}
//开始游戏按钮
startBtn.onclick = function () {
startAddPaush();
}
//暂停,开始按钮
startP.onclick = function () {
startAddPaush();
}
}
/**
* 执行游戏
*/
function startAddPaush() {
if (startPaushBool) {
if (startGameBool) {
startGame();
startGameBool = false;
}
startP.innerHTML = '暂停';
document.onkeydown = function (e) {
var code = e.keyCode;
setDerict(code);
}
snakeMove = setInterval(function () {
move()
}, speed)
startPaushBool = false;
} else {
startP.innerHTML = '开始';
clearInterval(snakeMove);
document.onkeydown = function (e) {
e.returnValue = false;
return false;
}
startPaushBool = true;
}
}
这里给他们准备了一份源码,地址如下:
https://github.com/Janesuyue/Gluttonous-Snake
在本地下拉仓库即可;
clone https://github.com/Janesuyue/Gluttonous-Snake.git