用jquery写贪吃蛇

7次阅读

共计 7050 个字符,预计需要花费 18 分钟才能阅读完成。

需要具备知识:1.html、css 基础 2.jquery 基础

具体实现方法:
创建游戏界面
.bts
{
display: flex;
}
.bt
{
width: 60px;
height: 24px;
line-height: 24px;
font-size: 18px;
text-align: center;
background: #ede;
margin-left: 20px;
}
.bg
{
width: 400px;
height: 400px;
background: #ddd;
margin-top: 30px;
position: relative;
}

<div class=”bts”>
<div class=”start bt” onclick=”start()”> 开始 </div>
<!– <div class=”pause bt” onclick=”pause()”> 暂停 </div> –>
</div>
<div class=”bg”>

</div>
其中 bts 是按钮组,因为开始打算写个暂停,后面放弃了,bt 是按钮,bg 是游戏界面(大小最好为 10,15,20 的倍数,比较容易计算游戏内方块的), 其中 bg(游戏界面背景)是才用 relative 定位,蛇与食物采用用 absolute 定位。
定义游戏主要函数首先,假设游戏内方块的个数为 2020,每个方块的大小为 20px20px(当然为了适配手机,可以转换为 rem 去适配网页大小),蛇与食物的大小为一个方块的大小 (food 为食物,snakes 为蛇)其中因为 border 会在 div 的外面去渲染,所以,大小为 20 的方块,实际宽高为 18px,加上上下各 1px 的边框,一个食物与蛇的大小为 20px*20px

.snakes,.food
{
position: absolute;
width: 18px;
height: 18px;
border: solid 1px #444;
}
.snakes
{
background: red;
}
.food
{
background: yellow;
}

定义游戏中的变量,
var snakes = []; // 存储蛇的位置
var stepX = 20; // 默认向 X 行走的像素
var stepY = 0; // 默认向 Y 行走的像素
var live = false; // 是否存活
var isPause = false; // 是否暂停,未用
var food = {}; // 食物的位置
var keydown = ‘right’; // 默认方向为右
start() 函数,点击开始游戏时候,执行的操作
start = function(){ // 开始
if(!live)
{
stepX = 20;
stepY = 0;
keydown = ‘right’;
live = true;
$(“.snakes”).remove();
snakes = [];
drawSnake(3); // 初始化蛇
snakeMove(); // 移动蛇,游戏主要进程
createFood(); // 创建食物
}
isPause = false;

}
首先点击游戏开始的时候,需要去初始化一下蛇,让他生成在游戏区域内的左上角,由于采用的是 absolute 定位,所以,默认的第一个点的位置为 top:0;left:0; (看成坐标轴的话,右上角的原点为 0,0),定义一个蛇的方块,通过 for 循环,将蛇画在屏幕的左上角,其中 num 为默认蛇的长度。然后将创建的元素存成 json 格式的,push 在 snakes 数组里面。由于 push() 是往最后面去添加元素,所以蛇的头是 snakes 里面最后的一个元素

drawSnake = function(num){// 初始化蛇身体
var item = ‘<div class=”snakes”></div>’
for(var i=0;i<num;i++)
{
$(“.bg”).append(item)
$(“.snakes”).eq(i).css({
top:0,
left:20*i
})
item1 = {
top:0,
left:20*i
}
snakes.push(item1)
//console.log(snakes);
}
}
使用 setTimeout(), 去驱动蛇,由于蛇头是存在数组的最后一位,所以蛇头其实是 snakes[snakes.length-1] 这个元素,然后,通过 for 循环,去让蛇的第 i 个元素的值等于第 i + 1 个值(蛇头是最后一个,所以如果蛇长度为三个的话,先把第一个的位置移动到第第二个的位置,第二个的位置移动到第一个的位置,然后再将蛇头往其他地方移动,就说明蛇移动了),然后 setTimeout 里面继续递归调用该函数,蛇就会开始移动
snakeMove = function(){ // 移动蛇
if(live){// 判断蛇是否存活,如果存活,则移动蛇, 否则弹出游戏结束
for(var i=0;i<snakes.length-1;i++)
{
$(“.snakes”).eq(i).css({
top:snakes[i+1].top,
left:snakes[i+1].left
})
snakes[i].top = snakes[i+1].top
snakes[i].left = snakes[i+1].left
}
var first = snakes.length-1
$(“.snakes”).eq(first).css({
top:snakes[first].top+stepY,
left:snakes[first].left+stepX
})
snakes[first].top = snakes[first].top+stepY;
snakes[first].left = snakes[first].left+stepX;
if(!isLive(snakes[first].top,snakes[first].left))
{
live = false;
alert(“ 游戏结束 ”);
}
else
{
eatFood(snakes[first].top,snakes[first].left);
setTimeout(“snakeMove()”,100);
}
}
}

