JS----贪吃蛇游戏

时间:2021-02-26 05:06:17

在网上找到的几种例子

<!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gbk">
<title>贪吃蛇游戏</title> <style type="text/css">
* {
margin: 0;
padding: 0;
} .wrap {
width: 600px;
margin: 0 auto;
position: relative;
} p {
position: absolute;
left: 65%;
top: 10%;
} h1 {
text-align: center;
margin-bottom: 20px;
} #score {
text-align: center;
font-size: 20px;
} #snake_map {
margin: 0 auto;
border: 1px solid skyblue;
}
/*行样式*/
.row {
height: 20px;
}
/*列样式*/
.col {
height: 20px;
width: 20px;
box-sizing: border-box;
border: 1px solid lightgray;
background: rgb(250, 250, 250);
float: left;
} .activeSnake {
background: black;
} .egg {
background: red;
} #Pause {
margin-left: 18%;
border: 1px solid skyblue;
color: white;
background: skyblue;
width: 50px;
height: 30px;
margin-bottom: 10px;
border-radius: 5px;
} #Start,#Refresh,#Speed {
border: 1px solid skyblue;
background: skyblue;
color: white;
width: 50px;
height: 30px;
border-radius: 5px;
margin-left: 15px;
}
</style> </head>
<body>
<div class="wrap">
<h1>贪吃蛇游戏</h1>
<!-- 记录吃了多少个蛋 -->
<p style="font-size:20px;color:red"> score:<span id="score" style="color:black">0</span> </p>
<!-- 暂停按钮 -->
<input id="Pause" type="button" name="name" value="Pause">
<!-- 开始按钮 -->
<input id="Start" type="button" name="name" value="Start">
<!-- 刷新(重新开始游戏) -->
<input id="Refresh" type="button" name="name" value="Refresh">
<!-- 加速按钮 -->
<input id="Speed" type="button" name="name" value="Speed">
<!-- 贪吃蛇的行走路径地图 -->
<div id="snake_map"> </div>
</div>
</body> <script type="text/javascript">
//获取分数标签
var score = document.getElementById('score');
// 获取路径地图标签
var map = document.getElementById('snake_map');
// 为了灵活的设置地图的大小,以下设置两个变量
// 用于存储行数和列数(即方格的个数)
var rowNumber = 25;// 行数
var columnNumber = 20;// 列数;
var mapWidth = columnNumber * 20 + 'px';// 地图的宽
var mapHeight = rowNumber * 20 + 'px';// 地图的高
map.style.width = mapWidth;
map.style.height = mapHeight;// 设置地图宽高
// 创建一个二维数组,用来记录地图上的所有div的位置
var snakeDIVPosition = [];
// 通过双层for循环来创建地图元素
for ( var i = 0; i < rowNumber; i++) {
// 创建行div
var rowDIV = document.createElement('div');
// 设置div样式
rowDIV.className = 'row';
// 将行div添加到路径地图map中
map.appendChild(rowDIV);
// 创建一个行级数组,用来存储当前行中的每个方块div
var rowArray = [];
for ( var j = 0; j < columnNumber; j++) {
// 创建每一行中的方块div
var columnDIV = document.createElement('div');
// 设置css样式
columnDIV.className = 'col';
// 将方块DIV添加到当前行中
rowDIV.appendChild(columnDIV);
// 同时将方块添加到行数组中
rowArray.push(columnDIV);
}
// 当前内层循环结束,将行数组添加到二维数组中
snakeDIVPosition.push(rowArray);
} // 创建蛇模型
// 创建一个一维数组,用来存储蛇身所占的div
var snake = [];
// 固定蛇身起始长度为3个div
for ( var i = 0; i < 3; i++) {
// 为蛇身设置不同颜色的div
snakeDIVPosition[0][i].className = 'col activeSnake';
// 存储在蛇身数组中
snake[i] = snakeDIVPosition[0][i];
}
// 定义变量来控制蛇
var x = 2;
var y = 0;// 蛇头的起始位置偏移量
var scoreCount = 0;// 分数计数器,即吃了多少个蛋
var eggX = 0;// 记录蛋所在的行位置
var eggY = 0;// 记录蛋所在的列位置; var direction = 'right';// 记录蛇移动的方向,初始为向右
var changeDir = true;// 判断是否需要改变蛇的移动方向
var delayTimer = null;// 延迟定时器 // 添加键盘事件监听方向键来改变蛇的移动方向
document.onkeydown = function(event) {
// 先判断是否需要改变方向,true表示需要,false表示不需要
if (!changeDir) {
return;// return空表示直接结束函数,后续代码不执行
}
event = event || window.event;
// 为了合理处理蛇的移动,需要判断蛇头和蛇身
// 假设蛇向右移动,点方向键左,右键都不需要做出响应
if (direction == 'right' && event.keyCode == 37) {
return;// 终止事件执行
}
if (direction == 'left' && event.keyCode == 39) {
return;
}
if (direction == 'up' && event.keyCode == 40) {
return;
}
if (direction == 'down' && event.keyCode == 38) {
return;
}
// 我们通过keyCode确定蛇要移动的方向
switch (event.keyCode) {
case 37:
direction = 'left';// 向左
break;
case 38:
direction = 'up';// 向上;
break;
case 39:
direction = 'right';// 向右
break;
case 40:
direction = 'down';// 向下
break;
}
changeDir = false;
delayTimer = setTimeout(function() {
// 设置是否需要改变方向
changeDir = true;
}, 300);
}; // 开始设置蛇移动逻辑
// 蛇移动函数
function snakeMove() {
// 根据上面设置的方向来设置蛇头的位置
switch (direction) {
case 'left':
x--;
break;
case 'right':
x++;
break;
case 'up':
y--;
break;
case 'down':
y++;
break;
};
// 判断是否游戏结束
if (x < 0 || y < 0 || x >= columnNumber || y >= rowNumber) {
alert('Game Over!!!');
// 结束蛇移动的定时器
clearInterval(moveTimer);
return;// 终止键盘事件;
}
// 如果蛇吃到自己,也要结束游戏
for ( var i = 0; i < snake.length; i++) {
// 将此时蛇头移动后的位置与之前左右的组成蛇的div的位置进行比较,如果相同则说明吃到自己,游戏结束
if (snake[i] == snakeDIVPosition[y][x]) {
alert('Game over!!!');
clearInterval(moveTimer);
return;
};
}
// 判断蛇头移动的位置是否有蛋
if (eggX == x && eggY == y) {
snakeDIVPosition[eggY][eggX].className = 'col activeSnake';
snake.push(snakeDIVPosition[eggY][eggX]);// 加入蛇身
scoreCount++;// 记录分数
// 更新当前的分数
score.innerHTML = scoreCount;
// 随机产生一个新的蛋
createNewEgg();
} else {
// 设置蛇碰不到蛋的逻辑
// 让蛇移动
// 蛇尾去掉蛇自身的颜色,变成格子的颜色
snake[0].className = 'col';
// 将蛇尾div从数组中移除
snake.shift();
// 定位到的新的蛇头加入到蛇数组中
snakeDIVPosition[y][x].className = 'col activeSnake';
snake.push(snakeDIVPosition[y][x]);
};
}; var moveTimer = setInterval('snakeMove()', 300); // 定义一个生成min,max之间的随机数函数
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}; function createNewEgg() {
// 随机出新的egg的下标的x和y值
eggX = random(0, columnNumber - 1);
eggY = random(0, rowNumber - 1); // 判断如果随机产生的蛋与蛇身重合,就重新随机产生一个蛋
if (snakeDIVPosition[eggY][eggX].className == 'col activeSnake') {
createNewEgg();// 重新随机新的egg
} else {
snakeDIVPosition[eggY][eggX].className = 'col egg';
}
}; createNewEgg();// 在游戏开始的时候生成新的egg var pause = document.getElementById('Pause');
var start = document.getElementById('Start');
var refresh = document.getElementById('Refresh');
var speed = document.getElementById('Speed');
// 添加暂停按钮
pause.onclick = function() {
clearInterval(moveTimer);
};
// 添加开始按钮
start.onclick = function() {
clearInterval(moveTimer);
moveTimer = setInterval('snakeMove()', speed1);
};
// 添加刷新按钮
refresh.onclick = function() {
window.location.reload();
};
// 添加加速按钮
var speed1 = 300;
speed.onclick = function() {
speed1 -= 20;
clearInterval(moveTimer);
moveTimer = setInterval('snakeMove()', speed1);
};
</script> </html>

