原生js贪吃蛇加暂停和倍速功能以下是1.0版本

先体验为敬:188.131.132.214/snake.html

2.0版本在我的github上https://github.com/zxy1131167456/snake

github上有原图片,欢迎clone~fork

 

<!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前小图标 -->

<link rel="icon" href="img/title.ico" type="img/x-ico" />

<title>贪吃蛇小游戏v1.0</title>

<link rel="stylesheet" href="snake.css">

</head>

 

<body>

<div class="conent" id="conent">

</div>

<div class="start" id="start">

</div>

<div class="score">

得分:

<span id="score"></span>

</div>

<div class="restart" id="restart">

得分:<span id="scores"></span>

<button id="btn">再来一局</button>

</div>

<div class="stop" id="stop" title="暂停"></div>

<div class="stop1" id="stop1" title="开始"></div>

<div class="change">

<button id="btn1">1倍速<span>(龟速慎选)</span></button>

<button id="btn2">2倍速<span>(默认选中)</span></button>

<button id="btn3">3倍速<span>(超速慎选)</span></button>

</div>

<script src="snake.js"></script>

</body>

 

</html>

 

* {

margin: 0;

padding: 0;

}

 

body {

width: 100%;

height: auto;

background-image: url('./img/1.jpg');

background-repeat: no-repeat;

/* background-size: 100% 100%; body里的错误写法*/

background-size: 100%;

}

 

.conent {

width: 900px;

height: 600px;

position: fixed;

top: 0px;

bottom: 0;

left: 0;

right: 0;

margin: auto;

background-image: url('./img/4.jpg');

background-repeat: no-repeat;

background-size: 100% 100%;

}

 

.start {

width: 350px;

height: 100px;

z-index: 9999;

position: absolute;

top: 0px;

bottom: 0;

left: 0;

right: 0;

margin: auto;

background-image: url('./img/start.png');

background-repeat: no-repeat;

background-size: 100% 100%;

cursor: pointer;

}

 

.food {

background-image: url('./img/apple.png');

background-size: 100% 100%;

}

 

.head {

background-image: url('./img/head.png');

background-size: 100% 100%;

}

 

.body {

background-image: url('./img/body.png');

background-size: 100% 100%;

}

 

.score {

width: 30%;

height: 50px;

text-align: center;

font-size: 50px;

font-weight: bold;

position: absolute;

left: 35%;

top: 20px;

}

 

.restart {

display: none;

width: 20%;

height: 100px;

border: 1px solid #cec67f;

border-radius: 50%;

z-index: 9999;

text-align: center;

font-size: 30px;

font-weight: bold;

position: absolute;

top: 0px;

bottom: 0;

left: 0;

right: 0;

margin: auto;

background: #91c9c9

}

 

.restart button {

width: 50%;

height: 50px;

font-size: 30px;

font-weight: bold;

background: #91c9c9;

position: absolute;

bottom: 10px;

left: 25%;

cursor: pointer;

border: none;

border: 1px solid #061f1f;

border-radius: 10px;

}

 

.stop {

width: 100px;

height: 100px;

position: absolute;

left: 10%;

top: 10%;

background-image: url('./img/stop.png');

background-repeat: no-repeat;

background-size: 100% 100%;

cursor: pointer;

}

 

.stop1 {

display: none;

width: 100px;

height: 100px;

position: absolute;

left: 10%;

top: 10%;

background-image: url('./img/stop1.png');

background-repeat: no-repeat;

background-size: 100% 100%;

cursor: pointer;

}

 

.change {

width: 10%;

height: 50%;

position: absolute;

left: 8%;

top: 30%;

}

 

.change #btn1 {

width: 100%;

height: 30%;

font-size: 40px;

border: none;

border-radius: 10px;

background: #19cfcf;

cursor: pointer;

}

 

.change #btn2 {

width: 100%;

height: 30%;

font-size: 40px;

margin-top: 3%;

border: none;