将蛇驱动后,开始控制蛇的移动与游戏结束。
isLive = function(top,left){
if(top>380||top<0||left>380||left<0) // 如果蛇移动到画布外面,则游戏结束,开始坐标是 0,0,所以边界值是 380,380
{
return false;
}
else
{
for(var i=0;i<snakes.length-1;i++) // 循环蛇每个元素,判断蛇头是否与他们重合,重合的话,则说明蛇撞到自己,游戏结束
{

if(top==snakes[i].top&&left==snakes[i].left)
{
return false;
break;
}
}
return true;
}
}
document.onkeydown = function(event) {// 判断点击的按钮,让蛇往不同的方向去走 ( 注意右上角是坐标原点,往下是 Y,往右是 X)
//console.log(event);
if(event.keyCode==38) // 上
{
if(keydown!=’down’) // 如果往下走,就不能只能摁上,如果直接倒着走,会撞到自己,结束游戏
{
keydown=’up’;
stepX=0;
stepY=-20;
}
}
else if(event.keyCode==40) // 下
{
if(keydown!=’up’)
{
keydown=’down’;
stepX=0;
stepY=20;
}
}
else if(event.keyCode==37) // 左
{
if(keydown!=’right’)
{
keydown=’left’;
stepX=-20;
stepY=0;
}
}
else if(event.keyCode==39) // 右
{
if(keydown!=’left’)
{
keydown=’right’
stepX=20;
stepY=0;
}
}
}
将结束游戏与蛇移动处理完后,开始处理创建食物与判断是否吃掉食物
createFood = function(){ // 创建食物
$(“.food”).remove(); // 首先清理掉开始默认的食物(后面吃掉食物的时候,也会用该函数进行创建)
isCreate = true // 设置一个状态去判断食物是否创建成功
do
{
food={// 生成食物的位置,用随机数生成(边界值为 380,380 上面说过)
top:Math.round(Math.random()*19)*20,
left:Math.round(Math.random()*19)*20
}
for(var i=0;i<snakes.length;i++) // 循环蛇身体,让生成的食物不能生成在蛇身上,如果生成成功了,就跳出 do while (没有做通关的判断,因为感觉没人能玩到通关)
{
if(food.top==snakes[i].top&&food.left==snakes[i].left)
{
isCreate = false;
break;
}
else
{
isCreate = true;
}
}
}
while(!isCreate)
var foodItem ='<div class=”food”></div>’
$(“.bg”).append(foodItem);
$(“.food”).css({
top:food.top,
left:food.left
})
}
eatFood = function(top,left){// 是否吃到食物
if(top==food.top&&left==food.left) // 如果蛇吃到食物,那么蛇头的坐标与食物坐标重合,然后将食物那个点作为蛇头,append 一个蛇元素到游戏里面,再把坐标 push 到蛇里面,然后创建一个新的食物
{
var item = ‘<div class=”snakes”></div>’
snakes.push({top:top,left:left})
$(“.bg”).append(item)
$(“.snakes”).last().css({
top:top,
left:left
})
createFood();
}
}
项目源码:
<!DOCTYPE html>
<html>
<head>
<title> 贪吃蛇 </title>
<meta charset=”utf-8″>
<script type=”text/javascript” src=”https://cdn.bootcss.com/jquery/3.3.1/jquery.js”></script>
<style type=”text/css” media=”screen”>
.bts
{
display: flex;
}
.bt
{
width: 60px;
height: 24px;
line-height: 24px;
font-size: 18px;
text-align: center;
background: #ede;
margin-left: 20px;
}
.bg
{
width: 400px;
height: 400px;
background: #ddd;
margin-top: 30px;
position: relative;
}
.snakes,.food
{
position: absolute;
width: 18px;
height: 18px;
border: solid 1px #444;
}
.snakes
{
background: red;
}
.food
{
background: yellow;
}
</style>
</head>
<body>
<div class=”bts”>
<div class=”start bt” onclick=”start()”> 开始 </div>
<!– <div class=”pause bt” onclick=”pause()”> 暂停 </div> –>
</div>
<div class=”bg”>

