java swing实战——baba is you(push逻辑实现)

4.4 ROCK is PUSH

​ 此时,大家可能对于Map的引入比较疑惑,最初我们使用List,但是List并不能很好的区分出不同的People(既baba、rock、flag和wall),这里,我们改用Map存取4种对应的List,这样对于不同角色可以进行更加方便地操作。

4.4.1 默认rock is push(专注于push逻辑实现)

​ 本节我们进行Push逻辑的代码实现,首先为了简化,我们依旧先默认rock is push,同样这样的默认规则在GameFrame中以如下方式说明

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

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

4.4.2 push逻辑实现

在GamePeople 的move方法中增加如下关于碰撞的代码

/**
 * push逻辑
 */
List<People> pushList = this.peopleMap.get(push);
for (int i = 0; i < pushList.size(); i++) {
    
     // 遍历所有Push的对象判断
    People pushPeople = pushList.get(i);
    if (pushPeople.getX() == you.getX() && pushPeople.getY() == you.getY()) {
    
     // 发生碰撞

    }
}

下面增添碰撞后的细节:

  • 推动方向没有障碍物时,推动箱子时,箱子需要和推动者同向移动一格
  • 如果被推动物体遇到stop物体或者墙体,物体无法通过

​ 一种思路是:此时,我们在推动时需要判断下一个物块是否为push或者是stop,如果是push则要判断push的下一个是push或者是stop,如此递归。

​ 如果push的下一块既不是stop也不是push,那么都可以移动;如果下一块是stop,则都不可移动;如果是push则递归进行下一次判断。

​ 因此,我们需要改变之前先移动后反弹的规则,即先判断下一块,后移动。

但这里,作者使用了一种取巧的办法,依旧是先移动,后碰撞反弹
在这里插入图片描述

代码角度,便是添加如下递归方法

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

此时的问题是,如果发生递归,pushPeople和自己一定是重合(碰撞),会陷入无限递归,因此我们要判断排除

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

​ 如此,我么以一种取巧的办法实现了推箱子,当然,这样的处理与原版游戏有仍然有一定的差异,但是对于自己制作的游戏,我们不妨就认为这个是我们的特性。当然,大家有兴趣也可以尝试先判断后移动的策略。

下面是一段展示,之后我们以同样的规则作用Text即可实现文字块的推动

这是目前效果视频(阿里云盘) https://www.aliyundrive.com/s/783pdoYvtcv

猜你喜欢

转载自blog.csdn.net/m0_46565757/article/details/122378697

相关文章