代码如下(每一步都有详细的解释):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>贪吃蛇地图的 绘制</title>
<style>
*{
margin: 0;
padding: 0;
}
h1{
margin-left: 20px;
}
#bts{
margin-left: 20px;
}
button{
font-size: 20px;
}
#map{
width: 500px;
height: 500px;
background-color: pink;
position: relative;
/* 给粉色背景色一个相对定位 */
}
td{
width: 48px;
height: 48px;
}
table{
position: absolute;
top: 67px;
left: 0px;
/* 给表格设置一个绝对定位,相对定位到粉色的背景色上 */
}
</style>
</head>
<body>
<h1 id="Score">Score: 0</h1>
<div id="bts">
<button id="bt1">快</button>
<button id="bt2">中</button>
<button id="bt3">慢</button>
</div>
<div id="map"></div>
<script>
// 利用for循环创建一个10*10的表格
document.write("<table border='1' cellspacing='0'>")
for(var n=0;n<10;n++){
document.write("<tr>")
for(var j=0;j<10;j++){
document.write("<td></td>")
}
document.write("</tr>")
}
document.write("</table>")
// // 蛇头的随机生成
// var head=document.createElement("div")
// head.style.width="50px"
// head.style.height="50px"
// head.style.backgroundColor="red"
// head.style.position="absolute"
// head.style.top=parseInt(Math.random()*10)*50+"px"
// head.style.left=parseInt(Math.random()*10)*50+"px"
// //使用随机数的概念来 随机产生对应的位置
// //Math.random() 0-1随机数 小数
// //发现left和top必须为50的整数倍 ,0-9
// //产生一个0-9随机数,*50
// //Math.random() 0-1*10 0-10随机数 parseInt()
// var map=document.getElementById("map")
// map.appendChild(head)
// // 食物的随机生成
// var food=document.createElement("div")
// food.style.width="50px"
// food.style.height="50px"
// food.style.backgroundColor="blue"
// food.style.position="absolute"
// food.style.top=parseInt(Math.random()*10)*50+"px"
// food.style.left=parseInt(Math.random()*10)*50+"px"
// map.appendChild(food)
//将这个蛇头和食物的随机生成封装成函数
function createDiv(Color){
// 创建一个div标签并放到div这个变量里
var div=document.createElement("div")
// 创建的这个标签宽度为50px,高度50px
div.style.width="50px"
div.style.height="50px"
// 设置新创建的这个div的颜色
div.style.backgroundColor=Color
// 给这个新创建的元素一个绝对定位,以body为圆点设置
div.style.position="absolute"
// 每次刷新,蛇头和食物都会随机出现在地图上
div.style.top=parseInt(Math.random()*10)*50+"px"
div.style.left=parseInt(Math.random()*10)*50+"px"
// 找到map,并在map里创建新的div
var map=document.getElementById("map")
map.appendChild(div)
// 返回div,就可以在函数外部调用了
// 通过变量来使用,当前对应的div标签
return div
}
// 蛇头调用这个函数,并且背景色设置为红色
var head=createDiv("red")
// 食物调用这个函数,并且背景色设置为蓝色
var food=createDiv("blue")
// 将蛇头默认移动的方向设置为向上移动
head.direction="上"
// 找到这三个启动按钮
// 快
var bt1=document.getElementById("bt1")
// 中
var bt2=document.getElementById("bt2")
//慢
var bt3=document.getElementById("bt3")
// 给这三个按钮添加事件
var t
bt1.onclick=function(){
window.t=setInterval(function(){
move()
},200)
}
bt2.onclick=function(){
window.t=setInterval(function(){
move()
},500)
}
bt3.onclick=function(){
window.t=setInterval(function(){
move()
},700)
}
var bodyNodes=[] // var一个空数组用来放置,生成的身体
var s=0 //用来计算分数
// 启动自动移动的定时器中的内容
function move(){
switch(head.direction){
case "左":
var t=parseInt(head.style.left)
head.style.left=t-50+"px"
break
case "右":
var t=parseInt(head.style.left)
head.style.left=t+50+"px"
break
case "上":
var t=parseInt(head.style.top)
head.style.top=t-50+"px"
break
case "下":
var t=parseInt(head.style.top)
head.style.top=t+50+"px"
break
}
// 身体的移动,永远跟随前一块移动
// 身体有长度,才可以控制他的移动
if(bodyNodes.length>0){
// 因为bodyNodes这个数组没有最后一个元素所以拿不到bodyNodes[n]
// 因为length长度是1 索引值又从零开始 没有这个1 所以需要bodyNodes.length-1
for(var n=bodyNodes.length-1;n>=0;n--){
// 检查报错
// console.log(n)
// console.log(bodyNodes[n])
// 碰撞检测,检测蛇头有没有碰撞到身体,如果碰撞到身体,就游戏结束,终止定时器
if(bodyNodes[n].style.left==head.style.left&&bodyNodes[n].style.top==head.style.top){
alert("咬到本座的尾巴了,你是🐖吗?")
clearInterval(window.t)
}
switch(bodyNodes[n].direction){
case "左":
var t=parseInt(bodyNodes[n].style.left)
bodyNodes[n].style.left=t-50+"px"
break
case "右":
var t=parseInt(bodyNodes[n].style.left)
bodyNodes[n].style.left=t+50+"px"
break
case "上":
var t=parseInt(bodyNodes[n].style.top)
bodyNodes[n].style.top=t-50+"px"
break
case "下":
var t=parseInt(bodyNodes[n].style.top)
bodyNodes[n].style.top=t+50+"px"
break
}
// 判断当前的是不是生成的第一块身体,如果是,跟随蛇头的移动方向移动
// 其他的身体跟随前一块移动
if(n==0){
bodyNodes[n].direction=head.direction
}else{
bodyNodes[n].direction=bodyNodes[n-1].direction
}
}
}
// 食物碰撞检测
if(head.style.left==food.style.left&&head.style.top==food.style.top){
console.log("碰撞成功")
// 蛇头每吃一块食物,产生一个黄色的身体,在蛇头的后方
// 身体更在最后一块后边,明确谁是最后一块,操作每一块身体
var body=createDiv("yellow")
// 蛇头每吃一个食物就生成一个身体
// 目前产生的身体位置是随机的,要求是跟在最后一块的后边移动
// 数组中最后一个内容,数组中如果是空,蛇头就是最后一块内容
var lastNode //var 一个新变量,表示最后一块
if(bodyNodes.length==0){
// 蛇头是最后一块
lastNode=head
}else{
// 因为要跟在最后一块后边移动,所以需要bodyNodes中的数组长度-1
lastNode=bodyNodes[bodyNodes.length-1]
}
// body的位置,要根据最后一块的移动方向来决定的,
// 在最后一块移动方向的后边创建新的身体.
switch(lastNode.direction){
// 当最后一块的移动方向为上,下的时
// 新生成的身体左,右保持一致
// 在移动方向的相反方向生成身体(如果在相同方向,直接咬死自己)
case "上":
body.style.left=lastNode.style.left
body.style.top=parseInt(lastNode.style.top)+50+"px"
break
case "下":
body.style.left=lastNode.style.left
body.style.top=parseInt(lastNode.style.top)-50+"px"
break
// 当最后一块的移动方向为左,右时
// 新生成的身体上,下保持一致
//在移动方向的相反方向生成身体(如果在相同方向,直接咬死自己)
case "左":
body.style.top=lastNode.style.top
body.style.left=parseInt(lastNode.style.left)+50+"px"
break
case "右":
body.style.top=lastNode.style.top
body.style.left=parseInt(lastNode.style.left)-50+"px"
break
}
// 新产生的身体 移动方向,和最后一块的移动方向保持一致
body.direction=lastNode.direction
//将新产生的身体放入数组中
bodyNodes.push(body)
console.log(body)
//食物的位置随之更新
food.style.top=parseInt(Math.random()*10)*50+"px"
food.style.left=parseInt(Math.random()*10)*50+"px"
// 计算分数,每吃一个食物,分数加10
// 用id找到这个分数
var Score=document.getElementById("Score")
s=s+10
Score.innerHTML="Score:"+s
}
if(parseInt(head.style.top)>=500||parseInt(head.style.top)<0||parseInt(head.style.left)>=500||parseInt(head.style.left)<0){
console.log("撞墙死亡")
clearInterval(window.t)
alert("撞到本座的头了,你眼瞎吗?")
}
}
// 按键控制div移动
document.onkeydown=function(event){
var e = event || window.event
console.log(e.keyCode)
switch(e.keyCode){
case 38:
head.direction="上"
break
case 40:
head.direction="下"
break
case 37:
head.direction="左"
break
case 39:
head.direction="右"
break
}
}
</script>
</body>
</html>