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

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

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

演示

链接描述

html&&data:

<div id="snake">
        <table>
        <tr v-for="(col,y) in cols"><td v-for="(row,x) in rows" :class="body(x,y)||showfood(x,y)?'active':''"></td></tr>
        </table>
        <button @click="start()">开始</button>
</div>

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<this.position.length;i++){//循环身体函数,利用索引和身体位置做毕竟,如果索引和身体数组重合就会添加active样式
            if(this.position[i][0]===x&&this.position[i][1]===y){
                return true
            }
        }
    },

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

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麻烦反馈,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue.js是十分耀眼的项目之一,受到国内外开发人员的极度推崇。内容包括Vue.js概述、Vue.js的安装、定义页面、渲视图、路由、发送HTTP请求、表单的绑定和提交、打包、部署、解决js的跨域问题、Debug、Component、Vuex、页面的生命周期等,*后还给出一个实战案例供读者了解Vue.js项目开发过程。2020-2021最新Vue.js零基础入门到精通实战开发课程视频教程下载。课程以项目实战为驱动,帮你打开通往Vue.js的任督二脉,让你迅速成为一个优秀的Vue.js开发人员。 一、课程介绍Vue.js致力于构建数据驱动的web应用开发框架,是一个精简的MVVM。Vue.js 专注于 MVVM 模型的 ViewModel 层。简单的数据操作,就可以完成页面的更新,当然也有很多类似的框架,如Angular,React,但是Vue以简洁化,轻量级,数据驱动,模块友好等优势深受企业以及前端开发者的喜爱,成为前端开发人员必备的技能。2020年了,你还只会用jQuery吗?本课程以项目实战为驱动,帮你打开通往Vue.js的任督二脉,让你迅速成为一个优秀的Vue.js开发人员。二、课程需知我们的课程面向的同学是:需要有网页开发基础,熟悉HTML/CSS/JavaScript等前端开发技术,初步掌握JSON,闭包,AJAX…等JavaScript技术,在进阶阶段的课程中会使用ES6的一些语法,因此事先掌握一些ES6的知识也是有必要的。三、内容编排本课程分为三大部分讲解了运用Vue.js 进行项目实战开发。内容包括:第一步:Vue.js基础1、初识vue.js 2、模板语法3、计算属性4、class与style绑定5、条件渲染6、列表渲染7、fetch&axios8、事件处理器9、表单控件10、组件化开发第二步:Vue.js进阶1、过渡动画效果2、自定义指令3、单文件组件4、路由vue-router第三步:项目实战1、卖座苹果网站项目- 引入iconfont- 路由搭建- axios以及反向代理-嵌套路由-数据渲染2、Vue.js第三方框架使用-Element UI-mintUI3、状态管理vuex课程详细目录:Vue.js 课程介绍.docx第001集-1vue初识第002集-2条件渲染第003集-3tab切换第004集-4列表渲染第005集-5模板语法第006集-6计算属性第007集-7侦听器和class第008集-8内联样式第009集-9事件绑定第010集-10表单输入绑定第011集-11过渡动画第012集-12todolist应用第013集-13生命周期与组件生命周期第014集-14组件之间的传值第015集-15$root_$parent_$children第016集-16v-model与插槽第017集-17vue-cli第018集-18vue-devtools第019集-19vue-cli原理第020集-20vue组件化第021集-21vue聊天框第022集-22socket初识和安装第023集-23单聊和群聊以及命名空间第024集-24聊天项目第025集-25聊天登录登出第026集-26聊天列表第027集-27个人聊天第028集-28单聊功能第029集-29自动滚动和聊天第030集-30群聊第031集-31注意编译地址第032集-32vue实现原理1第033集-33vue实现原理2第034集-34less第035集-35vue-less使用第036集-36sass第037集-37vue-router第038集-38动态路由和嵌套路由第039集-39命名视图和组件传参第040集-40vue路由高级应用第041集-41Vue路由守卫第042集-42vuexstate第043集-43vuex getter第044集-44vuex-action第045集-45vuex-module第046集-46vuex-插件第047集-47vuex-vant第048集-48网易严选商城第049集-49网易商城首页第050集-50分类列表第051集-51产品列表第052集-52产品列表2第053集-53商品产品页面第054集-54产品sku第055集-55产品购物车第056集-56购物车

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值