资讯专栏INFORMATION COLUMN

小白成长日记:写个贪吃蛇

archieyang / 372人阅读

摘要:贪吃蛇并不是通过操作来完成移动的,而是通过记录贪吃蛇的路径来将身体渲染出来。目前没有内置的操作符判断对象的内容是否相同。

还是用的vue,本来以为不合适,但想法错了。贪吃蛇并不是通过操作dom来完成移动的,而是通过记录贪吃蛇的路径来将身体渲染出来。

一般移动元素,我们都是变动它的css达到目的,但我在写贪吃蛇的时候发现这样很难以实现,参考了网上的资源,发现大部分人是通过记录贪吃蛇的路径,保存进数组,通过数组变动来表示贪吃蛇的下一步,主要是增加头部位置,去除尾部位置,再动态添加css样式,这样就达到移动的效果。

演示

链接描述

html&&data:
data(){ return{ rows:"",//横框 cols:"",//竖框 position:[[0,0],[1,0],[2,0],[3,0]],//蛇的初始位置 direction:1,//方向 food:[]//食物的位置 } },
初始化准备
methods:{
    background(){//生成横框和竖框的函数
        this.rows=Array(30)
        this.cols=Array(30)
    }, 
    keyboard(){//键盘事件
        let _this = this;
        document.onkeydown = function(e){
            if(e.keyCode===37){
                _this.change(-1)
            }else if(e.keyCode===38){
                _this.change(-2)
            }else if(e.keyCode===39){
                _this.change(1)
            }else{
                _this.change(2)
            }
        }
    },
    creatfood(){//创造食物
        this.food[0]=Math.floor(Math.random()*30)
        this.food[1]=Math.floor(Math.random()*30)
    },
    showfood(x,y){//显示食物
        if(this.food[0]===x&&this.food[1]===y){
            return true
        }
    },
    body(x,y){//显示身体
        for(i=0;i

前期准备就是这么多,接下来就是跑起来,先声明一个计时器

let timer=""

接着就用定时器开始跑

start(){//开始按钮
    timer=setInterval(()=>this.autorun(),300)
}

这里的autorun就是我们要写的跑动函数

autorun(){                    
    let direction=this.direction//目前方向
    let headX,headY//
        headX=this.position[this.position.length-1][0]//复制蛇头的X坐标
        headY=this.position[this.position.length-1][1]//复制蛇头的Y坐标
        if(direction===1||direction===-1){//如果方向是在左右跑动                        
            direction>0?headX++:headX--//往右跑X坐标+1,往左跑X坐标-1                                        
        }else{
            direction>0?headY++:headY--//如果方向是在上下跑动,Y坐标做对应处理
        }
//此时蛇头的下一个坐标位置就是[headX,headY],接下来就可以判断是否结束游戏,如果结束了,蛇头就没必要添加了
        if(headX<0||headX>29||headY<0||headY>29||this.body(headX,headY)){//当蛇头下一个位置出了边界或者这个位置是符合身体函数(即蛇头撞上了身体)
            alert("Game Over")//结束
            clearInterval(timer)//清除定时器
            this.position=[[0,0],[1,0],[2,0],[3,0]]//还原身体
            this.creatfood()//重新创造食物
            this.direction=1//还原方向
        }else{//如果蛇头下一个位置是符合规则的                        
            this.position.push([headX,headY])//将下一个位置添加进数组,头部长一节
            if(headX!==this.food[0]||headY!==this.food[1]){//如果下一个头部位置不是食物的位置,即吃食物开始                            
                this.position.shift()//我们将尾部去掉,一长一短实现了蛇的走动
            }else{//如果下一个头部位置是食物
                this.creatfood()//不去除尾部,再次创建食物(这里有个小bug,随机的食物有几率与身体重合)
            }
        }                                    
},
change(dir){//改变方向
    if(Math.abs(dir)===Math.abs(this.direction)){//如果方向相同或者想法,不做任何操作
        return
    }else{
        this.direction=dir//否则把方向改动
    }
},

就是这个样子,贪吃蛇就写完了,逻辑方面并不是太复杂,但是对于数组的操作有很多,这里提下我碰见的几个问题:

vue中的数组对象在更新的时候和多带带的数据是不一样的,只有某些特定的函数会去主动更新数组,否则的话需要用vm.$set( target, key, value )这个去更新数组

二维数组和一维数组是不同的,indexOf()不管用,无法检测;而且类似this.position[0]===[0,0]也是无法正确判断的,这导致我在写这个小demo的时候犯了很多错。

let po=[[0,0],[1,0],[2,0],[3,0]]
let qo=[[0,0]]
let oo=[0,0]
console.log(po[0]==qo[0])//false
console.log(qo[0]==oo)//false

这大概就是最大的收获,我还太年轻。
因为JavaScript里面Array是对象,==或===操作符只能比较两个对象是否是同一个实例,也就是是否是同一个对象引用。目前JavaScript没有内置的操作符判断对象的内容是否相同。
但是惯性思维让人以为数组也是值,是可以比较的。(这段是复制的,别人总结的,和我想法一模一样)希望能给同为小白的朋友们提个醒

源码

https://github.com/yuyeqianxu...
希望能帮助到和我一样的小白朋友们,有bug麻烦反馈,谢谢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/90204.html

相关文章

  • 用 js 写个自动寻路的贪吃

    摘要:前言偶尔看到两年前写的贪吃蛇,当时没把自动寻路的算法写好,蛇容易挂,周末找了个时间把当年的坑填上,写了个不会挂的贪吃蛇。 前言 偶尔看到两年前写的贪吃蛇,当时没把自动寻路的算法写好,蛇容易挂,周末找了个时间把当年的坑填上,写了个不会挂的贪吃蛇。 两年前的版本_点击查看 这次更新的版本_点击查看 代码比较简单,使用 canvas 完成游戏的画图,抛开 A* 算法的实现,整个 html 代...

    gaara 评论0 收藏0
  • 小白成长日记写个省市区三级联动

    摘要:数据来源台湾缺省完成图初始化选完省之后部分请选择请选择暂无数据暂无数据一开始的初始状态是省份可以选择,利用来控制市和区的现实选项。当省份未选择时,市区因为没有数据,所以会选择暂无数据。 依旧使用vue,不需要关注dom太方便了。数据来源(台湾缺省):https://github.com/airyland/c... 完成图 初始化 showImg(https://segmentfault...

    JerryC 评论0 收藏0
  • 小白成长日记写个日历

    摘要:一周有天,返回的数,如果上月最后一天是星期二,看下的日历是补了三天,我们得到的是,所以为此,之后就是填充最后一天,用处理一下再排序,上一个月的数据就得到了。 每天进步一点点。写个简单的小日历,依旧用vue,方便 完成图 showImg(https://segmentfault.com/img/bVZoWs?w=416&h=495); 思路 本月的天数 截取上月的天数 截取下月天数 今...

    muzhuyu 评论0 收藏0
  • 用jquery写贪吃

    需要具备知识:1.html、css基础2.jquery基础 具体实现方法: 创建游戏界面 .bts { display: flex; } .bt { width: 60px; height: 24px; line-height: 24px...

    gitmilk 评论0 收藏0
  • 用jquery写贪吃

    需要具备知识:1.html、css基础2.jquery基础 具体实现方法: 创建游戏界面 .bts { display: flex; } .bt { width: 60px; height: 24px; line-height: 24px...

    h9911 评论0 收藏0

发表评论

0条评论

archieyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<