2、

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
</head> <body> <canvas id="canvasTCS">
</canvas> <script>
var tcs = function (id) {
this.element = document.getElementById(id);
this.element.width = this.column * this.cellSize + 200
this.element.height = this.row * this.cellSize + 200;
this.ctx = this.element.getContext("2d");
this.bodys = [];
this.init();
this.drawMap(); }
// 设置他的基础属性
tcs.prototype = {
cellSize: 30,
row: 20,
column: 20,
level: 1,// 默认第一关
tcsOptions: {
hColor: "green",
sColor: "gray",
shiwuColor: "blue",
zawColor: "#000",
bodyLength: 5 }, // 地图
maps: [
'',
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
],
[
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
]
],
drawMap: function () {
var
that = this,
maps = that.maps,
bodys = that.bodys,
ctx = this.ctx,
cellSize = that.cellSize,
row = that.row,
column = that.column,
width = column * cellSize,
height = row * cellSize,
startX = 100,
startY = 100,
x = 0.5
;
if (maps.length == 1) {
return;
}
if (that.level > maps.length) {
that.level = 1;
}
ctx.lineWidth = 1;
ctx.strokeStyle = "#000";
ctx.beginPath();
for (var i = 0; i <= row; i++) {
ctx.moveTo(startX + x, startY + (i * cellSize) + x);
ctx.lineTo(startX + width + x, startY + (i * cellSize) + x)
}
for (var i = 0; i <= column; i++) {
ctx.moveTo(startX + (i * cellSize) + x, startY + x);
ctx.lineTo(startX + (i * cellSize) + x, startY + height + x)
}
for (var i = 0; i < row; i++) {
bodys[i] = [];
for (var c = 0; c < column; c++) {
bodys[i][c] = {
x: startX + (c * cellSize) + 1,
y: startY + (i * cellSize) + 1,
w: cellSize - 1,
h: cellSize - 1,
color: maps[this.level][i][c] == 0 ? "" : this.tcsOptions.zawColor }; }
}
ctx.stroke();
this.createTcs();
this.drawBody(); this.isStartGame = false;
this.direction = 39;
this.speed = 500;
this.gameover = false;
this.isAddSpeed = true;
this.movecomplete = false;
},
drawBody: function () {
var bodys = this.bodys, len = bodys.length;
for (var i = 0; i < len; i++) {
for (var c = 0, len2 = bodys[i].length; c < len2; c++) { this.drawPoint(bodys[i][c]); }
}
},
drawPoint: function (d) {
this.ctx.fillStyle = d.color || "#fff";
this.ctx.fillRect(d.x, d.y, d.w, d.h);
},
createTcs: function () {
var that = this, sheSheng = that.sheSheng = [];
for (var i = 2, len = this.tcsOptions.bodyLength + i; i < len; i++) { sheSheng.push({
r: 1,
c: i
});
}
this.drawTcs();
that.createSW(1);
},
drawTcs: function () {
for (var i = 0; i < this.sheSheng.length; i++) {
this.bodys[this.sheSheng[i].r][this.sheSheng[i].c].color = this.gameover ? this.tcsOptions.sColor : this.tcsOptions.hColor;
}
}, eachSheSheng: function (fn) {
for (var i = 0; i < this.sheSheng.length; i++) {
fn.call(this.sheSheng[i]);
}
},
startGame: function () {
var that = this,
maxLen = 15,
speed = that.speed / maxLen,
maxR = that.row,
maxC = that.column,
first,
movehandler = function () {
if (that.sheSheng.length >= maxLen) { that.level++;
that.drawMap();
return;
}
var first, last = that.sheSheng[that.sheSheng.length - 1], r = 0, c = 0;
if (that.direction == 39) {
r = last.r;
c = last.c + 1;
} else if (that.direction == 38) {
r = last.r - 1;
c = last.c;
} else if (that.direction == 37) {
r = last.r;
c = last.c - 1;
} else if (that.direction == 40) {
r = last.r + 1;
c = last.c;
}
if (r < 0 || r >= maxR || c < 0 || c >= maxC) {
that.gameover = true;
that.drawTcs();
that.drawBody();
return;
}
else if (that.bodys[r][c].color == that.tcsOptions.zawColor) {
that.gameover = true;
that.drawTcs();
that.drawBody();
return;
} else if (that.bodys[r][c].color == that.tcsOptions.shiwuColor) {
that.swCount--;
if (that.swCount == 0) {
that.createSW(that.level);
}
} else {
first = that.sheSheng.shift()
that.bodys[first.r][first.c].color = "";
} that.sheSheng.push({ r: r, c: c }); that.drawTcs();
that.drawBody();
that.movecomplete = false;
setTimeout(movehandler, that.speed - speed * that.sheSheng.length);
},
gameTime = setTimeout(movehandler, that.speed - speed * that.sheSheng.length);
},
createSW: function (count) {
this.swCount = 0;
var maxR = this.row,
maxC = this.column, r = 0, c = 0;
do {
r = Math.floor(Math.random() * maxR);
c = Math.floor(Math.random() * maxC);
if (this.bodys[r][c].color != "") {
count++;
} else {
this.bodys[r][c].color = this.tcsOptions.shiwuColor; }
this.swCount++;
} while (--count); }, init: function () {
var that = this; document.addEventListener("keydown", function (e) {
if (that.gameover == true) {
return;
}
if (!that.isStartGame) {
that.isStartGame = true;
that.startGame();
}
if (that.movecomplete) {
return;
}
var keycode = e.which || e.keyCode;
if (keycode >= 37 && keycode <= 40) {
that.movecomplete = true;
if (that.direction == 39 && keycode == 37 || that.direction == 38 && keycode == 40 || that.direction == 40 && keycode == 38 || that.direction == 37 && keycode == 39) {
return;
}
that.direction = keycode;
} }); }
}; var t = new tcs("canvasTCS");
</script> <style>
.aa {
color: #f4f;
}
</style>
</body> </html>