border-radius: 10px;

background: #19cfcf;

cursor: pointer;

opacity: 0.5;

}

 

.change #btn3 {

width: 100%;

height: 30%;

margin-top: 3%;

font-size: 40px;

border: none;

border-radius: 10px;

background: #19cfcf;

cursor: pointer;

}

 

.change #btn1 span {

font-size: 15px;

}

 

.change #btn2 span {

font-size: 15px;

}

 

.change #btn3 span {

font-size: 15px;

}

 

 

 

var conent = document.getElementById('conent');

var start = document.getElementById('start');

var restart = document.getElementById('restart');

var timer;

var speed = 100;

var lock = true;

var lock1 = true;

init();

//初始化

function init() {

//游戏区域

this.mapW = parseInt(getComputedStyle(conent).width); //取到conent边界宽度的数值

this.mapH = parseInt(getComputedStyle(conent).height); //getComputerStyle()只能获取dom元素的样式

this.mapDiv = conent;

//食物小苹果

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.direct = 'right';

this.right = false;

this.left = false;

this.up = true;

this.down = true;

this.score = 0;

document.getElementById('score').innerHTML = this.score;

speedChange();

bindEvent();

}

//start开始点击事件

function bindEvent() {

start.onclick = function() {

lock1 = false; //点击选择完速度之后不可再次选择速度,所以将速度锁锁上

start.style.display = 'none';

food();

snake();

timer = setInterval(function() {

move();

}, speed)

keyDown();

}

}

//随机生成食物

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() {

// console.log(1);

for (i = this.snakeBody.length - 1; i > -1; i--) { //也可以写成for(i = 0; i < this.snakeBody.length; i++)

// console.log(i);

// this.snake[i][0] = this.snake[i - 1][0];

// this.snake[i][1] = this.snake[i - 1][1];

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 'left':

snake.style.transform = 'rotate(180deg)';

break;

case 'up':

snake.style.transform = 'rotate(270deg)';

break;

case 'down':

snake.style.transform = 'rotate(90deg)';

break;

}

}

}

 

function move() {

sTop();

if (lock) {

// console.log(1);

//蛇的移动通过数组里,后一位等于前一位

for (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) {

//向右时数组第一位也就是蛇头的X坐标值+1,以此类推

case 'right':

this.snakeBody[0][0] += 1;

break;

case 'left':

this.snakeBody[0][0] -= 1;

break;

case 'up':

this.snakeBody[0][1] -= 1;

break;

case 'down':

this.snakeBody[0][1] += 1;

break;

default:

break;

}

//删除原来的蛇

removeClass('snake');

//渲染新的蛇

snake();

//当蛇头和食物的XY相等时

while (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) {

//向右Y固定,X+1可参考101行,以此类推

case 'right':

this.snakeBody.push([snakeEndX + 1, snakeEndY, 'body']);

break;

case 'left':

this.snakeBody.push([snakeEndX - 1, snakeEndY, 'body']);

break;

case 'up':

this.snakeBody.push([snakeEndX, snakeEndY - 1, 'body']);

break;

case 'down':

this.snakeBody.push([snakeEndX, snakeEndY + 1, 'body']);

break;

default:

break;

}

this.score += 1;

document.getElementById('score').innerHTML = this.score;

removeClass('food');

food();

}

//当蛇头和左右边界相撞即X坐标值为0或边界宽度除以自身大小20px时结束游戏

while (this.snakeBody[0][0] < 0 || this.snakeBody[0][0] >= this.mapW / 20) {

// alert("得分:" + this.score);

reGame();

 

}

//当蛇头和上下边界相撞时结束游戏

while (this.snakeBody[0][1] < 0 || this.snakeBody[0][1] >= this.mapH / 20) {

// alert("得分:" + this.score);

reGame();

}

//取到蛇头的X,Y坐标值

var snakeHX = this.snakeBody[0][0];

var snakeHY = this.snakeBody[0][1];

for (var i = 1; i < this.snakeBody.length; i++) {

//当蛇头和蛇身相撞即XY坐标值相同时结束游戏

while (snakeHX == this.snakeBody[i][0] && snakeHY == this.snakeBody[i][1]) {

// alert("得分:" + this.score);

reGame();

}

}

}

}

