天天看點

#打卡不停更# 簡單的JS鴻蒙小遊戲——飛行棋之遊戲邏輯

前言

我們之前完成了遊戲的基本布局,今天我們接着來講下如何實作飛行棋的遊戲邏輯。

遊戲邏輯

  • 擲骰子:随機地擲出點數1~6,根據骰子點數和目前陣營的棋子狀态改變對應棋子的disabled屬性,以控制該棋子是否可互動移動,若無符合互動條件的棋子可操作則進行回合輪替。
todice() {
    this.dice_dab = true;
    this.dice_num = Math.floor(Math.random()*6+1);
    switch(this.dice_num) {
        case 1:
            this.dice_pic = "point1";
            break;
        case 2:
            this.dice_pic = "point2";
            break;
        case 3:
            this.dice_pic = "point3";
            break;
        case 4:
            this.dice_pic = "point4";
            break;
        case 5:
            this.dice_pic = "point5";
            break;
        case 6:
            this.dice_pic = "point6";
            break;
        default:
            console.log("骰子意外出錯");
            break;
    }
    // 骰子點數小于6,若有飛行狀态的棋子可點選,該回合可操作,否則回合輪替
    if(6 > this.dice_num) {
        var operable = false;
        for(var i=0; i<4; i++) {
            if("flying" == thetype[i].type) {
                thetype[i].chess_dab = false;
                operable = true;
            }
        }
        if(false == operable) {
            this.rotate();
        }
        else {}
    }
    // 骰子點數為6,除已到達的棋子都可點選
    else {
        for(var i=0; i<4; i++) {
            if("arrive" != thetype[i].type) {
                thetype[i].chess_dab = false;
            }
        }
    }
},
           
  • 選擇棋子:玩家選擇可移動的棋子行動,根據棋子狀态移動棋子。若棋子還未“起飛”,則移動到起點;若棋子已經行走在航線上,則移動與骰子點數對應的步數,若超過終點則回退多餘步數。
// 選中棋子行動
appoint(thecamp, num) {
    for(var i=0; i<4; i++) {
        thecamp[i].chess_dab = true;
    }
    // 若該棋子已進入航線
    if(null != thecamp[num].step) {
        for(var t=0; t<MapData[Route[this.theround%4][thecamp[num].step]].chess.length; t++) {
            if(thecamp[num].index == MapData[Route[this.theround%4][thecamp[num].step]].chess[t].index) {
                MapData[Route[this.theround%4][thecamp[num].step]].chess.splice(t, 1);
                break;
            }
        }
    }
    // 如果該棋子處于待機狀态,進入起點,最後結束
    if("wait" == thecamp[num].type) {
        MapData[thecamp[num].index].chess.pop();
        thecamp[num].step = 0;
        thecamp[num].type = "flying";
        thecamp[num].x = MapData[Route[this.theround%4][thecamp[num].step]].x;
        thecamp[num].y = MapData[Route[this.theround%4][thecamp[num].step]].y;
        thecamp[num].angle = MapData[Route[this.theround%4][thecamp[num].step]].angle;
        MapData[Route[this.theround%4][thecamp[num].step]].chess.push(thecamp[num]);
        this.dice_num = 0;
        this.dice_dab = false;
        this.dice_pic = "dice";
        return;
    }
    temp = this.dice_num;
    // 若走不到終點
    if(56 >= (thecamp[num].step + this.dice_num)) {
        forward = temp;
    }
    // 超過終點,回退幾步
    else {
        forward = 56 - thecamp[num].step;
        backward = temp - forward;
    }
    // 0.5秒執行一次走棋方法
    onestep = setInterval(()=> {
        this.move(thecamp[num]);
    }, 500);
},
           
  • 棋子移動:重複定時器執行棋子移動方法,一步一步走完後确認落點,先後進行是否觸發踩棋子判定或位移判定,之後再進行回合輪替。當有棋子行至終點時更新左側的飛行進度,若其中三名玩家完成遊戲則遊戲結束,彈出排行榜,未完成的一方為最後一名。
