<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>JS贪吃蛇游戏</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 482px;
margin: 0 auto;
}
.box .main {
float: left;
border: 1px solid #ccc;
}
.box .info {
line-height: 60px;
}
.box .info p {
float: left;
margin-right: 20px;
}
.main .row {
overflow: hidden;
}
.main .col,
.main .active {
float: left;
width: 20px;
height: 20px;
}
.main .active {
background: red;
}
</style>
<script>
// 模仿jquery获取元素
function $(selector, content) {
content = content || document;
var sTag = selector.charAt(),
arr = [],
allName = content.getElementsByTagName('*');
if (sTag === '#') {
selector = selector.substring(1);
// console.log(selector);
return content.getElementById(selector);
} else if (sTag === '.') {
selector = selector.substring(1);
for (var i = 0; i < allName.length; i++) {
var sstr = allName[i].className.indexOf(selector);
if (sstr != -1) {
arr.push(allName[i]);
};
};
// console.log(arr);
return arr;
} else {
return content.getElementsByTagName(selector);
};
}
window.onload = function() {
var oMap = $('#map');
oMap.innerHTML = '';
var nRow = 20, //行
nCol = 20, //列
g = 3, //蛇默认蛇身长度
x = 0, //蛇头在哪一行
y = g - 1, //蛇头在那一列
foodX = 0,
foodY = 0; //食物的x,y轴位置
// 蛇的长度
var aSnakes = new Array();
var timer = null;
var score = 0;
var speed = 200; //默认初始速度
// 添加地图布局
var AllCols = new Array();
for (var i = 0; i < nRow; i++) {
var row = document.createElement('div');
row.className = 'row';
var aRow = new Array();
for (var j = 0; j < nCol; j++) {
var col = document.createElement('div');
col.className = 'col';
row.appendChild(col)
aRow[j] = col; //添加col到数组中
};
// 把所有row的col 添加到数组中
AllCols[i] = aRow;
oMap.appendChild(row)
};
// 循环蛇长度
for (var k = 0; k < g; k++) {
AllCols[0][k].className = 'col active';
aSnakes[k] = AllCols[0][k];
};
// 第一个蛇隐藏
function firstHide(obj) {
obj[0].className = 'col';
}
// 最后一个蛇,往前挪动
function lastShow(obj) {
obj[obj.length - 1].className = 'col active';
}
// 控制键盘方向
var dir = 'right',
oldDir = dir;
var fa = false;
document.onkeydown = function(ev) {
var ev = ev || event;
// 保存上一个值
oldDir = dir;
dir = ev.keyCode;
// 排除所有非方向箭
if (dir>40 || dir<37) {
dir = oldDir;
};
// 排除相反方向,如果正在向下移动,按上则无效
if (dir == 38 && oldDir == 'bottom') {
dir = 'bottom';
} else if (dir == 39 && oldDir == 'left') {
dir = 'left'
} else if (dir == 40 && oldDir == 'top') {
dir = 'top'
} else if (dir == 37 && oldDir == 'right') {
dir = 'right'
};
// 正常行走
if (dir == 39) {
dir = 'right';
} else if (dir == 38) {
dir = 'top';
} else if (dir == 37) {
dir = 'left';
} else if (dir == 40) {
dir = 'bottom';
}
};
// 生成食物坐标
function food() {
foodX = Math.floor(Math.random() * nRow) //食物在哪一行
foodY = Math.floor(Math.random() * nCol) //食物在哪一列
// 排除在自己身上
if (AllCols[foodX][foodY].className == 'col active') {
food();
} else {
AllCols[foodX][foodY].className = 'col active';
};
};
food();
// 蛇吃到虫子新增长度
function addSnake() {
aSnakes[aSnakes.length] = AllCols[foodX][foodY];
g += 1;
score += 1;
if (speed == 100) {
speed -= 10
} else if (speed == 50) {
speed -= 5
} else {
speed -= 20;
};
document.getElementById('score').innerHTML = score;
food();
}
// 游戏结束
function gameOver() {
alert('游戏结束!');
clearTimeout(timer);
};
// 检测是否碰到自身
function checkMe(arr) {
var bflag = true;
for (var i = 0; i < aSnakes.length; i++) {
if (aSnakes[i] == arr) {
bflag = false;
};
};
return bflag;
};
// 游戏开始
function start() {
switch (dir) {
case 'left':
// 是否撞到墙
if (y - 1 >= 0) {
// 是否吃到自身
if (checkMe(AllCols[x][y - 1])) {
// 蛇尾隐藏
firstHide(aSnakes)
if (x == foodX && y - 1 == foodY) {
addSnake();
} else {
for (var i = 0; i < aSnakes.length - 1; i++) {
aSnakes[i] = aSnakes[i + 1]
};
aSnakes[g - 1] = AllCols[x][y - 1];
};
// 新蛇头显示
lastShow(aSnakes)
y -= 1;
timer = setTimeout(start, speed);
} else {
gameOver();
};
} else {
gameOver();
};
break;
case 'top':
// 是否撞到墙
if (x - 1 >= 0) {
// 是否吃到自身
if (checkMe(AllCols[x - 1][y])) {
// 蛇尾隐藏
firstHide(aSnakes)
if (x - 1 == foodX && y == foodY) {
addSnake();
} else {
for (var i = 0; i < aSnakes.length - 1; i++) {
aSnakes[i] = aSnakes[i + 1]
};
aSnakes[g - 1] = AllCols[x - 1][y];
};
// 新蛇头显示
lastShow(aSnakes)
x -= 1;
timer = setTimeout(start, speed);
} else {
gameOver();
};
} else {
gameOver();
};
break;
case 'right':
// 是否撞到墙
if (y + 1 < nCol) {
// 是否吃到自身
if (checkMe(AllCols[x][y + 1])) {
// 蛇尾隐藏
firstHide(aSnakes)
if (x == foodX && y + 1 == foodY) {
addSnake();
} else {
for (var i = 0; i < aSnakes.length - 1; i++) {
aSnakes[i] = aSnakes[i + 1]
};
aSnakes[g - 1] = AllCols[x][y + 1];
};
// 新蛇头显示
lastShow(aSnakes)
// aSnakes[g - 1] = AllCols[x][y-1]; //倒数第二个
// console.log(aSnakes[g - 1],AllCols[x][y - 1]);
y += 1;
timer = setTimeout(start, speed);
} else {
gameOver();
};
} else {
gameOver();
};
break;
case 'bottom':
// console.log(aSnakes[g - 1]);
// 是否撞到墙
if (x + 1 < nRow) {
// 是否吃到自身
if (checkMe(AllCols[x + 1][y])) {
// 蛇尾隐藏
firstHide(aSnakes)
if (x + 1 == foodX && y == foodY) {
addSnake();
} else {
for (var i = 0; i < aSnakes.length - 1; i++) {
aSnakes[i] = aSnakes[i + 1]
};
aSnakes[g - 1] = AllCols[x + 1][y];
};
// 新蛇头显示
lastShow(aSnakes)
x += 1;
timer = setTimeout(start, speed);
} else {
gameOver();
};
} else {
gameOver();
};
break;
}
// console.log(aSnakes);
}
var oStart = document.getElementById("start");
oStart.onclick = function() {
start();
};
};
</script>
</head>
<body>
<div class="box">
<h1>JS贪吃蛇游戏</h1>
<div class="info">
<p class="text">您的分数:<span id="score">0</span>分</p>
<p>按[上下左右]方向键吃虫</p>
<input id="start" type="button" value="开始游戏" />
</div>
<div class="main" id="map"></div>
</div>
</body>
</html>