如何简化多个IF语句?

时间:2019-11-19 14:52:00

标签: java android libgdx game-development

我正在用Java编写一个简单的小行星游戏。并找到这个问题(不是一个真正的问题,我的解决方案可以正常工作,但是看起来很丑)。我只想知道有没有一种方法可以简化我的代码。

我的游戏中有一些物体。船,流星,子弹和硬币。它们都是 GameObject 的子类。要处理碰撞,在 MyGame 类中,我具有这些功能。

private void ship_hit_meteor(Ship ship, Meteor meteor){}
private void bullet_hit_meteor(Bullet bullet, Meteor meteor){}
private void ship_hit_coin(Ship ship, Coin coin){}
//...and so on

为了进行冲突检查,我将所有对象放入1个大的 objArray 中。 然后,我迭代数组以检查冲突。我就是这样做的:但是想像一下我是否有100种对象。

//inside the collision loop
GameObject a = objArray[i];
GameObject b = objArray[j];
if(a instanceof Ship && b instanceof Meteor ){
    ship_hit_meteor((Ship)a, (Meteor)b);
}
else if(a instanceof Meteor && b instanceof Ship){
    ship_hit_meteor((Ship)b, (Meteor)a);
}
else if(a instanceof Bullet && b instanceof Meteor){
    bullet_hit_meteor((Bullet)a, (Meteor)b);
}
else if(a instanceof Meteor && b instanceof Bullet){
    bullet_hit_meteor((Bullet)b, (Meteor)a);
}
//... end of the loop

有什么方法可以简化这个过程吗?

谢谢。

4 个答案:

答案 0 :(得分:1)

如果您有100种类型的对象,那么您会发现自己编写了5050种方法,如果您为每种对象类型组合编写了单独的方法。 (如果有n个类型,则公式为n(n-1)+n方法)。而且,这甚至都没有考虑到如何分配给正确的人,这就是您在这里所努力的目标。

一种更好的方法是拥有一种通用的碰撞处理方法,该方法知道如何基于碰撞对象的属性来处理所有碰撞。然后,可以将这些属性表示为方法,以及允许碰撞逻辑操作碰撞对象的方法。例如

public interface Collides {
    // properties
    int damageDealtOnImpact();
    boolean isReward();
    boolean isIndestructible();
    boolean isDestroyedOnImpact();

    // impact methods
    void damage(int damage);
    void destroy();
    void split();
    void changeCourse(Vector impactVector);

    // ... and so on, whatever you need
}

这样,添加对象的类型应该相对容易。尽管有时对于新类型的对象可能需要新的属性。在这种情况下,您的通用冲突处理方法将受到影响,并且您可能需要在现有对象上实现额外的属性。但是它比添加101种新方法并分派给它们要好得多。

答案 1 :(得分:0)

也许您可以创建一个接口,比如说“ SpaceObject”,并且所有与之交互的类都可以实现它。接口具有方法handleCollision(),并且类应重写它。在那里,您将碰撞逻辑,损坏等置于其中。将其放入HandlerService(代码段所在的位置)中,您仅会收到一个SpaceObjects列表并调用它们的handleCollision方法。

答案 2 :(得分:0)

尽管我对Java一无所知,但是我认为您的代码需要对子例程的组织有所思考。我宁愿为每个对象定义1个自己的“命中”过程。在主要流程中,对照有效的对象名称列表检查第一个对象,然后使用参数2调用相应的“ object.hitting”。检查参数的有效性将输出单个数字或0,您可以在此处“切换”。

答案 3 :(得分:0)

您首先使用一些四叉树库检查碰撞,而无需参考对象类型。

查看此答案 Quadtree for 2D collision detectionEfficient (and well explained) implementation of a Quadtree for 2D collision detection

然后-..您可以自己过滤碰撞。

https://www.iforce2d.net/b2dtut/collision-filtering

因此设置对象ID

public static final short xUSER_SHIP      = 0x0001;
public static final short xUSER_BULLET    = 0x0002;

和通过碰撞的任何事物的逻辑或创建的碰撞类别掩码

public static final short USER_SHIP_MASK = xPICKUP | xWALL | xENEMY_SHIP;

(记住,您必须声明A击中B,B击中A。

然后在碰撞列表中实现

bool collide =
          (filterA.maskBits & filterB.categoryBits) != 0 &&
          (filterA.categoryBits & filterB.maskBits) != 0;

但是,完成了所有这些工作之后,它需要进行很多工作。您可能更喜欢每个正方形的课程网格,它比任何单个对象(硬币,小行星等)大。每个对象在此主网格上更新其x,y位置。对于每个对象,在路线网格上查找其封闭的正方形(它可能与它的直接所有者重叠,但不能越过周围的单元格)以进行碰撞检出“基于网格的碰撞检测”或“基于瓷砖的碰撞检测”。这将是最简单的,您可以实现自己,但是您喜欢p.s。如果您将所有内容都视作碰撞的圈子,那就更容易了。