在我的项目中我遇到了这个问题,我有一个抽象的实体类,它的子类是player,shot和敌人。我要检查他们之间有没有碰撞。一个单独的物理类正在使用以下代码进行碰撞评估:
public class Physics {
private static int height = 32;
private static int width = 32;
public static void collision(Entity entity, LinkedList<Entity> eList) {
for (int i = 0; i<eList.size(); i++) {
if (entity.getBounds(width, height).intersects(eList.get(i).getBounds(width, height))) {
entity.collidesWith(eList.get(i));
}
}
}
}
linkedlist包含快照和敌人,但是由于某些原因,碰撞只调用collideswith(实体)方法,而不是collideswith(快照b)或collideswith(敌人e)。
edit:提到的类(在本例中,只有我认为对它们很重要的代码)
实体:
public abstract class Entity {
protected double x;
protected double y;
public Entity (double x, double y) {
this.x = x;
this.y = y;
}
public abstract void tick();
public double getX() { return x; }
public double getY() { return y; }
public Rectangle getBounds(int width, int height) {
return new Rectangle((int)x, (int)y, width, height);
}
public abstract void collidesWith(Entity e);
public abstract void collidesWith(Enemy e);
public abstract void collidesWith(Shot s);
玩家:
public class Player extends Entity {
private boolean alive;
private int gameWidth, gameHeight;
private GameController gCont;
private Textures textures;
public Player( String name, int x, int y, int gameWidth, int gameHeight, Textures textures, GameController gCont) {
super(x,y);
this.name = name;
this.score = 0;
this.gameWidth = gameWidth;
this.gameHeight = gameHeight;
this.gCont = gCont;
this.textures = textures;
this.alive = true;
}
public void tick() {
gCont.collisionCheck(this);
}
public void collidesWith(Enemy e) {
System.out.println("Player collides with enemy");
this.alive = false;
}
public void collidesWith(Shot s) {
return;
}
public void collidesWith(Entity e) {
System.out.println("collided with entity");
return;
}
射击
public class Shot extends Entity {
private Textures textures;
private GameController gCont;
public Shot(double x, double y, Textures textures, GameController gCont) {
super(x, y);
this.textures = textures;
this.gCont = gCont;
}
public void tick() {
x+=10;
gCont.collisionCheck(this);
}
public void collidesWith(Entity e) {
return;
}
public void collidesWith(Enemy e) {
gCont.removeEntity(e);
gCont.removeEntity(this);
gCont.addScore();
}
@Override
public void collidesWith(Shot s) {
return;
}
敌人
public class Enemy extends Entity {
private int speed;
public Enemy(double x, double y) {
super(x, y);
Random random = new Random();
speed = random.nextInt(3)+1;
}
public void tick() {
x-=speed;
}
public void collidesWith(Entity e) {
return;
}
@Override
public void collidesWith(Enemy e) {
return;
}
@Override
public void collidesWith(Shot s) {
return;
}
如何让它调用正确的函数?
4条答案
按热度按时间cbjzeqam1#
我认为除了jamie bisotti指定的泛型类型之外,还有一个解决方案,就是使用接口和开关来检查哪个类是what。
这是一个接口,它声明了所有可能发生冲突的实体必须具有的方法:
然后,您希望能够碰撞的每个类都必须实现:
我更喜欢使用接口,这样我可以指定每个行为。目前看来一切都很简单,所有的东西都可以从实体抽象类中扩展出来,但是有那么一刻,您将通过许多其他特性来区分每个实体。
例如,一个飞行的敌人,一个行走的敌人,ecc ecc,你可以用一个接口来指定每个特征。
在这种情况下,接口也非常简单。但是您可以指定许多要实现的方法,例如
您可以在抽象实体类中实现som方法,但是抽象实体不应该知道它的子实体。这就是为什么要实现一些方法,直接在子对象中使用泛型“可合并”类型作为输入。
prdp8dxp2#
对我来说,实体类了解敌人和射击是错误的。
为什么不从实体和子类中删除这两个方法:
仅保留和实施:
如果需要知道作为参数传递的实体e的类型,可以使用反射,但这是一种糟糕的设计。最好实现collideswith,这样就不需要知道所传递参数的确切类型。
pgx2nnw83#
查看java的泛型。我想你可以用这样的方法:
xtfmy6hx4#
可能是错的,我对回答stackoverflow的问题还不熟悉。
希望这能让你明白:
entity.collidesWith(eList.get(i));
get(i)在那一行中,在物理类entity中返回一个entity类型的对象。这是因为它的定义如下:LinkedList<Entity> eList
这意味着,如果有一个重载接受该实体,它只会调用该方法。这正是我在你的代码里看到的。您有一个参数为:entity的“collideswith”的方法重载。在实体的所有子类中。我认为您应该多读一些关于“java多态性”的内容。