2

简单的JS鸿蒙小游戏—飞行棋之游戏逻辑

 1 year ago
source link: https://www.51cto.com/article/721766.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

简单的JS鸿蒙小游戏—飞行棋之游戏逻辑

作者:Looker_song 2022-11-01 15:17:48
今天我们接着来讲下如何实现飞行棋的游戏逻辑。
32b63bf63da26fb9157413498d3fb8a772078b.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

我们之前完成了​​游戏的基本布局​​,今天我们接着来讲下如何实现飞行棋的游戏逻辑。

  • 掷骰子:随机地掷出点数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 = "红色方的回合";
},

至此,飞行棋小游戏项目开发完毕,希望大家能从游戏中理清逻辑,学到需要的知识。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。

责任编辑:jianghua 来源: 51CTO开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK