游戏区域限制在一个ul里,蛇的每一节是有一个个li组成,每个li都用position定位。食物是创建的一个div,每次蛇头碰触食物时,创建一个新的li,li会自动加载蛇的尾部,然后通过随机数改变食物的位置。通过响应键盘的wasd控制蛇头的方向(用的是onkeypress事件和keyCode),用定时器控制蛇头自动走,用数组储存蛇头每次所走的top和left值,用循环把这些top和left值赋值给蛇头后面的li上,这样蛇身子就会随着蛇头动起来了。
效果图:
标注:红色的圆是食物,蛇头是黑色的。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>蛇头移动</title>
<style media="screen">
*{
padding: 0px;
margin: 0px;
}
ul{
height: 800px;
width: 800px;
background-color: darkgreen;
position: relative;
list-style: none;
margin: 15px auto;
text-align: right;
color: white;
font-size: 2em;
padding: 10px 10px;
}
ul li{
height: 100px;
width: 100px;
border-radius: 50%;
background-color: darkred;
position: absolute;
}
ul li:nth-child(1){
top: 20px;
left: 0;
background-color: black;
height: 111px;
width: 111px;
}
ul li:nth-child(2){
top: 10px;
left: 0;
background-color: white;
}
ul li:nth-child(3){
top: 0px;
left: 0;
}
div{
height: 100px;
width: 100px;
border-radius: 50%;
background-color: darkred;
position: absolute;
}
section{
width: 800px;
padding: 10px 0px;
border-radius: 30px;
background-color: rgba(200,17, 2,0.9);
margin: 1px auto;
text-align: center;
font-size: 33px;
border: 3px solid black;
box-shadow: 0 0 10px gray;
cursor: pointer;
color: white;
}
</style>
<script type="text/javascript">
window.onload=function(){
var ul=document.querySelector('ul');
var lis=document.getElementsByTagName('li');
var btn=document.getElementsByTagName('section')[0];
var timer;
//蛇头的top与left值
var top=lis[0].offsetTop;
var left=lis[0].offsetLeft;
var flag=true;
//存储蛇头的每一节的位置
var snakePosi=[{x:lis[1].offsetLeft,y:lis[1].offsetTop},{x:lis[0].offsetLeft,y:lis[0].offsetTop}];
//声明速度
var speedX=10;
var speedY=10;
var contrStarPau=false;
function keyContrMove(flag){
clearInterval(timer);
timer=setInterval(function(){
if (!contrStarPau) {
return;
}
if (flag) {
top+=speedY;
lis[0].style.top=top+'px';
}else {
left+=speedX;
lis[0].style.left=left+'px';
}
//将蛇头的位置存入数组,目的是把它的位置赋给它的下一节
snakePosi.push({x:left,y:top});
if (snakePosi.length>lis.length) {
snakePosi.shift();
}
for (var i =1; i<snakePosi.length; i++) {
lis[i].style.top=snakePosi[snakePosi.length-1-i].y+'px';
lis[i].style.left=snakePosi[snakePosi.length-1-i].x+'px';
}
if ((Math.abs(lis[0].offsetTop-div.offsetTop)<lis[0].offsetHeight && lis[0].offsetLeft==div.offsetLeft) || (Math.abs(lis[0].offsetLeft-div.offsetLeft)<lis[0].offsetWidth && lis[0].offsetTop==div.offsetTop)) {
div.style.top=randomNum()+'px';
div.style.left=randomNum()+'px';
createLi();
}
if (lis[2].offsetTop<0 || lis[2].offsetTop>(ul.offsetHeight-lis[2].offsetHeight) || lis[2].offsetLeft<0 || lis[2].offsetLeft>(ul.offsetWidth-lis[2].offsetWidth)) {
clearInterval(timer)
}
},33)
}
keyContrMove(true);
document.onkeypress=function(event){
event=event||window.event;
if (event.keyCode==119 && flag==false) {
if (speedY>0) {
speedY=-speedY;
}
flag=true;
keyContrMove(true);
}
if (event.keyCode==115 && flag==false) {
if (speedY<0) {
speedY=-speedY;
}
flag=true;
keyContrMove(true);
}
if (event.keyCode==97 && flag==true) {
if (speedX>0) {
speedX=-speedX;
}
flag=false;
keyContrMove(false);
}
if (event.keyCode==100 && flag==true) {
if (speedX<0) {
speedX=-speedX;
}
flag=false;
keyContrMove(false);
}
}
function randomNum(){
var a=parseInt(Math.random()*(700-10)+10)
return a=a-a%10;
}
function createLi(){
var li=document.createElement('li');
ul.appendChild(li);
}
function createDiv(){
var div=document.createElement('div');
div.style.top=randomNum()+'px';
div.style.left=randomNum()+'px';
ul.appendChild(div);
}
createDiv();
var div=document.getElementsByTagName('div')[0];
btn.onclick=function(){
contrStarPau=!contrStarPau;
console.log(contrStarPau);
}
}
</script>
</head>
<body>
<ul>
By Paul.SJ
<li></li>
<li></li>
<li></li>
</ul>
//按钮
<section>
?start? / ?pause?
</section>
</body>
</html>