從零開始:用REACT寫一個格鬥遊戲(一)

coro發表於2019-02-28

注:本介紹是分享過程並且尋求指點的,希望大家多多建議並參與

最近為了熟悉Bone框架,就準備用react寫一個簡單的格鬥遊戲練練手。目前用2天時間完成了遊戲的前期準備工作。可以控制人物前進,後退,攻擊,跳躍,發動技能等操作,但是總覺得操作起來有一點不流暢。接下來還準備完善人物的更多動作與連招,並且加入2個人物互相攻擊後的扣血,僵直等,還有電腦AI的自我行動等等。希望有經驗的同學可以多多分享。

前期工作

動畫效果雖然看起來是一個整體,但其實就是多個圖片一幀一幀切換。所有我們可以切換圖片的src地址來實現動畫效果。雖然專案是用react寫的,但是思路還是和JS一樣,操作DOM。利用ref屬性獲取DOM,然後加以操作。

人物前進

我們在頁面上先放上一個人物圖片,首先我們先實現這個用鍵盤控制這個圖片的移動。我們先規定一下按鍵:A是後退,D是前進,S蹲下,空格跳躍。在componentDidMount中,給圖片加上keydown事件,當我們按下某個鍵時,就可以得到按鍵的code了。知道了這個code,我們就可以選擇向哪裡移動這個圖片了。舉個例子,當我們按下D時,得到按鍵code為68,我們就知道是控制人物前進。接下來我們通過this.refs.xx.offsetLeft可以獲取人物的位置,假設我們規定前進一次移動25px,我們就可以這樣設定這個IMG的屬性:this.refs.xx.style.left = this.refs.xx.offsetLeft+25+"px"; 通過改變圖片的left屬性改變圖片位置。

當然,我們還要加上人物的動作,不然就不像動畫了。使用setTimeout設定切換圖片的間隔,例如:前進這個動作有5張圖片,那麼就每隔80毫秒切換一次圖片。這樣就實現了動畫效果。當然,既然每隔80毫秒切換一次圖片,那麼我們向前移動也不能一下子就移動25px,把25px分到5次圖片切換中,每次移動5px,這樣就不會突兀了。

這裡還有一個問題,就是keydown事件你按著鍵盤不動的時候,會持續觸發這個事件,這樣一個前進動作還沒有完成又會觸發另一個前進動作,這就讓人物移動變得很鬼畜。這裡我們有2個辦法解決。

  1. 讓keydown事件按下後只觸發一次
  2. 讓人物前進動作結束後再觸發另一個前進動作

第一個辦法不太適合,因為我們讓人物前進的時候就是一直按著D鍵的,人物的攻擊動作到是可以用第一個辦法。所以我們這裡用第二個辦法。大概思路就是我們先加一個lock狀態,初始狀態為false,每當按下D鍵時,如果lock為true,就不執行前進操作,當lock為false時,將lock變為true,然後執行前進操作。當人物前進動作沒完成時,lock一直都是true並且無法再次進行前進操作。當人物前進動作完成也就是切換到第5張圖片時,將lock設為false,人物又可以繼續前進了。後退,跳躍,操作大致與前進差不多。

人物攻擊

人物的攻擊操作與前進有一點區別,就是攻擊一直按著J鍵人物只會攻擊一次。這裡就需要在圖片上增加一個keyup事件,並且lock狀態在人物攻擊動作完成後不會變為false,必須當觸發這個keyup事件後才改變lock狀態。

人物蹲下

蹲下操作與前面的操作也不相同,蹲下操作需要一直按著S才會觸發,當你鬆開S鍵時,人物就會站起來。前面的lock狀態在組合鍵中有用,所以我們這裡再加一個keep狀態,初始為false,keep為true時不觸發操作,當keep為false時觸發蹲下動作並且把keep變為true,當keyup事件觸發時才讓keep變為false。

組合鍵操作

keydown事件不能同時監聽2個按鍵,你同時按下兩個按鍵,實際上keydown事件只能得到一個code,那這樣我們怎麼觸發組合按鍵呢?我的思路是用一個狀態組解決這個問題。首先宣告一個 keyStatus = {},在keydown事件中加上keyStatus[e.keyCode] = true ,然後再keyup事件中加上keyStatus[e.keyCode] = false。舉個例子,我們要進行蹲下攻擊操作,在我們按下S鍵並且沒有鬆開時,這時keyStatus[83] = true,接著我們再按下J,這時keyStatus[74] = true。接著我們判斷

    if(keyStatus[83]&&keyStatus[74]){
        //新增事件
    }
複製程式碼

就可以完成組合鍵操作了,當然我們鬆開按鍵時keyStatus[e.keyCode]就會變為false了。

人物技能

這裡我們舉個波動拳的例子,我的思路是繼續建立一個IMG(波動拳圖片),然後將它隱藏。讓我們按鍵觸發人物技能時,當人物的技能動作完成後,先獲取人物的位置,然後把波動拳位置放在人物位置後並且設定display:block讓圖片顯示出來。然後用setInterval讓波動拳自己飛行移動,當波動拳碰撞到邊界時,clearInterval清除並且隱藏波動拳圖片。

當然,我這裡只實現了對一個人物的控制,後面還要完成人物對戰,電腦AI等操作,感興趣的同學可以下載下來一起完成。希望大家多多提出可以改進的地方。附上下載地址github.com/leslie233/r…

GIF演示

從零開始:用REACT寫一個格鬥遊戲(一)

下一篇

相關文章