#打卡不停更# 簡單的JS鴻蒙小遊戲——飛行棋之遊戲邏輯
// 移動棋子
move(thechess) {
    // 若前進步數為0,且需要後退
    if((0 == forward) && (0 != backward)) {
        thechess.step -= 1;
        backward --;
    }
    // 若需要前進
    if(forward != 0) {
        thechess.step += 1;
        forward --;
    }
    thechess.x = MapData[Route[this.theround%4][thechess.step]].x;
    thechess.y = MapData[Route[this.theround%4][thechess.step]].y;
    thechess.angle = MapData[Route[this.theround%4][thechess.step]].angle;
    temp -= 1;

    // 若步數走完
    if(0 == temp) {
        clearInterval(onestep);
        forward = 0;
        backward = 0;
        this.complex(thechess);     // 踩棋子判斷
        this.getjump(thechess);     // 位移判斷

        // 向棋子目前落點寫入棋子資訊
        ruzhan = setTimeout(()=> {
            MapData[Route[this.theround%4][thechess.step]].chess.push(thechess);
        }, 1200);

        // 延遲後進行回合輪替
        changeturn = setTimeout(()=> {
            // 若該棋子到達終點,更新進度
            if(56 == thechess.step) {
                thechess.type = "arrive";
                this.flylog[this.theround%4].progress += 1;

                // 若該棋子走完後剛好全部到達,計入排行榜
                if(4 == this.flylog[this.theround%4].progress) {
                    this.allrank.push(
                        {
                            rank: this.allrank.length + 1,
                            chess: this.flylog[this.theround%4].camp,
                            round: "用時" + this.theround + "回合",
                        }
                    )
                    if(3 == this.allrank.length) {
                        for(var i=0; i<4; i++) {
                            if(this.flylog[i].progress < 4) {
                                var chesstemp = this.flylog[i].camp;
                            }
                        }
                        this.allrank.push(
                            {
                                rank: this.allrank.length + 1,
                                chess: chesstemp,
                                round: "未完成",
                            }
                        )
                        this.dice_dab = true;
                        this.result = true;
                        return;
                    }
                }
            }
            this.rotate();
        }, 1500);
    }
},
           
  • 踩棋事件判定:當棋子落點處已有其它棋子時判斷是否異色,若為同方陣營的棋子則共處一格;若為其它陣營的棋子則會被擊落回到起點。
#打卡不停更# 簡單的JS鴻蒙小遊戲——飛行棋之遊戲邏輯
// 落點是否有棋子
complex(thechess) {
    if(52 > MapData[Route[this.theround%4][thechess.step]].index) {
        if(0 != MapData[Route[this.theround%4][thechess.step]].chess.length) {
            // 我方棋子
            if(thechess.color == MapData[Route[this.theround%4][thechess.step]].chess[0].color) {
            }
            // 敵方棋子,踩回起點
            else {
                for(var i=0; i<MapData[Route[this.theround%4][thechess.step]].chess.length; i++) {
                    MapData[Route[this.theround%4][thechess.step]].chess[i].type = "wait";
                    MapData[Route[this.theround%4][thechess.step]].chess[i].step = null;
                    MapData[Route[this.theround%4][thechess.step]].chess[i].x =
                    MapData[MapData[Route[this.theround%4][thechess.step]].chess[i].index].x;
                    MapData[Route[this.theround%4][thechess.step]].chess[i].y =
                    MapData[MapData[Route[this.theround%4][thechess.step]].chess[i].index].y;
                    MapData[Route[this.theround%4][thechess.step]].chess[i].angle =
                    MapData[MapData[Route[this.theround%4][thechess.step]].chess[i].index].angle;
                    this.flylog[this.theround%4].hit += 1;
                }
                MapData[Route[this.theround%4][thechess.step]].chess.splice(0, MapData[Route[this.theround%4][thechess.step]].chess.length);
            }
        }
    }
},
           
  • 位移事件判定:若棋子與落點處棋格顔色相同,則觸發跳躍移動到下一個同色棋格位置,接着再進行一次踩棋事件判定。
#打卡不停更# 簡單的JS鴻蒙小遊戲——飛行棋之遊戲邏輯
// 判斷觸發位移
getjump(thechess) {
    // 在進入最後的直航線前的轉角前都有可能觸發位移
    if(46 >= thechess.step) {
        if(thechess.color == MapData[Route[this.theround%4][thechess.step]].color) {
            if(18 == thechess.step) {
                thechess.step += 12;
            }
            else {
                thechess.step += 4;
            }
            jump1 = setTimeout(()=> {
                thechess.x = MapData[Route[this.theround%4][thechess.step]].x;
                thechess.y = MapData[Route[this.theround%4][thechess.step]].y;
                thechess.angle = MapData[Route[this.theround%4][thechess.step]].angle;
                // 第二次踩棋子
                this.complex(thechess);
                if(18 == thechess.step) {
                    jump2 = setTimeout(()=> {
                        thechess.step += 12;
                        thechess.x = MapData[Route[this.theround%4][thechess.step]].x;
                        thechess.y = MapData[Route[this.theround%4][thechess.step]].y;
                        thechess.angle = MapData[Route[this.theround%4][thechess.step]].angle;
                        // 第三次踩棋子
                        this.complex(thechess);
                    }, 500);
                }
            }, 500);
        }
    }
},
           
  • 回合輪替:以回合數%4的方式進行回合輪替,若玩家擲出點數6則追加一次擲骰子機會。
