java swing实战——baba is you(游戏规则判定)

5. 游戏规则判定

​ 本游戏的创意性之一就在于规则的改变,玩家的行动会影响之后的胜利条件、推动规则等,在之前的编写中,我们默认规则baba is you、flag is win、wall is stop, rock is push.现在,我们编写改变规则的逻辑,这一部分的处理代码位于GameText.

5.1 who is you

​ 最重要的判定是谁可以移动,当然移动的对象可以有多个,在GameText采用如下的方法:

/**
 * 判定 who is you
 * 即从上到下,从左到右的组合
 * 如果存在组合放置于list中,反之,返回null
 * @return
 */
public List<String> whoIsYou() {
    return null;
}

​ 在GameFrame中调用:

    private void peopleMove(KeyEvent e) {
        String stop = PeopleLocation.WALL; // 默认wall is stop
        String push = PeopleLocation.ROCK; // 默认rock is push
        String win = PeopleLocation.FLAG; // 默认flag is win

        List<String> youList = gameText.whoIsYou();
        if (youList == null) {
            System.out.println("游戏失败");
            return;
        }

        /**
         * 遍历循环(添加GamePeople的getPeopleList()方法)
         * 寻找可以移动的角色
         */
        List<People> peopleList = gamePeople.getPeopleList();
        for (int i = 0; i < peopleList.size(); i++) {
            People people = peopleList.get(i);
            for (int j = 0; j < youList.size(); j++) {  // 遍历可控制的角色
                String you = youList.get(j);
                if(you.equalsIgnoreCase(people.getName())) {
                    switch (e.getKeyCode()) {
                        case KeyEvent.VK_UP:
                            gamePeople.move(1,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_DOWN:
                            gamePeople.move(-1,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_RIGHT:
                            gamePeople.move(2,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_LEFT:
                            gamePeople.move(-2,people,stop,push, win,gameText);
                            break;
                    }
                }
            }

        }
    }

GameText的判定逻辑如下:

  • 找到textList中的you块

  • 横向判定

    • you的左边第一块是is
    • you的左边第二块是可移动的角色
  • 纵向判定

    • you的上面第一块是is
    • you的上面第二块是可移动角色

代码如下:

/**
 * 判定 who is you
 * 即从上到下,从左到右的组合
 * 如果存在组合放置于list中,反之,返回null
 * @return
 */
public List<String> whoIsYou() {
    // 返回结果
    List<String> res = new ArrayList<>();

    //找到textList中的you块
    Text you = null;
    for (int i = 0; i < textList.size(); i++) {
        if (textList.get(i).getRule().equalsIgnoreCase(TextLocation.YOU)) {
            you = textList.get(i);
            break;
        }
    }
    // 横向判定
    //- you的左边第一块是is
    boolean flagL = false;
    for (int i = 0; i < textList.size(); i++) {
        Text text = textList.get(i);
        if (you.getX() - you.getWidth() == text.getX() && you.getY() == text.getY()) {
            if (text.getRule().equalsIgnoreCase(TextLocation.IS)) {
                flagL = true; // 左边第一块是is
                break;
            } else {
                break; // 左边第一块不是is
            }
        }
    }
    //- you的左边第二块是可移动的角色
    if (flagL) {
        for (int i = 0; i < textList.size(); i++) {
            Text text = textList.get(i);
            if (you.getX() - 2 * you.getWidth() == text.getX() && you.getY() == text.getY()) {
                switch (text.getRule()) {
                    case TextLocation.BABA:
                        res.add(PeopleLocation.BABA);
                        break;
                    case TextLocation.FLAG:
                        res.add(PeopleLocation.FLAG);
                        break;
                    case TextLocation.ROCK:
                        res.add(PeopleLocation.ROCK);
                        break;
                    case TextLocation.WALL:
                        res.add(PeopleLocation.WALL);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    // 纵向判定
    //- you的上边第一块是is
    boolean flagU = false;
    for (int i = 0; i < textList.size(); i++) {
        Text text = textList.get(i);
        if (you.getX() == text.getX() && you.getY() - you.getHeight() == text.getY()) {
            if (text.getRule().equalsIgnoreCase(TextLocation.IS)) {
                flagU = true; // 上边第一块是is
                break;
            } else {
                break; // 上边第一块不是is
            }
        }
    }
    //- you的上边第二块是可移动的角色
    if (flagU) {
        for (int i = 0; i < textList.size(); i++) {
            Text text = textList.get(i);
            if (you.getX()  == text.getX() && you.getY() - 2 * you.getHeight() == text.getY()) {
                switch (text.getRule()) {
                    case TextLocation.BABA:
                        res.add(PeopleLocation.BABA);
                        break;
                    case TextLocation.FLAG:
                        res.add(PeopleLocation.FLAG);
                        break;
                    case TextLocation.ROCK:
                        res.add(PeopleLocation.ROCK);
                        break;
                    case TextLocation.WALL:
                        res.add(PeopleLocation.WALL);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    if (res.size() > 0) return res;

    return null;
}

至此,我们改变角色规则,当然,此时wall is you由于stop的默认规则,暂时不能移动

5.2 who is stopwho is winwho is push

完成了上述逻辑,我们很容易的复制修改出对应的代码,首先,我们提取条件判定的公共代码

/**
 * 公共代码
 * @param rule
 * @return
 */
private List<String> whoIs(String rule) {
    // 返回结果
    List<String> res = new ArrayList<>();

    //找到textList中的you块
    Text you = null;
    for (int i = 0; i < textList.size(); i++) {
        if (textList.get(i).getRule().equalsIgnoreCase(rule)) {
            you = textList.get(i);
            break;
        }
    }
    // 横向判定
    //- you的左边第一块是is
    boolean flagL = false;
    for (int i = 0; i < textList.size(); i++) {
        Text text = textList.get(i);
        if (you.getX() - you.getWidth() == text.getX() && you.getY() == text.getY()) {
            if (text.getRule().equalsIgnoreCase(TextLocation.IS)) {
                flagL = true; // 左边第一块是is
                break;
            } else {
                break; // 左边第一块不是is
            }
        }
    }
    //- you的左边第二块是可移动的角色
    if (flagL) {
        for (int i = 0; i < textList.size(); i++) {
            Text text = textList.get(i);
            if (you.getX() - 2 * you.getWidth() == text.getX() && you.getY() == text.getY()) {
                switch (text.getRule()) {
                    case TextLocation.BABA:
                        res.add(PeopleLocation.BABA);
                        break;
                    case TextLocation.FLAG:
                        res.add(PeopleLocation.FLAG);
                        break;
                    case TextLocation.ROCK:
                        res.add(PeopleLocation.ROCK);
                        break;
                    case TextLocation.WALL:
                        res.add(PeopleLocation.WALL);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    // 纵向判定
    //- you的上边第一块是is
    boolean flagU = false;
    for (int i = 0; i < textList.size(); i++) {
        Text text = textList.get(i);
        if (you.getX() == text.getX() && you.getY() - you.getHeight() == text.getY()) {
            if (text.getRule().equalsIgnoreCase(TextLocation.IS)) {
                flagU = true; // 上边第一块是is
                break;
            } else {
                break; // 上边第一块不是is
            }
        }
    }
    //- you的上边第二块是可移动的角色
    if (flagU) {
        for (int i = 0; i < textList.size(); i++) {
            Text text = textList.get(i);
            if (you.getX()  == text.getX() && you.getY() - 2 * you.getHeight() == text.getY()) {
                switch (text.getRule()) {
                    case TextLocation.BABA:
                        res.add(PeopleLocation.BABA);
                        break;
                    case TextLocation.FLAG:
                        res.add(PeopleLocation.FLAG);
                        break;
                    case TextLocation.ROCK:
                        res.add(PeopleLocation.ROCK);
                        break;
                    case TextLocation.WALL:
                        res.add(PeopleLocation.WALL);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    if (res.size() > 0) return res;

    return null;
}

下面便是规则判定的4个函数

/**
 * 判定 who is you
 * 即从上到下,从左到右的组合
 * 如果存在组合放置于list中,反之,返回null
 * @return
 */
public List<String> whoIsYou() {
    return whoIs(TextLocation.YOU);
}

public List<String> whoIsStop() {
    return whoIs(TextLocation.STOP);
}

public List<String> whoIsPush() {
    return whoIs(TextLocation.PUSH);
}

public List<String> whoIsWin() {
    return whoIs(TextLocation.WIN);
}

5.3 优化move逻辑

​ 由于我们的判定都可以有横向两种形式,而之前我们只是假定了一个变量,因此,这里我们重构代码为集合类型。

​ GameFrame中的变化:

    private void peopleMove(KeyEvent e) {
//        String stop = PeopleLocation.WALL; // 默认wall is stop
//        String push = PeopleLocation.ROCK; // 默认rock is push
//        String win = PeopleLocation.FLAG; // 默认flag is win

        List<String> stop = gameText.whoIsStop();
        List<String> push = gameText.whoIsPush();
        List<String> win = gameText.whoIsWin();

        List<String> youList = gameText.whoIsYou();
        if (youList == null) {
            System.out.println("游戏失败");
            return;
        }

        /**
         * 遍历循环(添加GamePeople的getPeopleList()方法)
         * 寻找可以移动的角色
         */
        List<People> peopleList = gamePeople.getPeopleList();
        for (int i = 0; i < peopleList.size(); i++) {
            People people = peopleList.get(i);
            for (int j = 0; j < youList.size(); j++) {  // 遍历可控制的角色
                String you = youList.get(j);
                if(you.equalsIgnoreCase(people.getName())) {
                    switch (e.getKeyCode()) {
                        case KeyEvent.VK_UP:
                            gamePeople.move(1,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_DOWN:
                            gamePeople.move(-1,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_RIGHT:
                            gamePeople.move(2,people,stop,push, win,gameText);
                            break;
                        case KeyEvent.VK_LEFT:
                            gamePeople.move(-2,people,stop,push, win,gameText);
                            break;
                    }
                }
            }

        }
    }

GamePeople的变化:

public void move(int direction, Block you, List<String> stop, List<String> push, List<String> win , GameText gameText) {
    /**
     * 先移动
     */
    switch (direction) {
        case 1:
            you.up = true;
            you.down = you.right = you.left = false;
            you.setY(you.getY() - 24);//y -= 24;
            break;
        case -1:
            you.down = true;
            you.up = you.right = you.left = false;
            you.setY(you.getY() + 24);//y += 24;
            break;
        case 2:
            you.right = true;
            you.up = you.down = you.left = false;
            you.setX(you.getX() + 24);//x += 24;
            break;
        case -2:
            you.left = true;
            you.up = you.right = you.down = false;
            you.setX(you.getX() - 24);//x -= 24;
            break;
    }

    /**
     * stop逻辑
     */
    if (stop != null && stop.size() > 0) {
        for (int i = 0; i < stop.size(); i++) {
            String s = stop.get(i);
            List<People> stopList = this.peopleMap.get(s);

            for (int j = 0; j < stopList.size(); j++) { // 遍历所有不可动的对象判断
                People stopPeople = stopList.get(j);
                if(stopPeople.getX() == you.getX() && stopPeople.getY() == you.getY()) { // 发生碰撞
                    // 反弹
                    if (you.up) {
                        you.setY(you.getY() + 24);//y += 24;
                    } else if (you.down) {
                        you.setY(you.getY() - 24);//y -= 24;
                    } else if (you.right) {
                        you.setX(you.getX() - 24);//x -= 24;
                    } else if (you.left) {
                        you.setX(you.getX() + 24);//x += 24;
                    }
                    return;// 优化
                }
            }

        }
    }


    /**
     * push逻辑
     */
    if (push != null && push.size() > 0) {
        for (int i = 0; i < push.size(); i++) {
            String s = push.get(i);

            List<People> pushList = this.peopleMap.get(s);
            for (int j = 0; j < pushList.size(); j++) { // 遍历所有Push的对象判断
                People pushPeople = pushList.get(j);
                if (pushPeople == you) continue;
                if (pushPeople.getX() == you.getX() && pushPeople.getY() == you.getY()) { // 发生碰撞
                    move(direction, pushPeople, stop, push,win, gameText);
                }
            }
        }
    }


    /**
     * text推动逻辑
     */
    List<Text> textList = gameText.getTextList();
    for (int i = 0; i < textList.size(); i++) {
        Text text = textList.get(i);
        if(text == you) continue;
        if(text.getX() == you.getX() && text.getY() == you.getY()) {
            move(direction, text, stop, push,win, gameText);
            return;
        }
    }


    /**
     * win逻辑
     */
    if(win != null && win.size() > 0) {
        for (int i = 0; i < win.size(); i++) {
            String s = win.get(i);

            List<People> winList = this.peopleMap.get(s);
            for (int j = 0; j < winList.size(); j++) {
                People winPeople = winList.get(j);
                if(winPeople.getX() == you.getX() && winPeople.getY() == you.getY()) {
                    System.out.println("胜利了");
                    return;
                }
            }
        }
    }


}

​ 至此,我们完成了游戏规则判定的逻辑,我们游戏的所有逻辑基本完成(此外,游戏还有flag is baba等的角色切换逻辑,这个我们之后编写),下面我们首先进行地图位置坐标的优化。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>