【问题标题】:Java game programming: multiple instances of an object, treat same way?Java游戏编程:一个对象的多个实例,以同样的方式对待?
【发布时间】:2012-10-22 21:49:34
【问题描述】:

对不起,如果标题没有多大意义。我在 Java Eclipse 中制作了一个 Chip's Challenge 风格的游戏,其中像 Player、硬币和可推动块这样的特殊事物是一类。可推块和玩家之间的交互需要大量的碰撞检测逻辑,而且代码变得很糟糕,因为我必须对类的每个实例进行相同的逻辑检查。例如:

public void pb1TouchingBaddy() {

    if (pb1.getTileX() == b1.getTileX() & pb1.getTileY() == b1.getTileY()) {
        if (b1.getbUp() == 1 & pb1.getTileY() - 1 != pb2.getTileY()) {
            pb1.move(0, -1);
        } else if (b1.getbDown() == 1
                & pb1.getTileY() + 1 != pb2.getTileY()) {
            pb1.move(0, 1);
        } else if (b1.getbRight() == 1
                & pb1.getTileX() + 1 != pb2.getTileX()) {
            pb1.move(1, 0);
        } else if (b1.getbLeft() == 1
                & pb1.getTileX() - 1 != pb2.getTileX()) {
            pb1.move(-1, 0);
        }
    }

    if (pb1.getTileX() == b2.getTileX() & pb1.getTileY() == b2.getTileY()) {
        if (b2.getbUp() == 1 & pb1.getTileY() - 1 != pb2.getTileY()) {
            pb1.move(0, -1);
        } else if (b2.getbDown() == 1
                & pb1.getTileY() + 1 != pb2.getTileY()) {
            pb1.move(0, 1);
        } else if (b2.getbRight() == 1
                & pb1.getTileX() + 1 != pb2.getTileX()) {
            pb1.move(1, 0);
        } else if (b2.getbLeft() == 1
                & pb1.getTileX() - 1 != pb2.getTileX()) {
            pb1.move(-1, 0);
        }
    }

    if (pb1.getTileX() == b3.getTileX() & pb1.getTileY() == b3.getTileY()) {
        if (b3.getbUp() == 1 & pb1.getTileY() - 1 != pb2.getTileY()) {
            pb1.move(0, -1);
        } else if (b3.getbDown() == 1
                & pb1.getTileY() + 1 != pb2.getTileY()) {
            pb1.move(0, 1);
        } else if (b3.getbRight() == 1
                & pb1.getTileX() + 1 != pb2.getTileX()) {
            pb1.move(1, 0);
        } else if (b3.getbLeft() == 1
                & pb1.getTileX() - 1 != pb2.getTileX()) {
            pb1.move(-1, 0);
        }
    }

    if (pb1.getTileX() == b4.getTileX() & pb1.getTileY() == b4.getTileY()) {
        if (b4.getbUp() == 1 & pb1.getTileY() - 1 != pb2.getTileY()) {
            pb1.move(0, -1);
        } else if (b4.getbDown() == 1
                & pb1.getTileY() + 1 != pb2.getTileY()) {
            pb1.move(0, 1);
        } else if (b4.getbRight() == 1
                & pb1.getTileX() + 1 != pb2.getTileX()) {
            pb1.move(1, 0);
        } else if (b4.getbLeft() == 1
                & pb1.getTileX() - 1 != pb2.getTileX()) {
            pb1.move(-1, 0);
        }
    }

所以你可以看到这三个 if 语句块都是完全相同的逻辑,只是应用于同一对象的不同实例。有什么方法可以写这个而不必重复自己这么多?我能够将四个方向的运动逻辑变成一种方法,并一度认为自己是个天才,但我不知道如何做类似的事情,但要使用同一个对象的多个实例。现在,在我太困惑并且无法为另一个块做逻辑之前,我只被两个可推动的块卡住了。希望有任何建议,谢谢!

【问题讨论】:

  • 编写一个方法,该方法采用 b1b2b3b4 的任何对象的实例,并以这种方式执行检查。
  • 那么有什么方法可以将对象的实例传递给方法吗?

标签: java coding-style


【解决方案1】:
private function move(PBClass pb1, PBClass pb2, BClass b) {
    if (pb1.getTileX() == b.getTileX() & pb1.getTileY() == b.getTileY()) {
        if (b.getbUp() == 1 & pb1.getTileY() - 1 != pb2.getTileY()) {
            pb1.move(0, -1);
        } else if (b.getbDown() == 1
                & pb1.getTileY() + 1 != pb2.getTileY()) {
            pb1.move(0, 1);
        } else if (b.getbRight() == 1
                & pb1.getTileX() + 1 != pb2.getTileX()) {
            pb1.move(1, 0);
        } else if (b.getbLeft() == 1
                & pb1.getTileX() - 1 != pb2.getTileX()) {
            pb1.move(-1, 0);
        }
    }
}

public void pb1TouchingBaddy() {
    move(pb1, pb2, b1);
    move(pb1, pb2, b2);
    move(pb1, pb2, b3);
    move(pb1, pb2, b4);
}

当然,您需要将 PBClassBClass 替换为您的实际类名。

如果你有一个对象数组:

PBClass[] listPB = { pb1, pb2, pb3, pb4};
BClass[] listB = { b1, b2, b3, b4};

public void pb1TouchingBaddy() {
    for (int i=0; i < listPB.length - 1; i+=2) {
        for (int j=0; j < listB.length; j++) {
            move(pb[i], pb[i+1], b[j]);
        }
    }
}

或者你可以用同样的方式使用ArrayLists

【讨论】:

  • 我的意思是我想要某种方式,我不必每次都写“pb1”“pb2”等。所以从技术上讲,我可以让实例达到“pb100”,而不必在任何地方写 pb59、pb60、pb61 等。
  • 您的pbs 在列表中吗? bs 呢,只有四个吗?
  • 我很抱歉,很确定这完全回答了我的问题。太愚蠢了,没有意识到你已经将我的代码减少了 1/3:D 谢谢!打算尝试实现这个系统,看看游戏是否仍然表现相同,非常感谢!
  • 帮了很多忙,这就是我最终得到的结果,真棒项目变得多么小:编辑:好吧,不能在这个 lil 盒子里添加那么多,但相信我的话!跨度>
【解决方案2】:

将这些方法放在一个接口中,并使它们都实现该接口。

让您的方法只对那个接口感兴趣,而不用担心实际的具体类型可能是什么。

【讨论】:

    【解决方案3】:

    您需要某种Iterable 集合。这样你就可以循环遍历它了。

    【讨论】:

    • 但是还是要写pb1、pb2、pb3等?我不能只做 pbX 并传入 X 吗?我可以做一些像你写的那样的事情,但这不是我遇到的问题。我只是想概括对象代码,因此玩家将以相同的方式对待对象的所有实例,而无需我为每个实例明确说明并添加 50 亿行代码。
    • 你需要循环。创建一个实现Iterable 或具有某种Iterator 的类。或者使用Collection的一些子类。
    • 对不起,您的代码答案实际上帮了很多忙,我只是没有意识到它在做什么。想试试这种风格,谢谢!也要去看看 Collections,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多