摘要:貪吃蛇并不是通過操作來完成移動的,而是通過記錄貪吃蛇的路徑來將身體渲染出來。目前沒有內置的操作符判斷對象的內容是否相同。
還是用的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麻煩反饋,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90204.html
摘要:前言偶爾看到兩年前寫的貪吃蛇,當時沒把自動尋路的算法寫好,蛇容易掛,周末找了個時間把當年的坑填上,寫了個不會掛的貪吃蛇。 前言 偶爾看到兩年前寫的貪吃蛇,當時沒把自動尋路的算法寫好,蛇容易掛,周末找了個時間把當年的坑填上,寫了個不會掛的貪吃蛇。 兩年前的版本_點擊查看 這次更新的版本_點擊查看 代碼比較簡單,使用 canvas 完成游戲的畫圖,拋開 A* 算法的實現,整個 html 代...
摘要:數據來源臺灣缺省完成圖初始化選完省之后部分請選擇請選擇暫無數據暫無數據一開始的初始狀態是省份可以選擇,利用來控制市和區的現實選項。當省份未選擇時,市區因為沒有數據,所以會選擇暫無數據。 依舊使用vue,不需要關注dom太方便了。數據來源(臺灣缺省):https://github.com/airyland/c... 完成圖 初始化 showImg(https://segmentfault...
摘要:一周有天,返回的數,如果上月最后一天是星期二,看下的日歷是補了三天,我們得到的是,所以為此,之后就是填充最后一天,用處理一下再排序,上一個月的數據就得到了。 每天進步一點點。寫個簡單的小日歷,依舊用vue,方便 完成圖 showImg(https://segmentfault.com/img/bVZoWs?w=416&h=495); 思路 本月的天數 截取上月的天數 截取下月天數 今...
需要具備知識:1.html、css基礎2.jquery基礎 具體實現方法: 創建游戲界面 .bts { display: flex; } .bt { width: 60px; height: 24px; line-height: 24px...
需要具備知識:1.html、css基礎2.jquery基礎 具體實現方法: 創建游戲界面 .bts { display: flex; } .bt { width: 60px; height: 24px; line-height: 24px...
閱讀 2904·2021-10-14 09:42
閱讀 1253·2021-09-24 10:32
閱讀 2968·2021-09-23 11:21
閱讀 2848·2021-08-27 13:10
閱讀 3338·2019-08-29 18:41
閱讀 2204·2019-08-29 15:16
閱讀 1213·2019-08-29 13:17
閱讀 899·2019-08-29 11:22