// 回合輪替
rotate() {
    // 剛剛是否投出6,是則再來一次,否則回合數加一,進行輪替
    if(6 == this.dice_num) {
        if(4 == this.flylog[this.theround%4].progress) {
            this.theround += 1;
        }
    }
    else {
        this.theround += 1;
    }
    this.dice_num = 0;
    this.dice_pic = "dice";
    this.dice_dab = false;

    switch(this.theround % 4) {
        case 0:     // 紅的回合
            thetype = this.RED;
            this.roundtitle = "紅色方的回合";
            break;
        case 1:     // 綠的回合
            thetype = this.GREEN;
            this.roundtitle = "綠色方的回合";
            break;
        case 2:     // 黃的回合
            thetype = this.YELLOW;
            this.roundtitle = "黃色方的回合";
            break;
        case 3:     // 藍的回合
            thetype = this.BLUE;
            this.roundtitle = "藍色方的回合";
            break;
        default:
            console.log("意外出錯");
            break;
    }

    // 若該顔色的4枚棋子都已到達終點,直接進行回合輪替
    var win = 0;
    for(var i=0; i<4; i++) {
        if("arrive" == thetype[i].type) {
            win += 1;
        }
    }
    if(4 == win) {
        this.rotate();
    }
},
           
  • 重新開始遊戲:為了避免誤觸,将按鈕事件設定為長按觸發,長按後重置遊戲各個變量為初始值。
#打卡不停更# 簡單的JS鴻蒙小遊戲——飛行棋之遊戲邏輯
// 重新開始遊戲
restart() {
    // 重置遊戲其它變量
    clearInterval(onestep);
    temp = 0;
    forward = 0;
    backward = 0;
    clearTimeout(jump1);
    clearTimeout(jump2);
    clearTimeout(ruzhan);
    clearTimeout(changeturn);
    this.roundtitle = "";
    this.theround = 0;
    this.dice_pic = "dice";
    this.dice_num = 0;
    this.dice_dab = false;
    this.result = false;

    // 重置地圖
    for(var i=0; i<MapData.length; i++) {
        MapData[i].chess = [];
    }

    // 重置飛行記錄和排行榜
    for(var j=0; j<4; j++) {
        this.flylog[j].hit = 0;
        this.flylog[j].progress = 0;
    }
    this.allrank = [];

    // 重置棋子
    for(var k=0; k<4; k++) {
        this.RED[k].type = "wait";
        this.RED[k].chess_dab = true;
        this.RED[k].step = null;
        this.RED[k].x = MapData[this.RED[k].index].x;
        this.RED[k].y = MapData[this.RED[k].index].y;
        this.RED[k].angle = MapData[this.RED[k].index].angle;

        this.GREEN[k].type = "wait";
        this.GREEN[k].chess_dab = true;
        this.GREEN[k].step = null;
        this.GREEN[k].x = MapData[this.GREEN[k].index].x;
        this.GREEN[k].y = MapData[this.GREEN[k].index].y;
        this.GREEN[k].angle = MapData[this.GREEN[k].index].angle;

        this.YELLOW[k].type = "wait";
        this.YELLOW[k].chess_dab = true;
        this.YELLOW[k].step = null;
        this.YELLOW[k].x = MapData[this.YELLOW[k].index].x;
        this.YELLOW[k].y = MapData[this.YELLOW[k].index].y;
        this.YELLOW[k].angle = MapData[this.YELLOW[k].index].angle;

        this.BLUE[k].type = "wait";
        this.BLUE[k].chess_dab = true;
        this.BLUE[k].step = null;
        this.BLUE[k].x = MapData[this.BLUE[k].index].x;
        this.BLUE[k].y = MapData[this.BLUE[k].index].y;
        this.BLUE[k].angle = MapData[this.BLUE[k].index].angle;
    }

    // 棋子歸位
    for(var l=0; l<4; l++) {
        MapData[77+l].chess.push(this.RED[l]);
        MapData[82+l].chess.push(this.GREEN[l]);
        MapData[87+l].chess.push(this.YELLOW[l]);
        MapData[92+l].chess.push(this.BLUE[l]);
    }

    // 預設紅色先手
    thetype = this.RED;
    this.roundtitle = "紅色方的回合";
},
           

結語

至此,飛行棋小遊戲項目開發完畢,希望大家能從遊戲中理清邏輯,學到需要的知識。

<br>項目倉庫連結 https://gitee.com/zhan-weisong/flight-chess

附件連結:https://ost.51cto.com/resource/2365

本文作者:Looker_song

繼續閱讀