日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

HTML5 2D平台游戏开发#4状态机

發布時間:2025/3/15 HTML 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTML5 2D平台游戏开发#4状态机 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  在實現了《HTML5 2D平臺游戲開發——角色動作篇之沖刺》之后,我發現隨著角色動作的增加,代碼中的邏輯判斷越來越多,鋪天蓋地的if() else()語句實在讓我捉襟見肘:

這還僅僅是角色只有數個動作的情況下,如果后期角色動作越來越多,那么這種編碼方式不僅容易出錯,而且還難以維護,我意識到自己正在朝一個錯誤的方向前進。在做了一番調研后,發現有限狀態機(Finite-state machine,簡稱FSM)是解決這類問題的方案之一。不過在使用狀態機之前,首先要明確都有些什么狀態,狀態之間是如何切換的。在稿紙上畫一張草圖來整理一下思路:

?

可以發現,雖然現在角色只有四種狀態,但按鍵分支已經達到八種,而且還沒有考慮到在每個狀態中雖然按下按鍵但不改變狀態的情況,比如跳躍中按下A/D鍵能左右移動但還是跳躍狀態。

下面就到了實現狀態機的階段了。狀態機首先要有一個標識當前狀態的成員,另外還需要一個設置這個成員的方法:

function FSM() {var activeState = null;//@param state {Function} 每一個狀態對應一個執行函數this.setState = function(state) {activeState = state;};this.update = function() {if (activeState != null) {activeState();}}; }var f = new FSM(); var flag = true;f.setState(function() {console.log('現在是站立狀態'); });//模擬狀態切換 (function updateState() {if (flag) {f.setState(function() {console.log('現在是移動狀態');});flag = !flag;} else {f.setState(function() {console.log('現在是站立狀態');});flag = !flag;}f.update();setTimeout(updateState, 1000); })();

不過,這個狀態機在游戲中不會用到?,這里只是用來表述一種思路。還有一種是基于堆棧的狀態機,有時稱之為下推自動機(Pushdown automata)

這種狀態機在工作時,只有棧頂的元素處于激活狀態。

一次只允許一種狀態激活,這樣就方便了游戲在各種狀態間進行切換,同時避免了代碼邏輯混亂的問題。

在update中使用條件選擇語句來進入各個分支:

update(dt) {switch (state) {case STATE.IDLE: //空閑this.updateIdle(dt);break;case STATE.WALKING: //移動this.updateWalking(dt);break;case STATE.JUMPING: //跳躍this.updateJumping(dt);break;case STATE.DASHING: //沖刺this.updateDashing(dt);break;case STATE.DASHING_JUMPING: //沖刺跳this.updateDashingJumping(dt);break;} }

再次回顧一下上面的思路草圖,在空閑狀態,角色能過渡到的狀態有跳躍、移動、沖刺,代碼實現如下:

//空閑 updateIdle(dt) {this.speed.x = 0; //處于靜止狀態,速度為0if (key[65]) { //向左移動this.speed.x -= this.speedX;this.direction = -1;this.state = STATE.WALKING; //進入移動狀態this.play(); //播放移動狀態時的動畫 }if (key[68]) { //向右移動this.speed.x += this.speedX;this.direction = 1;this.state = STATE.WALKING;//同上this.play();}if (key[75]) { //跳躍if (!this.jumping) { //這里不用判斷onGround,因為處于idle狀態必然是onGroundthis.state = STATE.JUMPING;//進入跳躍狀態this.jumping = true;this.speed.y = this.jumpSpeed;}}if (key[85]) { //沖刺if (!this.dashing) {this.dashLifeTime = CONFIG.MAX_DASH_LIFE_TIME;this.state = STATE.DASHING;//進入沖刺狀態this.dashing = true;this.speed.x += CONFIG.DASH_SPEED * this.direction;}} else {this.dashing = false;}this.speed.y += this.gravity;//更新位置this.moveX(dt);this.moveY(dt);if (this.pos.y >= 9.375) {this.speed.y = 0;this.pos.y = 9.375;if (!key[75]) this.jumping = false;} }

在上面的代碼中,如果按下了移動鍵,則會進入移動狀態,游戲再次循環時,就會執行updateWalking方法。如法炮制,就能很輕易地實現剩余的方法。

//移動 updateWalking(dt) {this.state = STATE.IDLE;this.speed.x = 0;if (key[65]) {this.speed.x -= this.speedX;this.state = STATE.WALKING;this.direction = -1;}else if (key[68]) {this.speed.x += this.speedX;this.state = STATE.WALKING;this.direction = 1;}if (key[75]) {if (!this.jumping) {this.state = STATE.JUMPING;this.jumping = true;this.speed.y = this.jumpSpeed;}} else {this.jumping = false;}if (key[85]) { //沖刺if (!this.dashing) {this.dashLifeTime = CONFIG.MAX_DASH_LIFE_TIME;this.state = STATE.DASHING;this.dashing = true;this.speed.x += CONFIG.DASH_SPEED * this.direction;}} else {this.dashing = false;}this.moveX(dt);this.moveY(dt);if (this.state === STATE.IDLE) this.play(); }

本篇結束,有空再繼續更新。

P.S.在沒有使用狀態機之前,我考慮的是通過記錄按鍵的順序與組合來實現各種動作,既繁瑣又容易出錯,代碼感覺都看不下去了,還好懸崖勒馬,才避免了許多無用功?。

?

轉載于:https://www.cnblogs.com/undefined000/p/use-finite-state-machine-in-2D-Platform-Game.html

總結

以上是生活随笔為你收集整理的HTML5 2D平台游戏开发#4状态机的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。