欢迎光临散文网 会员登陆 & 注册

战棋游戏移动范围算法

2022-05-21 12:18 作者:Nimanggi  | 我要投稿

---------------------------------------------------------------------------------


做一个四边格战棋类游戏的移动范围算法。


基本规则是:

    四边格,只允许临边移动(上、下、左、右)。

    有计步规则,每个格的计步权重为“1”。

    障碍格不许移动。


实现逻辑:


while (步数 > 0) {

    1. 设置角色当前的位置

    2. 计算当前剩余的步数

    3. 分别判断当前格子四周是否可以移动(是否为障碍格或已达到边界)

}


```

     +----+

     | 02 |

+----+----+----+

| 01 | 00 | 03 |

+----+----+----+

     | 04 |

     +----+

```




/**

 * 获取角色移动范围

 * @param __actorSite__ 角色位置

 * @param __moveRange__ 角色可移动范围

 */

XXX.prototype.getMovingRangeSites = function (__actorSite__, __moveRange__) {

    // 地图大小

    let mapSize = this._battleAPI._battleData.getMapSize();

    // 初始化

    let siteHasBeenChosenArr = new Array(mapSize.width);

    for (let i = 0; i < siteHasBeenChosenArr.length; ++i) {

        siteHasBeenChosenArr[i] = new Array(mapSize.height);

    }

    // 检索site是否被选择的临时用数组,标记全地图的site是否被使用

    for (let i = 0; i < mapSize.width; ++i) {

        for (let j = 0; j < mapSize.height; ++j) {

            siteHasBeenChosenArr[i][j] = 0;

        }

    }



    // 初始化结果数组

    let rangeSitesArr = [];



    // 判断range范围是否合法

    if (__moveRange__ >= 1 && __moveRange__ <= 20) {

        //

        let cellsToBeCheckArr = [];

        cellsToBeCheckArr.push(__actorSite__);



        // 根据角色移动的步数检索几次

        for (let index = 1; index <= __moveRange__; index++) {



            // 临时保存本次检查出来的site

            let tempArr = [];



            // 当前步数能走到的site

            for (const iterator of cellsToBeCheckArr) {

                // 检索顺序:左 上 右 下

                // 相邻节点坐标

                let siteLeft = {

                    x: iterator.x - 1,

                    y: iterator.y

                };



                // 判断是否满足逻辑要求的条件 及 检索时是否已经选择过该点

                if (this._checkSiteEnable(siteLeft) && !this._checkSiteHasBeenChosen(siteLeft, siteHasBeenChosenArr)) {

                    // 将该点设置成一倍检索状态

                    siteHasBeenChosenArr[siteLeft.x][siteLeft.y] = 1;

                    // 保存该点到结果数组

                    rangeSitesArr.push(siteLeft);

                    // 保存该点到临时数组,作为下次循环的根节点

                    tempArr.push(siteLeft);

                }



                let siteUp = {

                    x: iterator.x,

                    y: iterator.y + 1,

                };



                if (this._checkSiteEnable(siteUp) && !this._checkSiteHasBeenChosen(siteUp, siteHasBeenChosenArr)) {

                    siteHasBeenChosenArr[siteUp.x][siteUp.y] = 1;

                    rangeSitesArr.push(siteUp);

                    tempArr.push(siteUp);

                }



                let siteRight = {

                    x: iterator.x + 1,

                    y: iterator.y

                };



                if (this._checkSiteEnable(siteRight) && !this._checkSiteHasBeenChosen(siteRight, siteHasBeenChosenArr)) {

                    siteHasBeenChosenArr[siteRight.x][siteRight.y] = 1;

                    rangeSitesArr.push(siteRight);

                    tempArr.push(siteRight);

                }



                let siteDown = {

                    x: iterator.x,

                    y: iterator.y - 1,

                };



                if (this._checkSiteEnable(siteDown) && !this._checkSiteHasBeenChosen(siteDown, siteHasBeenChosenArr)) {

                    siteHasBeenChosenArr[siteDown.x][siteDown.y] = 1;

                    rangeSitesArr.push(siteDown);

                    tempArr.push(siteDown);

                }

            }



            // 将本次循环检索出来的site 放入待检查数组,以便下次循环使用

            cellsToBeCheckArr = tempArr;

        }

    } else {

        // range不合法时直接返回null

        rangeSitesArr = null;

    }



    return rangeSitesArr;

};




战棋游戏移动范围算法的评论 (共 条)

分享到微博请遵守国家法律