没有HTML代码,全程有JS写
有些代码有注释,助于理解
贪吃蛇游戏:主要三部分
- 地图
- 随机生成食物
- 蛇及身体创建
3.1-蛇的移动
3.2-蛇的吃食物
3.3-蛇的死亡
<!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>Document</title>
</head>
<style>
/*{
margin: 0;
padding: 0;
}
.mark{
width: 810px;
height: 510px;
background-color: #ccc;
position: absolute;
left: 0;
top: 0;
z-index: 3;
display: none;
}
.mark button{
z-index: 4;
background-color: #ccc;
border: 1px solid #fff;
} */
</style>
<body>
<!-- <div class="mark">
<p></p>
<button>开始游戏</button>
<button>重新开始</button>
<button>结束游戏</button>
</div> -->
</body>
<script>
//设置样式
function setStyle(ele,styleObj){
for(var attr in styleObj){
ele.style[attr] = styleObj[attr]
}
}
//随机数
function getRandom(a,b){
var max = a
var min = b
if(a<b){
max = b
min = a
}
return parseInt(Math.random()*(max-min)+min)
}
//随机颜色
function getColor(){
return `rgb(${getRandom(0,256)},${getRandom(0,256)},${getRandom(0,256)})`
}
//创建地图
function Map(){
//地图div
this.box = document.createElement('div')
//地图设置样式
setStyle(this.box,{
width:'800px',
height:'500px',
backgroundColor:'transparent',
border:'5px solid #000',
position:'relative',
overflow:'hidden'
})
//添加到body中
document.querySelector('body').appendChild(this.box)
}
var map = new Map()
//创建食物 - 地图上随机出现食物 - 食物位置有left,top决定
function Food(){
//创建食物div
this.fooddiv = document.createElement('div')
//随机left,top值 - 食物的坐标
this.foodleft = Math.floor(getRandom(0,map.box.clientWidth-10)/10)*10
this.foodtop = Math.floor(getRandom(0,map.box.clientHeight-10)/10)*10
//给食物设置样式
setStyle(this.fooddiv,{
width:'10px',
height:'10px',
//食物颜色 - 随机
backgroundColor:getColor(),
position:'absolute',
left: this.foodleft +'px',
top: this.foodtop +'px',
borderRadius:'50%'
})
//添加到地图div中
map.box.appendChild(this.fooddiv)
}
var food = new Food();
//蛇
function Snake(){
//蛇的身体 - 及坐标
//初始蛇的身体是3个div组成,div的位置由left(x),top(y)来设置,数组存储 比如:
//尾部:x:0 y:0 中间:x:10 y:0 头部:x:20 y:0 - 蛇身体的div坐标
this.body = [
//尾部
{
x:0,
y:0
},
//中间
{
x:10,
y:0
},
//头部
{
x:20,
y:0
}
]
//循环创建身体的div
this.show()
//蛇运动的方向 - 初始蛇的方向为向右
this.direction = 'right'
//改变蛇的运动方向 - 键盘事件
document.onkeydown = e=>{
var e = e || window.event
//获取按下的键的阿斯克码
var keycode = e.keyCode || e.which
//将阿斯克码转换成字母,并同一转换小写字母
var word = String.fromCharCode(keycode).toLowerCase()
//判断按下的键,是什么方向
switch(word){
case 'a':
this.direction = 'left'
break;
case 'd':
this.direction = 'right'
break;
case 'w':
this.direction = 'top'
break;
case 's':
this.direction = 'bottom'
break;
}
}
//蛇的运动
this.timer = setInterval(()=>{
this.move()
},200)
//蛇一边运动一边吃食物,所以吃食物的方法在蛇运动的方法里调用
}
Snake.prototype.move = function(){
//蛇的运动,根据方向来运动
//具体怎么运动,就是前一节身体的坐标给后一节,而蛇头坐标另外给值
//依次替换蛇身体的坐标 - 蛇头单独设置坐标,故少循环一次
for(var i=0;i<this.body.length-1;i++){
this.body[i].x = this.body[i+1].x
this.body[i].y = this.body[i+1].y
}
//这里设置蛇头的坐标
switch(this.direction){
case 'left':
this.body[this.body.length-1].x -=10
break;
case 'right':
this.body[this.body.length-1].x +=10
break;
case 'top':
this.body[this.body.length-1].y -=10
break;
case 'bottom':
this.body[this.body.length-1].y +=10
break;
}
//从新显示蛇的身体
this.show()
//吃食物
this.eat()
//蛇撞身体,地图边缘 - 死亡
this.die()
}
//死亡
Snake.prototype.die = function(){
//蛇撞在地图边缘死亡
if(
this.body[this.body.length-1].x<0||
this.body[this.body.length-1].y<0||
this.body[this.body.length-1].x>map.box.clientWidth-10||
this.body[this.body.length-1].y>map.box.clientHeight-10
){
//死亡,就停下定时器
clearInterval(this.timer)
}
//蛇撞在自己身上死亡 - 比较的就是坐标相同
for(var i=0;i<this.body.length-1;i++){
if(this.body[this.body.length-1].x === this.body[i].x && this.body[this.body.length-1].y === this.body[i].y){
//死亡,就停下定时器
clearInterval(this.timer)
//结束循环
break;
}
}
}
//吃食物方法
Snake.prototype.eat = function(){
//当食物的坐标与蛇头的坐标吻合,就吃到食物了
if(this.body[this.body.length-1].x === food.foodleft && this.body[this.body.length-1].y === food.foodtop){
//条件成立,食物吃到了,蛇的身体加1,食物消失,食物从新创建
//蛇的身体加1
//首先,把身体尾部的坐标复制一份,添加到身体坐标数组里的开头,当蛇运动时,坐标就会被替换
var obj = {
x:this.body[0].x,
y:this.body[0].y
}
this.body.unshift(obj)
//食物消失 - 从地图中删除食物这个div
map.box.removeChild(food.fooddiv)
//食物从新创建
food = new Food();
}
}
Snake.prototype.show = function(){
//创建身体之前,先清除之前的身体
//怎么清除 - 先获取到蛇的身体,如果地图上有蛇身体就获取得到,没有的话就为null
var snakes = map.box.querySelectorAll('.snake')
//判断长度不为0时候,就表示地图有身体,那就清除
if(snakes.length){
//怎么删除,遍历身体,得到每节身体,在把每节身体删除
for(var i=0;i<snakes.length;i++){
map.box.removeChild(snakes[i])
}
}
//循环this.body,创建相应的div - 蛇的身体
for(var i=0;i<this.body.length;i++){
var div = document.createElement('div')
//设置样式,并给坐标x,y给div
setStyle(div,{
width:'10px',
height:'10px',
backgroundColor:getColor(),
position:'absolute',
left: this.body[i].x +'px',
top: this.body[i].y +'px'
})
//给蛇头设置不一样 的样式
//当i === 数组最后一个下标 , 此时的div就是蛇头
if(i === this.body.length-1){
setStyle(div,{
borderRadius: '50%',
backgroundColor:'black'
})
}
//给蛇的身体的设置标记 - 代表这是蛇,不是食物,因为地图中只有蛇和食物
div.className = 'snake'
//添加到地图div中
map.box.appendChild(div)
}
}
var snake = new Snake()
</script>
</html>