#打卡不停更#简单的js鸿蒙小游戏——飞行棋之游戏逻辑(代码片段)

author author     2022-12-06     215

关键词:

前言

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

游戏逻辑

  • 掷骰子:随机地掷出点数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);
,
  • 棋子移动:重复定时器执行棋子移动方法,一步一步走完后确认落点,先后进行是否触发踩棋子判定或位移判定,之后再进行回合轮替。当有棋子行至终点时更新左侧的飞行进度,若其中三名玩家完成游戏则游戏结束,弹出排行榜,未完成的一方为最后一名。

// 移动棋子
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);
    
,
  • 踩棋事件判定:当棋子落点处已有其它棋子时判断是否异色,若为同方阵营的棋子则共处一格;若为其它阵营的棋子则会被击落回到起点。

// 落点是否有棋子
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);
            
        
    
,
  • 位移事件判定:若棋子与落点处棋格颜色相同,则触发跳跃移动到下一个同色棋格位置,接着再进行一次踩棋事件判定。

// 判断触发位移
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();
    
,
  • 重新开始游戏:为了避免误触,将按钮事件设定为长按触发,长按后重置游戏各个变量为初始值。

// 重新开始游戏
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

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

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

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

#打卡不停更#harmonyos-基于arkui(js)实现虚拟摇杆组件(代码片段)

作者:杨尚晓前言虚拟摇杆在移动端游戏中是最常见看的,用来实现游戏中的精灵移动。本案例中使用jspai中的div和image组件来实现的虚拟摇杆组件,然后监听touch事件获取滑动的方向和位置x,y。开发环境说明工具版本:OpenHarmon... 查看详情

#打卡不停更#三方库移植之napi开发[2]c/c++与js的数据类型转换(代码片段)

在《三方库移植之NAPI开发[1]—HelloOpenHarmonyNAPI》通过一个HelloOpenHarmonyNAPI样例讲述了NPAI接口开发基础知识。本文在其基础上修改hellonapi.cpp文件,介绍JS类型和C/C++数据类型之间的转换。开发基于最新的OpenHarmony3.2Beta3版本及其对应... 查看详情

#打卡不停更#三方库移植之napi开发[4]异步调用:callback&promise(代码片段)

三方库移植之NAPI开发系列文章《HelloOpenHarmonyNAPI》、《C/C++与JS的数据类型转换》其接口都是同步的。对IO、CPU密集型任务需要异步处理。NAPI支持异步模型,提供了Promise、Callback2种方式。往期回顾:三方库移植之NAPI开发[1]—HelloO... 查看详情

#打卡不停更#harmonyos-基于arkui(ets)实现心电图组件(代码片段)

作者:杨尚晓前言随着大家生活水平的提升,越来越多的人注重自身身心健康,养生成了目前比较热门的活动。心电图是检测心脏活动状态的直观表现,可以通过心电图来观察人提的健康状况。响应鸿蒙万物互联的口号,肯定少... 查看详情

#打卡不停更#三方库移植之napi开发[3]通过ide开发napi工程(代码片段)

在三方库移植之NAPI开发[1]—HelloOpenHarmonyNAPI一文中,笔者开发的是一个rom包的napi工程。该工程需要编译烧录固件,C++的动态库会集成到开发板的ROM中。在本篇文章中,笔者使用三方库移植之NAPI开发[1]—HelloOpenHarmonyNAPI中一样的he... 查看详情

#打卡不停更#openharmony-arkui(ts)声明式开发之列表拖动排列(代码片段)

作者:梁青松项目介绍本项目基于OpenHarmony的ArkUI框架:TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:基于TS扩展的声明式开发范式,因为OpenHarmony的API相对于HarmonyOS的API,功能上比较完善和成熟的,有些... 查看详情

经典手机小游戏用加特林调整高度

经典手机小游戏中,用加特林调整高度的应该是《飞行员大战》这款游戏。在游戏中,玩家需要控制飞行员不断上升或下降,以躲避障碍物并攻击敌机。加特林被用作一种武器,可以在特定位置上方或下方发射,摧毁敌机并获得... 查看详情

