前端关于JS实现贪吃蛇

这个贪吃蛇我是用面向对象做的,有关于面向对象知识的请看我另一篇文章
先看效果

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

完整代码

css代码:

<style>
        *{margin: 0;padding: 0;}
        .map{
            width: 500px;
            height: 500px;
            background: pink;
            border: 5px solid #000;
            margin: 100px auto;
            position: relative;
        }
        body>p{
            position: absolute;
            top: 50px;
            left: 1000px;
            font-size: 30px;
        }
        .start{
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            width: 200px;
            height: 100px;
            font-size: 30px;
            display: none;
        }
        .end{
            margin: 100px;
            width: 300px;
            height: 300px;
            font-size: 30px;
            background: yellow;
            display: none;
            overflow: hidden;
        }
        .end p{
            margin:30px 0 30px 50%;
            transform: translateX(-50%);
        }
        .ok{
            width: 100px;
            height: 50px;
            font-size: 20px;
            margin: 30px 90px;
        }
    </style>

html代码:

<body>
    <div class="map">
        <button class="start">开始游戏</button>
        <div class="end">
            <p>游戏结束</p>
            <p>得分:<span></span></p>
            <button class="ok">确认</button>
        </div>
    </div>
    <p>分数:<span>0</span></p>
</body>

js代码:

<script>
function game() {
    this.map=document.querySelector('.map')
    this.span=document.querySelector('body>p>span')
    this.span1=document.querySelector('.end span')
    this.start=document.querySelector('.start')
    this.end=document.querySelector('.end')
    this.ok=document.querySelector('.ok')
    var that=this
    //地图的宽高
    this.mpcw=this.map.clientWidth   //不带边框
    this.mpch=this.map.clientHeight  //不带边框
    //点击方向键改变方向
    document.onkeydown=function(e){
        var cod=e.keyCode
        //w:87 a:65 s:83 d:68    ↑:38 ←:37 ↓:40 →:39
        if(cod==87 || cod==38 ){
            if(that.fx!='down'){
                that.fx='up'
            }
        }else if(cod==65 ||cod==37){
            if(that.fx!='right'){
                that.fx='left'
            }
        }else if(cod==83 || cod==40){
            if(that.fx!='up'){
                that.fx='down'
            }
        }else if(cod==68 || cod==39){
            if(that.fx!='left'){
                that.fx='right'
            }
        }
    }
    //开始游戏
    this.sta()
    //游戏结束
    this.ok.onclick=function(){
        that.en()
    }
}
//开始游戏
game.prototype.sta=function(){
    //初始化蛇
    this.reset()
    this.bd=[]
    var that=this
    this.start.style.display='block'
    this.start.onclick=function(){
        that.start.style.display='none'
        //创建食物
        that.food()
        //创建蛇
        that.snake()
        //蛇的移动
        that.timer=setInterval(()=>{
            that.fun()
        },70)
    }
}
//初始化
game.prototype.reset=function(){
    this.arr=[
        {x:this.mpcw/2, y:this.mpch/2},
        {x:this.mpcw/2, y:this.mpch/2+10},
        {x:this.mpcw/2, y:this.mpch/2+20},
    ]
    this.fx='up'
    this.timer=null
    //分数
    this.sp=0
    this.span.innerText=this.sp
}
//设置样式
game.prototype.setStyle= function (elm,obj) {
    for(var attr in obj){
        elm.style[attr]=obj[attr];
    }
}
//获取随机数
game.prototype.getRandom= function (a,b) {
    var max=Math.max(a,b)
    var min=Math.min(a,b)
    return Math.round(Math.random()*(max-min)+min)
}
//创建食物
game.prototype.food=function(){
    this.l=Math.round(this.getRandom(0,this.mpcw-10)/10)*10
    this.t=Math.round(this.getRandom(0,this.mpch-10)/10)*10
    this.fd=document.createElement('div')
    this.setStyle(this.fd,{
        width:'10px',
        height:'10px',
        borderRadius:'50%',
        background:'green',
        position:'absolute',
        left:this.l+'px',
        top:this.t+'px',
    })
    this.map.appendChild(this.fd)
}
//创建蛇
game.prototype.snake=function(){
    if(this.bd.length!=0){
        for(var i=0;i<this.bd.length;i++){
            this.map.removeChild(this.bd[i])
        }
    this.bd=[]
    }
    for(var i=0;i<this.arr.length;i++){
        var div=document.createElement('div')
        this.setStyle(div,{
            width:'10px',
            height:'10px',
            borderRadius:'50%',
            background:'black',
            position:'absolute',
            left:this.arr[i].x+'px',
            top:this.arr[i].y+'px',
        })
        if(i==0){
            div.style.background='red'
        }
        this.map.appendChild(div)
        this.bd.push(div)
    }
}
//蛇的移动
game.prototype.fun=function(){
    for(var i=this.arr.length-1;i>0;i--){
        this.arr[i].x=this.arr[i-1].x
        this.arr[i].y=this.arr[i-1].y
    }
    switch(this.fx){
        case 'up':this.arr[0].y-=10;
            break;
        case 'down':this.arr[0].y+=10;
            break;
        case 'left':this.arr[0].x-=10;
            break;
        case 'right':this.arr[0].x+=10;
            break;
    }
    //位置变后重新创建蛇
    this.snake()
    //吃到食物
    this.eat()
    //死亡判断
    this.die()
}
//吃到食物
game.prototype.eat=function(){
    if(this.arr[0].x==this.l && this.arr[0].y==this.t){
        this.map.removeChild(this.fd)
        this.food()
        this.sp+=1
        this.span.innerText=this.sp
        this.arr.push({x:this.arr[this.arr.length-1].x, y:this.arr[this.arr.length-1].y})
    }
}
//死亡判断
game.prototype.die=function(){
    //撞墙
    if(this.arr[0].x<0 || this.arr[0].x>this.mpcw-this.fd.offsetWidth || this.arr[0].y<0 || this.arr[0].y>this.mpch-this.fd.offsetHeight){
        this.died()
    }
    //撞身体
    for(var i=1;i<this.arr.length;i++){
        if(this.arr[0].x==this.arr[i].x && this.arr[0].y==this.arr[i].y){
            this.died()
        }
    }
}
//死亡函数
game.prototype.died=function(){
    clearInterval(this.timer)
    this.end.style.display='block'
    this.span1.innerText=this.sp
    this.span1.style.color='red'
}
//游戏结束
game.prototype.en=function(){
    this.end.style.display='none'
    this.reset()
    this.map.removeChild(this.fd)
    this.start.style.display='block'
    for(var i=0;i<this.bd.length;i++){
        this.map.removeChild(this.bd[i])
    }
    this.bd=[]
}
var a=new game()
</script>

