Bläddra i källkod

优化代码,调整跳起策略

DW-PC\DW 5 år sedan
förälder
incheckning
2b5a4779e8
2 ändrade filer med 236 tillägg och 153 borttagningar
  1. 227 144
      module/game.js
  2. 9 9
      module/groudData.js

+ 227 - 144
module/game.js

@@ -19,15 +19,34 @@ const ROLESTATE = {
 
 class Game {
     constructor(wrapper) {
+        this.wrapper = wrapper; //外层element
+
         this.stageWidth = 750;
         this.stageHeight = 1334;
 
-        this.gameState = GAME_RESULT_STATE.ON;
-        this.wrapper = wrapper;
-        this.roleJump = false; //跳起状态
+        this.app = null;
+        this.bump = null; //碰撞检测实例
+
+        this.gameState = GAME_RESULT_STATE.ON; //游戏状态
+        this._roleState = ROLESTATE.READY; //人物状态
+        this.roleReadyStep = 0; //人物准备状态的当前帧数
+        this.roleReadyTimer = null; //人物准备动画的计时器
+        this.roleRunStep = 0; //人物跑动状态的当前帧数
+        this.roleRunTimer = null; // 人物跑动动画的计时器
         this.fallingDown = false; //下坠状态
-        this.decibel = 0; //分贝总和
+
+        //地面
+        this.groundData = null; //地面构造数据
+        this.groundArr = []; //地面元素数组
+        this.totalWidth = 0; //总宽度,主要用于布局
+
+        //倒计时
+        this.uiCountdownTimes = 3; //倒计时次数 3 2 1 开始
+        this.uiCountdownTimer = null; //倒计时计时器
+
         //ui
+        this.uiRole = null; //人物sprite
+        this.uiuiGroundContainer = null; //地面总容器
         this.uiGameTopTip = null; //游戏顶部提示
         this.uiCountdown = null; //游戏开始倒计时
         this.uiFireworksContanier = null; //烟花容器
@@ -61,6 +80,9 @@ class Game {
                 }
             }
         };
+
+        this.decibelArr = []; //声贝队列
+        this.decibel = 0; //声贝峰值
         this.init();
         this.initProxy();
     }
@@ -76,6 +98,8 @@ class Game {
         this.bump = new PIXI.extras.Bump();
         loaderRes(["/scene.json"], this.loadedSource, this);
     }
+
+    //roleState代理
     initProxy() {
         Object.defineProperty(this, "roleState", {
             configurable: true,
@@ -98,22 +122,23 @@ class Game {
                         this.roleRunLoop();
                         break;
                     case ROLESTATE.JUMP:
-                        this.role.texture = TextureCache[`p_jump_0.png`];
+                        this.uiRole.texture = TextureCache[`p_jump_0.png`];
                         break;
                     case ROLESTATE.DOWN:
-                        this.role.texture = TextureCache[`p_jump_1.png`];
+                        this.uiRole.texture = TextureCache[`p_jump_1.png`];
                         break;
                 }
             }
         });
     }