一款简单地2d飞行射击游戏

...设也只能自己慢慢摸索。熬了一周,总算是熬出来了一款简单的游戏。贴个图看看效果······  大概就是这个样子了,能力有限,哈哈。整个游戏的脚本都比较简单,里面值得一说的就是各种... 查看详情

#打卡不停更#openharmony-应用开发入门指南(代码片段)

作者:余香鑫前言了解OpenHarmony能够开发一些简单的OpenHarmony应用一、了解OpenHarmonyOpenHarmony是由开放原子开源基金会(OpenAtomFoundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,搭建一个智能终端设备操作系统... 查看详情

openharmony游戏开发探索之军棋翻翻棋实现(代码片段)

...棋实现一,引言大家也经常看到市面上有斗地主,麻将,飞行棋等不是很复杂的棋类游戏;然后作为没有开发过游戏的我,在思考一款游戏是如何开发的?于是就想在openharmony上尝试一下。最近发现一个有意思的棋类游戏军棋翻... 查看详情

1个人70万行代码,20年持续更新,这款游戏号称开发到死,永不停更

...量子位报道|公众号QbitAI这是一款「开发到死」,「永不停更」的游戏。兄弟两人,一人开发,一人剧情,共同维持了这款游戏近20年。现在的玩家刚刚打开它,往往会发出“这啥玩意儿?”的疑问:没... 查看详情

#打卡不停更#openharmony数据转码应用开发实战(上)(代码片段)

背景OpenHarmony的应用开发支持C++、JS、eTS,从已有版本的演进路线来看,eTS是未来重点的技术路线。对于刚入门OpenHarmony应用开发的小伙伴来说,eTS可能比较陌生,如果有一个合适的实战项目来练手,那么对技术能力提升是非常有... 查看详情

#打卡不停更#智能喂食器(代码片段)

一、介绍​随着人们生活方式的不断改变,宠物猫在许多家庭中占有重要的地位,其凭借独立的个性和易于打理的饲养方式,成为当下上班族喜欢的宠物之一,人们更是把宠物猫和狗作为家庭的重要成员。有铲屎官表示,每月在... 查看详情

每日sql打卡​​​​​​​​​​​​​​​day4丨游戏玩法分析i难度简单(代码片段)

...介绍:「数据仓库技术交流群」已经正式启动每日SQL打卡,帮助大家扎实基础,努力工作之余,别忘了自我提升。欢迎报名和邀请小伙伴参与,一个人可能走得很快,但一群人会走得很远。🍅题目汇总... 查看详情

纯js写的2048游戏,分享之

...有实现动态移动,不是非常好看,只是玩儿着自己模仿的小游戏还是蛮爽的,哈哈假设没有玩儿过这个游戏,最好先试玩儿下,这样看起下边的代码来easy些用的是event。临时不支持firefox下玩儿。。。试玩儿>>里边好多步骤写... 查看详情

#打卡不停更#-openharmony/docs开发入门(代码片段)

作者:朱子道杨成前言不管是作为软件开发的爱好者还是已经从事软件开发这个行业的从业者,对于接触一种全新的系统OpenHarmony。学习OpenHarmony,需要清楚OpenHarmony这个系统是什么,能干什么,今日分享从设备开发和应用开发两... 查看详情

仿《雷霆战机》飞行射击手游开发--游戏简介

...指定的任务后,还能获取各种类型的道具奖励。游戏操作简单,上手容易,画面逼真炫酷,并有多种道具可供使用。本游戏支持三种游戏模式:闯关模式、无尽模式、急速模 查看详情

#打卡不停更#家庭健康管理平台(代码片段)

0.项目简介身体健康是一切生产生活的硬性基础。健康是福,一切安好,未来才可期。为什么经常跑步体重缺还在往上飘?突发紧急情况怎么处理?在数字时代,如何更好的为人们提供健康福祉、普及健康知识?如何进一步驱动... 查看详情