</div>
</body>
<script type=”text/javascript”>
var snakes = [];
var stepX = 20;
var stepY = 0;
var live = false;
var isPause = false;
var food = {};
var keydown = ‘right’; // 默认方向为右
start = function(){ // 开始
if(!live)
{
stepX = 20;
stepY = 0;
keydown = ‘right’;
live = true;
$(“.snakes”).remove();
snakes = [];
drawSnake(5);
snakeMove();
createFood();
}
isPause = false;

}
pause = function(){ // 暂停
isPause = true;
}
drawSnake = function(num){// 初始化蛇身体
var item = ‘<div class=”snakes”></div>’
for(var i=0;i<num;i++)
{
$(“.bg”).append(item)
$(“.snakes”).eq(i).css({
top:0,
left:20*i
})
item1 = {
top:0,
left:20*i
}
snakes.push(item1)
//console.log(snakes);
}
}
snakeMove = function(){ // 移动蛇
if(live){
for(var i=0;i<snakes.length-1;i++)
{
$(“.snakes”).eq(i).css({
top:snakes[i+1].top,
left:snakes[i+1].left
})
snakes[i].top = snakes[i+1].top
snakes[i].left = snakes[i+1].left
}
var first = snakes.length-1
$(“.snakes”).eq(first).css({
top:snakes[first].top+stepY,
left:snakes[first].left+stepX
})
snakes[first].top = snakes[first].top+stepY;
snakes[first].left = snakes[first].left+stepX;
if(!isLive(snakes[first].top,snakes[first].left))
{
live = false;
alert(“ 游戏结束 ”);
}
else
{
eatFood(snakes[first].top,snakes[first].left);
setTimeout(“snakeMove()”,100);
}
}
}
isLive = function(top,left){
if(top>380||top<0||left>380||left<0)
{
return false;
}
else
{
for(var i=0;i<snakes.length-1;i++)
{

if(top==snakes[i].top&&left==snakes[i].left)
{
return false;
break;
}
}
return true;
}
}
createFood = function(){ // 创建食物
$(“.food”).remove();
isCreate = true
do
{
food={
top:Math.round(Math.random()*19)*20,
left:Math.round(Math.random()*19)*20
}
for(var i=0;i<snakes.length;i++)
{
if(food.top==snakes[i].top&&food.left==snakes[i].left)
{
isCreate = false;
break;
}
else
{
isCreate = true;
}
}
}
while(!isCreate)
var foodItem ='<div class=”food”></div>’
$(“.bg”).append(foodItem);
$(“.food”).css({
top:food.top,
left:food.left
})
}
eatFood = function(top,left){// 是否吃到食物
if(top==food.top&&left==food.left)
{
var item = ‘<div class=”snakes”></div>’
snakes.push({top:top,left:left})
$(“.bg”).append(item)
$(“.snakes”).last().css({
top:top,
left:left
})
createFood();
}
}
document.onkeydown = function(event) {
//console.log(event);
if(event.keyCode==38) // 上
{
if(keydown!=’down’)
{
keydown=’up’;
stepX=0;
stepY=-20;
}
}
else if(event.keyCode==40) // 下
{
if(keydown!=’up’)
{
keydown=’down’;
stepX=0;
stepY=20;
}
}
else if(event.keyCode==37) // 左
{
if(keydown!=’right’)
{
keydown=’left’;
stepX=-20;
stepY=0;
}
}
else if(event.keyCode==39) // 右
{
if(keydown!=’left’)
{
keydown=’right’
stepX=20;
stepY=0;
}
}
}

</script>
</html>

正文完
 0