+
     clearRoleStateEffect() {
         clearTimeout(this.roleReadyTimer);
         clearTimeout(this.roleRunTimer);
     }
     roleReadyLoop() {
         this.roleReadyTimer = setTimeout(() => {
-            this.role.texture =
+            this.uiRole.texture =
                 TextureCache[`p_stand_${this.roleReadyStep % 2}.png`];
             this.roleReadyStep++;
             this.roleReadyLoop();
@@ -122,7 +147,7 @@ class Game {
 
     roleRunLoop() {
         this.roleRunTimer = setTimeout(() => {
-            this.role.texture =
+            this.uiRole.texture =
                 TextureCache[`p_run_${this.roleRunStep % 2}.png`];
             this.roleRunStep++;
             this.roleRunLoop();
@@ -130,62 +155,42 @@ class Game {
     }
 
     loadedSource() {
+        this.initGameReady();
         this.initGround();
         this.initRole();
-        this.initGameReady();
-        this.gameState = GAME_RESULT_STATE.ON;
-        this.readyStart();
         this.initFireworks();
+        this.readyStart();
     }
-    readyStart() {
-        this.uiCountdownTimes = 3;
-        this.uiCountdown.texture = TextureCache[`word_3.png`];
-        this.uiCountdown.visible = true;
-        this.uiCountdownTimer = setTimeout(this.countDownFn.bind(this), 1000);
-    }
-    countDownFn() {
-        this.uiCountdownTimes--;
-        if (this.uiCountdownTimes === 0) {
-            this.uiCountdown.texture = TextureCache[`word_start.png`];
-            this.gameStart();
-        } else if (this.uiCountdownTimes < 0) {
-            clearTimeout(this.uiCountdownTimer);
-            this.uiCountdown.visible = false;
-        } else {
-            this.uiCountdown.texture =
-                TextureCache[`word_${this.uiCountdownTimes}.png`];
-        }
 
-        this.uiCountdownTimer = setTimeout(this.countDownFn.bind(this), 1000);
-    }
-    gameStart() {
-        this.groundWalk();
-        this.roleState = ROLESTATE.RUN;
-    }
-    //创建角色
-    initRole() {
-        this.role = Sprite.fromFrame("people.png");
-        this.role.x = this.stageWidth / 2;
-        this.role.y = this.stageHeight - this.groundData[0].height + 24; //初始化位置
-        this.role._vy = 4;
-        this.role.anchor.x = 0.5;
-        this.role.anchor.y = 1;
-        this.app.stage.addChild(this.role);
-        this.app.ticker.add(this.jumpLoop, this);
-        this.roleState = ROLESTATE.READY;
+    //开始倒计时
+    initGameReady() {
+        this.uiGameTopTip = Sprite.from("word_tips.png");
+        this.uiGameTopTip.anchor.x = 0.5;
+        this.uiGameTopTip.x = 375;
+        this.uiGameTopTip.y = 20;
+        this.app.stage.addChild(this.uiGameTopTip);
+
+        this.uiCountdown = Sprite.from("word_3.png");
+        this.uiCountdown.anchor.x = 0.5;
+        this.uiCountdown.anchor.y = 0.5;
+        this.uiCountdown.x = 375;
+        this.uiCountdown.y = 400;
+        this.app.stage.addChild(this.uiCountdown);
     }
+
     // 创建地面容器
     initGround() {
+        this.groundData = createGroundData();
         this.groundArr = [];
         this.totalWidth = 0;
-        this.groundData = createGroundData();
-        this.groundContainer = new Container();
-        this.groundContainer._vx = 2.5;
-        this.app.stage.addChild(this.groundContainer);
+        this.uiGroundContainer = new Container();
+        this.uiGroundContainer._vx = 2.5;
+        this.app.stage.addChild(this.uiGroundContainer);
         this.groundData.forEach(this.createGround.bind(this));
-        this.totalWidth = this.groundContainer.width;
+        this.totalWidth = this.uiGroundContainer.width;
     }
-    //生成地面
+
+    //生成地面迭代器函数
     createGround(groundData, index, arr) {
         let { height, blockNum, gap } = groundData;
         this.totalWidth += gap;
@@ -206,7 +211,7 @@ class Game {
         }
         this.totalWidth += groundData.width;
         this.groundArr.push(groundUnitContainer);
-        this.groundContainer.addChild(groundUnitContainer);
+        this.uiGroundContainer.addChild(groundUnitContainer);
 
         //最后一个,需要添加通关门UI
         if (index === arr.length - 1) {
@@ -218,10 +223,89 @@ class Game {
         }
     }
 
+    //创建角色
+    initRole() {
+        this.uiRole = Sprite.fromFrame("people.png");
+        this.uiRole.x = this.stageWidth / 2;
+        this.uiRole.y = this.stageHeight - this.groundData[0].height + 24; //初始化位置
+        this.uiRole._vy = 400 / 60;
+        this.uiRole.anchor.x = 0.5;
+        this.uiRole.anchor.y = 1;
+        this.app.stage.addChild(this.uiRole);
+        this.roleState = ROLESTATE.READY;
+    }
+
+    //生成烟花
+    initFireworks() {
+        this.uiFireworksContanier = new Container();
+        Object.keys(this.fireworkOpts).forEach(key => {
+            let firework = this.fireworkOpts[key];
+            firework.frameFirework = 0; //下标
+            firework.timer = null; //计时器
+
+            let uiFirework = Sprite.from(
+                `fireworks_${key}_${firework.frameFirework}.png`
+            ); //ui
+            uiFirework.anchor.x = 0.5;
+            uiFirework.anchor.y = 0.5;
+            uiFirework.x = firework.pos.x;
+            uiFirework.y = firework.pos.y;
+
+            firework.uiFirework = uiFirework;
+
+            this.uiFireworksContanier.addChild(uiFirework);
+        });
+        this.uiFireworksContanier.visible = false;
+        this.app.stage.addChild(this.uiFireworksContanier);
+    }
+
+    //开始倒计时
+    readyStart() {
+        this.uiCountdownTimes = 3;
+        this.uiCountdown.texture = TextureCache[`word_3.png`];
+        this.uiCountdown.visible = true;
+        this.countDownLoop();
+    }
+
+    countDownLoop() {
+        this.uiCountdownTimer = setTimeout(() => {
+            this.uiCountdownTimes--;
+            if (this.uiCountdownTimes === 0) {
+                this.uiCountdown.texture = TextureCache[`word_start.png`];
+                this.gameStart();
+            } else if (this.uiCountdownTimes < 0) {
+                clearTimeout(this.uiCountdownTimer);
+                this.uiCountdown.visible = false;
+            } else {
+                this.uiCountdown.texture =
+                    TextureCache[`word_${this.uiCountdownTimes}.png`];
+            }
+            this.countDownLoop();
+        }, 1000);
+    }
+
+    gameStart() {
+        this.roleState = ROLESTATE.RUN;
+        this.groundWalk();
+    }
+
+    restartGame() {
+        console.log("restartGame");
+        this.gameState = GAME_RESULT_STATE.ON;
+        this.uiGroundContainer.x = 0;
+        this.uiRole.x = 375;
+        this.uiRole.y = this.groundData[0].y;
+        this.gameResultContainer.visible = false;
+        this.decibel = 0;
+        this.roleState = ROLESTATE.RUN;
+        this.app.ticker.start();
+    }
+
+    //每帧多要去判断人物状态
     walkLoop() {
-        this.groundContainer.x -= this.groundContainer._vx;
-        let rolePosX = Math.abs(this.groundContainer.x - 375); //人物所在位置
-        let rolePosY = this.role.y;
+        this.uiGroundContainer.x -= this.uiGroundContainer._vx;
+        let rolePosX = Math.abs(this.uiGroundContainer.x - 375); //人物所在位置
+        let rolePosY = this.uiRole.y;
 
         if (rolePosX >= this.totalWidth - 375) {
             console.log("完成游戏");
@@ -237,6 +321,21 @@ class Game {
             ground =>
                 rolePosX >= ground.x && rolePosX <= ground.x + ground.width
         );
+
+        if (index === -1) {
+            /**
+             * 掉坑里了
+             * 如果不是跳起状态,默认下坠
+             *  */
+            console.log("在坑里的范围内");
+            if (this.roleState !== ROLESTATE.JUMP && !this.fallingDown) {
+                this.fallDown();
+            }
+
+            //在坑里,默认寻找下一个地面作为碰撞检测
+            index = this.groundData.findIndex(ground => rolePosX <= ground.x);
+        }
+
         if (index >= 0) {
             /**
              * 人物下方的方块下标
@@ -245,7 +344,7 @@ class Game {
             let ground = this.groundArr[index];
             if (ground.y <= rolePosY) {
                 let collision = this.bump.hit(
-                    this.role,
+                    this.uiRole,
                     ground,
                     true,
                     true,
@@ -265,118 +364,112 @@ class Game {
                     }
                 }
             }
-        } else {
-            /**
-             * 掉坑里了
-             * 如果不是跳起状态,默认下坠
-             *  */
-            console.log("在坑里的范围内");
-            if (!this.roleJump && !this.fallingDown) {
-                this.fallDown();
-            }
         }
     }
 
+    //站在地面上
     standGround() {
+        this.decibel = 0;
+        this.decibelArr = [];
         this.roleState = ROLESTATE.RUN;
         this.app.ticker.remove(this.downLoop, this);
-        this.roleJump = false;
         this.fallingDown = false;
     }
 
-    //开始倒计时
-    initGameReady() {
-        this.uiGameTopTip = Sprite.from("word_tips.png");
-        this.uiGameTopTip.anchor.x = 0.5;
-        this.uiGameTopTip.x = 375;
-        this.uiGameTopTip.y = 20;
-        this.app.stage.addChild(this.uiGameTopTip);
-
-        this.uiCountdown = Sprite.from("word_3.png");
-        this.uiCountdown.anchor.x = 0.5;
-        this.uiCountdown.anchor.y = 0.5;
-        this.uiCountdown.x = 375;
-        this.uiCountdown.y = 400;
-        this.app.stage.addChild(this.uiCountdown);
-    }
-
-    gameOver() {
-        this.roleJump = false;
-        this.fallingDown = false;
-        this.app.ticker.remove(this.fallDownLoop, this);
-        this.gameState = GAME_RESULT_STATE.OVER;
-        this.app.ticker.stop();
-    }
-
-    gameSucc() {
-        this.groundStop();
-        this.roleWalk();
-    }
-
-    restartGame() {
-        console.log("restartGame");
-        this.gameState = GAME_RESULT_STATE.ON;
-        this.groundContainer.x = 0;
-        this.role.x = 375;
-        this.role.y = this.groundData[0].y;
-        this.gameResultContainer.visible = false;
-        this.decibel = 0;
-        this.roleState = ROLESTATE.RUN;
-        this.app.ticker.start();
-    }
-    roleWalk(){
+    //最后即将通关时候,人物开始走动,而不是背景移动。
+    roleWalk() {
         this.app.ticker.add(this.roleWalkLoop, this);
     }
-    roleStop(){
+
+    //人物停止走动
+    roleStop() {
         this.app.ticker.remove(this.roleWalkLoop, this);
     }
+
+    //人物走动帧函数
     roleWalkLoop() {
-        this.role.x += 2.5;
-        if (this.role.x >= 750 + this.role.width / 2) {
+        this.uiRole.x += 2.5;
+        if (this.uiRole.x >= 750 + this.uiRole.width / 2) {
             console.log("人物通关");
             this.roleStop();
             this.startFireworks();
         }
     }
 
+    //背景移动,人物不动。
     groundWalk() {
         this.app.ticker.add(this.walkLoop, this);
     }
 
+    //背景停止移动
     groundStop() {
         this.app.ticker.remove(this.walkLoop, this);
     }
-    // 跳起,有一个最高值
+    /**
+     *
+     * @param {number} decibel 声贝差值
+     * 取声贝峰值算法
+     * 1.如果声贝大于设置值,一旦呈下降趋势,则去当前峰值。
+     * 2.如果声贝一直增长,取第30帧的值。
+     */
     jump(decibel) {
         if (this.gameState === GAME_RESULT_STATE.OVER) return;
-        if (this.decibel >= 80) return;
-        this.decibel += decibel;
-        this.roleJump = true;
+        if (
+            this.roleState === ROLESTATE.JUMP ||
+            this.roleState === ROLESTATE.DOWN ||
+            this.roleState === ROLESTATE.READY
+        ) {
+            return;
+        }
+        console.log(this.decibelArr);
+        if (this.decibelArr.length >= 1) {
+            if (this.decibelArr.length >= 30) {
+                this.decibel = decibel * 10;
+                this.startJump();
+            } else {
+                let isAscend = this.decibelArr.every(item => decibel >= item);
+
+                if (isAscend) {
+                    this.decibelArr.push(decibel);
+                } else {
+                    this.decibel = this.decibelArr.pop() * 10;
+                    this.startJump();
+                }
+            }
+        } else {
+            this.decibelArr.push(decibel);
+        }
+    }
+
+    startJump() {
+        console.log("startJump");
+        this.app.ticker.add(this.jumpLoop, this);
         this.fallingDown = false;
         this.app.ticker.remove(this.fallDownLoop, this);
         this.app.ticker.remove(this.downLoop, this);
     }
+
     jumpLoop() {
         if (this.decibel > 0) {
-            let distance = Math.min(this.role._vy, this.decibel);
-            this.role.y -= distance;
+            let distance = Math.min(this.uiRole._vy, this.decibel);
+            this.uiRole.y -= distance;
             this.decibel -= distance;
             console.log("distance,decibel", distance, this.decibel);
             this.roleState = ROLESTATE.JUMP;
             if (this.decibel === 0) {
+                this.app.ticker.remove(this.jumpLoop, this);
                 this.app.ticker.add(this.downLoop, this);
             }
         }
     }
 
     downLoop() {
-        this.roleJump = true;
         this.roleState = ROLESTATE.DOWN;
-        this.role.y += this.role._vy;
+        this.uiRole.y += this.uiRole._vy;
     }
 
     fallDownLoop() {
-        this.role.y += this.role._vy;
+        this.uiRole.y += this.uiRole._vy;
     }
 
     fallDown() {
@@ -385,29 +478,6 @@ class Game {
         this.app.ticker.add(this.fallDownLoop, this);
     }
 
-    initFireworks() {
-        this.uiFireworksContanier = new Container();
-        Object.keys(this.fireworkOpts).forEach(key => {
-            let firework = this.fireworkOpts[key];
-            firework.frameFirework = 0; //下标
-            firework.timer = null; //计时器
-
-            let uiFirework = Sprite.from(
-                `fireworks_${key}_${firework.frameFirework}.png`
-            ); //ui
-            uiFirework.anchor.x = 0.5;
-            uiFirework.anchor.y = 0.5;
-            uiFirework.x = firework.pos.x;
-            uiFirework.y = firework.pos.y;
-
-            firework.uiFirework = uiFirework;
-
-            this.uiFireworksContanier.addChild(uiFirework);
-        });
-        this.uiFireworksContanier.visible = false;
-        this.app.stage.addChild(this.uiFireworksContanier);
-    }
-
     startFireworks() {
         this.uiFireworksContanier.visible = true;
 
@@ -417,7 +487,7 @@ class Game {
             clearInterval(firework.timer);
             setTimeout(() => {
                 firework.timer = setInterval(() => {
-                    firework.uiFirework.visible = (firework.frameFirework <= 6);
+                    firework.uiFirework.visible = firework.frameFirework <= 6;
                     if (firework.frameFirework <= 6) {
                         firework.uiFirework.texture =
                             TextureCache[
@@ -429,6 +499,19 @@ class Game {
             }, firework.delay);
         });
     }
+
+    gameOver() {
+        this.roleState = ROLESTATE.READY;
+        this.fallingDown = false;
+        this.app.ticker.remove(this.fallDownLoop, this);
+        this.gameState = GAME_RESULT_STATE.OVER;
+        this.app.ticker.stop();
+    }
+
+    gameSucc() {
+        this.groundStop();
+        this.roleWalk();
+    }
 }
 
 export default Game;

+ 9 - 9
module/groudData.js

@@ -1,47 +1,47 @@
 export default function createGroundData() {
     return [
         {
-            height: 572, // px
+            height: 272, // px
             blockNum: 6, // kuai
             gap: 0 //px
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 6,
             gap: 100
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 6,
             gap: 200
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 4,
             gap: 300
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 2,
             gap: 200
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 6,
             gap: 100
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 4,
             gap: 200
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 3,
             gap: 200
         },
         {
-            height: 572,
+            height: 272,
             blockNum: 6,
             gap: 300
         }