面向对象贪吃蛇

这篇博客介绍了一个使用JavaScript实现的HTML5贪吃蛇游戏。游戏中包括地图创建、随机食物生成、蛇的移动、吃食物和死亡检测等功能。通过键盘事件控制蛇的移动,当蛇碰到地图边缘或自身时游戏结束。此外,蛇吃到食物会增长身体长度。
摘要由CSDN通过智能技术生成

没有HTML代码,全程有JS写
有些代码有注释,助于理解
贪吃蛇游戏:主要三部分

  1. 地图
  2. 随机生成食物
  3. 蛇及身体创建
    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>



利用面向对象的方法,实现贪吃蛇。 1. 利用面向对象的思想实现——一个食物对象、一个蛇对象、一个游戏总控对象。 2. 在使用××.prototype= {}重写原型对象的时候,一定要加上一句constructor:该对象。不然会造成实例化出来的实例的constructor为object。 3. 在underscore中,使用_.random(a,b)即可获得a-b中的一个随机数。 4. 在求食物的随机位置的时候,用到了panel.clientHeight/this.height - 1) * this.height。 原理是使用盒子的高度/小球的高度,可以算得最多放多少个小球。因为要控制小球不能超过边界,所以总数量要减去1,数量×高度即为随机位置的最大值。 5. 在蛇对象中,用body数组存放蛇身体每一个部分对象。蛇的绘制过程就是遍历body,在面板上绘制。 6. 蛇的移动分为两部分。 ① 蛇节移动到前一个蛇节的位置。直到蛇头后一个蛇节移动到蛇头的位置。 ② 根据direction判断蛇头如何移动。 注意:在游戏绘制的过程中,界面的每一次绘制都要**删除**之前的绘制,不然会叠加到一起。 7. 在蛇的闭包中建一个局部数组,存储蛇对象,可以更加方便的删除操作。 8. 只有在原型对象中的方法和属性,外界是可以调用的。 9. 蛇的移动(动画)必然需要定时器协助。定时器的时间,即象征着刷新速度,也就是难度。 10. this所在的函数在哪一个对象中,this就指向谁。单独写一个函数的时候,如果调用之前对象的this,需要备份指针(将对象的this赋值给另一个变量)。 11. JavaScript原生的键盘按下事件(keydown) 中,事件有一个keyCode属性,其值代表按下的键。其中:37—left、38—top、39—right、40—bottom。 12. 边界控制。通过判断蛇头与最大X和Y的关系,判断是否碰到边界。 13. confirm()方法用于显示一个带有指定消息和确认及取消按钮的对话框。 14. window.location.reload(); 重新加载当前文档 15. window.close() 方法用于关闭浏览器窗口。 16. 与食物的碰撞检测:如果蛇头和食物坐标重叠,将蛇尾添加到body中。并重新绘制一个食物点,将之前的食物删掉。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

F2E_YoverL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值