//重新开始游戏

function reGame() {

removeClass('snake');

removeClass('food');

clearInterval(timer);

document.getElementById('restart').style.display = 'block';

document.getElementById('scores').innerHTML = this.score;

//再次初始化

this.snakeW = 20;

this.snakeH = 20;

this.snakeBody = [

[3, 1, 'head'],

[2, 1, 'body'],

[1, 1, 'body']

];

this.direct = 'right';

this.right = false;

this.left = false;

this.up = true;

this.down = true;

this.score = 0;

document.getElementById('score').innerHTML = this.score;

lock1 = true; //重新开始可再次选择速度

// speedChange();

//点击再来一局事件,开始新的一局

document.getElementById('btn').onclick = function() {

lock1 = false; //点击开始后再次将速度选择锁锁上

document.getElementById('restart').style.display = 'none';

food();

snake();

timer = setInterval(function() {

move();

}, speed)

keyDown();

}

}

//移除类名

function removeClass(className) {

var ele = document.getElementsByClassName(className);

while (ele.length > 0) {

ele[0].parentNode.removeChild(ele[0]);

}

}

//这里为了reurn的this.direct时全局的,所以要单独写一个functionsetDerict,

//如果写在KeyDown里面的话,return的this.direct会在函数keyDown里,从而导致其他函数里

//无法调用this.direct,从而使得按下键盘蛇的运动方向不变(编程时遇到的问题,自己觉得是这个原因)

function setDerict(code) {

switch (code) {

case 37:

//设置锁,蛇在向右移动时只能向上下改变方向,以此类推

// console.log(1);

if (this.left) {

this.direct = 'left';

this.left = false;

this.right = false;

this.up = true;

this.down = true;

}

break;

case 38:

// console.log(2);

if (this.up) {

this.direct = 'up';

this.up = false;

this.down = false;

this.left = true;

this.right = true;

}

break;

case 39:

// console.log(3);

if (this.right) {

this.direct = 'right';

this.up = true;

this.down = true;

this.left = false;

this.right = false;

}

break;

case 40:

// console.log(4);

if (this.down) {

this.direct = 'down';

this.up = false;

this.down = false;

this.left = true;

this.right = true;

}

break;

default:

break;

}

}

//键盘按下事件

function keyDown() {

document.onkeydown = function(e) {

var code = e.keyCode; //获取上下左右的ACSII码值

setDerict(code);

}

}

//暂停函数

function sTop() {

document.getElementById('stop').onclick = function() {

lock = false;

document.getElementById('stop1').style.display = 'block';

}

document.getElementById('stop1').onclick = function() {

lock = true;

document.getElementById('stop1').style.display = 'none';

}

}

//速度选择器

function speedChange() {

document.getElementById('btn1').onclick = function() {

if (lock1) {

document.getElementById('btn1').style.opacity = '0.5';

document.getElementById('btn2').style.opacity = '1';

document.getElementById('btn3').style.opacity = '1';

speed = 200;

}

}

document.getElementById('btn2').onclick = function() {

if (lock1) {

document.getElementById('btn2').style.opacity = '0.5';

document.getElementById('btn1').style.opacity = '1';

document.getElementById('btn3').style.opacity = '1';

speed = 100;

}

}

document.getElementById('btn3').onclick = function() {

if (lock1) {

document.getElementById('btn3').style.opacity = '0.5';

document.getElementById('btn1').style.opacity = '1';

document.getElementById('btn2').style.opacity = '1';

speed = 50;

}

}

}

源码下载:https://download.youkuaiyun.com/download/zxy15946565183/10862695

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值