3、

<!doctype html>
<html>
<body>
<canvas id="can" width="400" height="400" style="background: Black"></canvas>
<script>
var sn = [ 42, 41 ], dz = 43, fx = 1, n, ctx = document.getElementById("can").getContext("2d");
function draw(t, c) {
ctx.fillStyle = c;
ctx.fillRect(t % 20 * 20 + 1, ~~(t / 20) * 20 + 1, 18, 18);
}
document.onkeydown = function(e) {
fx = sn[1] - sn[0] == (n = [ -1, -20, 1, 20 ][(e || event).keyCode - 37] || fx) ? fx : n
};
!function() {
sn.unshift(n = sn[0] + fx);
if (sn.indexOf(n, 1) > 0 || n<0||n>399 || fx == 1 && n % 20 == 0 || fx == -1 && n % 20 == 19)
return alert("GAME OVER");
draw(n, "Lime");
if (n == dz) {
while (sn.indexOf(dz = ~~(Math.random() * 400)) >= 0);
draw(dz, "Yellow");
} else
draw(sn.pop(), "Black");
setTimeout(arguments.callee, 130);
}();
</script>
</body>
</html>

4、

<!Doctype html>
<html>
<head>
<title>贪吃蛇小游戏</title>
<meta http-equiv="content-Type" content="text/html;charset=gbk" />
<meta http-equiv="Window-target" content="_top" />
<meta http-equiv="progma" content="no-cache" />
<meta name="description" content="js实现的简单贪吃蛇游戏" />
<meta name="author" content="成兮" /> <style>
canvas{border:1px solid grey;}
</style> <script> </script>
</head> <body>
<canvas id="mycanvas" width="400" height="400"></canvas>
</body>
<script>
window.onload = function(){
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext('2d');
//设置蛇移动的频率
var snake_speed = 200;
var interval = window.setInterval(snake_leave,snake_speed);
//设置移动的方向0-3上下左右
var direction = 3;
//保存贪吃蛇的实际长度
var snakelen = 20;
//保存移动的路径,元素为{'x':x,'y':y}格式
var map = [];
//蛇身单元大小
var size = 8;
//食物坐标:(a*8,a*8)
var a = 0;
//贪吃蛇每次的蛇头坐标
var x = 8;
var y = 8; //贪吃蛇移动函数
function snake_leave(){
//根据移动方向来移动
switch(direction){
case 0:y -= size;
break;
case 1:y += size;
break;
case 2:x -= size;
break;
case 3:x += size;
break;
}
//判断是否撞墙
if(x > 400 || y > 400 || x < 0 || y < 0){
alert("你撞墙死了");
window.clearInterval(interval);
}
//判断是否撞到自己
for(var i=0; i<map.length; i++){
var xx = parseInt(map[i].x);
var yy = parseInt(map[i].y);
if(xx == x && yy == y){
alert("你撞自己死了");
window.clearInterval(interval);
}
}
//每次移动一下,蛇身最后都要减去1
if(map.length > snakelen){
//把数组的第一个元素删除并返回,map中的数据为{key:value}形式
var foot = map.shift();
context.clearRect(foot['x'],foot['y'],size,size);
}
//判断是否吃到了食物
if(x == a*8 && y == a*8){
snakelen++;
snake_food();
}
//每次移动,进行蛇头的改变
map.push({'x':x,'y':y});
context.fillStyle = "#069";
context.strokeStyle = "#069";
context.fillRect(x,y,size,size);
}; //添加方向键键盘控制事件
document.onkeydown = function(event){
var code = event.keyCode;
switch(code){
case 37:if(direction != 3) direction = 2;
break;
case 38:if(direction != 1) direction = 0;
break;
case 39:if(direction != 2) direction = 3;
break;
case 40:if(direction != 0) direction = 1;
break;
}
}; //产生食物坐标的随机数来生成食物
function snake_food(){
a = Math.ceil(Math.random() * 50);
context.fillStyle = "#000";
context.strokeStyle = "#000";
context.fillRect(a*8,a*8,8,8);
};
snake_food();
};
</script>
</html>