讲解一下这段代码

定义一个构造函数,然后new它

首先获取需要操作的标签
在两个不相关的函数之间不能互相访问局部变量,所以可以把变量添加为对象的属性
在这里插入图片描述
因为在事件函数里 this 指向的是事件源,所以要在外面定义一个变量that,将 this 赋值给 that ,然后在事件函数里就可以用 that 来进行相关操作

定义一个变量,根据按的方向键变为对应的值
还要判断不能掉头,如果是向左走就不能按右方向键
在这里插入图片描述
接下来实现各项功能,实现功能一般是给构造函数的原型添加方法,这样new出来的对象也可以调用,而且不会被其他全局变量覆盖

获取随机数和设置样式

首先添加一个获取随机数和设置样式的方法,为了后面写代码更方便
在这里插入图片描述

初始化

添加一个初始化的方法,蛇的位置,长度,方向还有分数等等
在这里插入图片描述

创建食物

食物是随机出现在地图上的,可以用到上面获取随机数和设置样式的方法,不能超出地图
在这里插入图片描述

创建蛇的身体

可以用初始化里的数组来创建身体,数组里面有几个对象身体就有几节,对象里放身体的坐标,初始化坐标在地图中间,代表蛇在地图中间出生

遍历数组创建身体
在这里插入图片描述

蛇的移动

蛇的移动就是改变身体的坐标,然后重新创建一个身体,并把之前的身体移除
将第二节身体的坐标给第三节,第一节的给第二节,第一节的坐标再加上一节身体的长度,就完成了移动
判断方向决定第一节的坐标变化
在这里插入图片描述
因为重新创建蛇后要移除上一条蛇,所以要在创建蛇的方法里改成先移除蛇,再创建蛇
在这里插入图片描述
然后给蛇的移动方法放进一个定时器里,每隔多久调用一次,这样就能“移动”了
在这里插入图片描述

吃到食物

吃到食物就是判断蛇头的坐标和食物坐标一样
吃到食物后,要移除食物,然后创建一个新的食物,并给创建身体的数组添加一个对象,坐标是蛇尾的坐标,这样下次创建身体就增加了一节
在这里插入图片描述

判断死亡

撞墙和撞身体会死,就是判断蛇头的坐标有没有超出地图,有没有和身体的坐标相同
在这里插入图片描述
死亡后要干什么也添加一个方法
要清除定时器等等
在这里插入图片描述
判断死亡条件成立就调用这个方法

因为吃食物和判断死亡都是在蛇的移动里的,所以把它们放进移动方法里去调用
在这里插入图片描述
这样各项功能就差不多完成了,然后定义一个点击开始按钮的方法,把这些功能放进去
在这里插入图片描述
然后点击游戏结束按钮也添加一个方法,打扫战场,移除蛇和食物,初始化什么的
在这里插入图片描述
在构造函数里面调用开始和结束就行了
在这里插入图片描述
点击方向键改变方向也可以定义成一个方法然后在这调用

然后代码整体就是这样
在这里插入图片描述
有不足的地方欢迎大佬指出来,一起交流交流!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值