小游戏目录结构
游戏运行效果图
HTML代码
css代码
js代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style media="screen">
*{
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;
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;">
得分:<span id="score" style="color: black;">0</span>
</p>
<input id="Pause" type="button" name="name" value="暂停" />
<input id="Start" type="button" name="name" value="开始" />
<input id="Refresh" type="button" name="name" value="重开" />
<input id="Speed" type="button" name="name" value="等级" />
<div id="snake_map"></div><!-- 25行 20列-->
</div>
<script type="text/javascript">
var score=document.getElementById('score');//获取分数id
var map=document.getElementById('snake_map');//获取路径地图id
var rowNumber=25;//行数
var columnNumber=20;//列数
var mapWidth=columnNumber*20+'px';//地图宽
var mapHeight=rowNumber*20+'px';//地图高
map.style.width=mapWidth;
map.style.height=mapHeight;//设置地图宽高
var snakeDIVPosition=[];//创建一个二维数组,用来记录地图的所有div的位置
for(var i=0;i<rowNumber;i++){//通过双层for循环创建地图元素
var rowDIV=document.createElement('div');//创建div
rowDIV.className='row';//设置div样式
map.appendChild(rowDIV);//将行div添加到路径地图map中
var rowArray=[];
for(var j=0;j<columnNumber;j++){
//创建每一行中的方块div
var columnDIV=document.createElement('div');
//设置css样式
columnDIV.className='col';
//将方块div添加到路径地图的map中
rowDIV.appendChild(columnDIV);
//创建一个行级数组,用来存储当前行中的每个方块div
rowArray.push(columnDIV);
}
snakeDIVPosition.push(rowArray);
}
var snake=[];
for(var i=0;i<3;i++){
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(e){
if(!changeDir){
return;
}
e=e||window.e;
if(direction=='right' && e.keyCode==37){
return;
}
if(direction=='left' && e.keyCode==39){
return;
}
if(direction=='up' && e.keyCode==40){
return;
}
if(direction=='down' && e.keyCode==38){
return;
}
switch (e.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++){
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';
snake.shift();
snakeDIVPosition[y][x].className='col activeSnake';
snake.push(snakeDIVPosition[y][x]);
}
}
var moveTimer=setInterval('snakeMove()',300);
function random(min,max){
return Math.floor(Math.random()*(max-min+1)+min);
}
function createNewEgg(){
eggX=random(0,columnNumber-1);
eggY=random(0,rowNumber-1);
if(snakeDIVPosition[eggY][eggX].className=='col activeSnake'){
createNewEgg();
}else{
snakeDIVPosition[eggY][eggX].className='col egg';
}
}
createNewEgg();
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>
</body>
</html>
*{
padding:0; margin:0;
}
html,body{
width:100%;
height:100%;
}
body{
position:relative;
}
div#container{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
margin:auto;
width:800px;
height:500px;
border:1px solid black;
font-size:0px;
}
span{
display:inline-block;
border:1px solid black;
box-sizing:border-box;
}
span.snake{
position:absolute;
background-color:red;
}
span.food{
position:absolute;
background-color:blue;
}
var box={width:50,height:50};//每一个方块的高度
var snake=[];//保存蛇每一节身体对应的span
var DIR={
DIR_RIGHT:1,
DIR_LEFT:2,
DIR_TOP:3,
DIR_BOTTOM:4
};
var dir=DIR.DIR_BOTTOM;
var food=null; //始终记录当前的食物
window.onload=function(){
//1.初始化地图
initMap();
//2.创建蛇
//2.5随机显示食物
showFood();
createSnake();
//3.让蛇动起来
setInterval(snakeMove,100);
//4.控制蛇移动
document.onkeyup=function(e){
switch(e.keyCode){
case 37:dir=DIR.DIR_LEFT;break;
case 38:dir=DIR.DIR_TOP;break;
case 39:dir=DIR.DIR_RIGHT;break;
case 40:dir=DIR.DIR_BOTTOM;break;
}
}
};
function isInSnakeBody(left,top){
for(var i=0;i<snake.length;i++){
if(snake[i].offsetTop==top&&snake[i].offsetLeft==left){
return true;
}
}
}
//这种随机生成食物的方法效率低---随着蛇身体的增长,随机生成食物的时间会变慢。
function showFood(){
var con=document.getElementById("container");
food=document.createElement("span");
food.className="food";
food.style.width=box.width+"px";
food.style.height=box.height+"px";
var left,top;
do{
left=Math.floor((con.offsetWidth-2)/box.width*Math.random())*box.width;
top=Math.floor((con.offsetHeight-2)/box.height*Math.random())*box.height;
}while(isInSnakeBody(left,top));
food.style.left=left+"px";
food.style.top=top+"px";
con.appendChild(food);
}
function initMap(){
var con=document.getElementById("container");
var row=Math.floor(con.offsetWidth/box.width);
var rol=Math.floor(con.offsetHeight/box.height);
var num=row*rol;
var newSpan=null;
for(var i=1;i<=num;i++){
newSpan=document.createElement("span");
newSpan.style.width=box.width+"px";
newSpan.style.height=box.height+"px";
con.appendChild(newSpan);
}
}
function createSnake(){
var newBody=null;
var con=document.getElementById("container");
for(var i=1;i<=5;i++){
newBody=document.createElement("span");
newBody.style.width=box.width+"px";
newBody.style.height=box.height+"px";
newBody.style.left=(i-1)*box.width+"px";
newBody.style.top="0px";
newBody.className="snake";
con.appendChild(newBody);
snake.push(newBody);
}
}
function snakeMove(){
var con=document.getElementById("container");
//蛇头移动
var head=snake[snake.length-1];
var newTop=head.offsetTop,newLeft=head.offsetLeft;
switch(dir){
case DIR.DIR_LEFT:newLeft-=box.width; break;
case DIR.DIR_RIGHT:newLeft+=box.width; break;
case DIR.DIR_TOP:newTop-=box.height; break;
case DIR.DIR_BOTTOM:newTop+=box.height; break;
default:break;
}
//如果超出边界,计算蛇头下一个位置的坐标
if(newLeft>con.offsetWidth-2-1){newLeft=0;}
if(newLeft<0){newLeft=con.offsetWidth-2-box.width;}
if(newTop<0){newTop=con.offsetHeight-2-box.height;}
if(newTop>con.offsetHeight-2-1){newTop=0;}
//判断新蛇头的位置是不是在蛇身体里面
//for(var i=0;i<snake.length-1;i++){
// if(snake[i].offsetLeft==newLeft&&snake[i].offsetTop==newTop){
// alert("Game over!!");
// window.location.href=window.location.href;
// }
//}
//1.如果吃到食物
if(newLeft==food.offsetLeft&&newTop==food.offsetTop){
food.className="snake";
snake.push(food);
showFood();
return;
}
//2.如果没吃到
//除蛇头外身体移动
for(var i=0;i<snake.length-1;i++){
snake[i].style.top=snake[i+1].offsetTop+"px";
snake[i].style.left=snake[i+1].offsetLeft+"px";
}
head.style.left=newLeft+"px";
head.style.top=newTop=newTop+"px";
}