我正在开发一款小游戏,现在我需要实现一些碰撞检测。我正在为我的所有游戏对象使用一个链表。我区分这些对象的方法是使用对象ID。我能够成功检测到具有不同ID的对象的冲突,但我无法有效地使用具有相同ID的对象。如果有一种简单的方法可以让我徘徊,也许有人可以给我一个例子。或者我可能只需要更多if语句。下面的代码正在运行,但正如您所看到的,每个对象的对象ID都不同。有没有办法修改此代码,以便它可以使用相同的ID。例如,我想知道敌人何时相互接触,以便我能够检测到并采取相应行动。
public void Collision(LinkedList<GameObject> object, Graphics g){
for(int i = 0; i < handler.object.size(); i++){
GameObject enemy = handler.object.get(i);
for(int j = 0; j < handler.object.size(); j++){
GameObject tempObject1 = handler.object.get(j);
if(enemy.getId() == ObjectId.Enemy && tempObject1.getId() == ObjectId.Bullet){
if(getBounds().intersects(enemy.getBounds())){
handler.removeObject(enemy);
handler.removeObject(tempObject1);
}
}
}
}
}
答案 0 :(得分:0)
嗯,伙计,你需要实现equals和hash代码,并验证它们是否正常运行单元测试。
两个主要的IDE都会为您生成代码。在Joshua Bloch的Effective Java中也有一个很好的讨论。
What issues should be considered when overriding equals and hashCode in Java?
永远不应该检查ID的等号。
答案 1 :(得分:0)
这是一个需要重新分解代码的答案。它使用已知模式来解决碰撞及其检测问题。假定存在的GameObject
类应该有intersects
方法。
我可能会使用碰撞调度程序接口实现一个碰撞侦听器接口,并在我需要的地方使用它们。
接口将具有以下方法:
CollisionListener
是需要了解冲突的类实现的接口:
public interface CollisionListener {
// respond to a collision event
public void collisionEvent(CollisionEvent ce);
}
CollisionDispatcher
是发现和通知其他人实施冲突的类的接口,以及其他注册的类。这可能是你的Game
类,或者那种类的主类。
interface CollisionDispatcher {
// add a collision listener who should be notified about each collision
public void addCollisionListener(CollisionListener cl);
// notify all subscribers (listeners) on collision event
public void notifyCollision(CollisionEvent ce);
}
我添加了一个实现两者的main的示例。你可能想要一些不同的东西。
这是部分代码:
private Collection<CollisionListener> cls;
private Collection<GameObject> gameObjects;
public Game(){
this.cls = new ArrayList<CollisionListener>();
this.addCollisionListener(this);
}
@Override
public void collisionEvent(CollisionEvent ce) {
System.out.println("Collision occured between "
+ ce.getGameObject1().toString() + " and "
+ ce.getGameObject1().toString());
}
@Override
public void addCollisionListener(CollisionListener cl) {
this.cls.add(cl);
}
@Override
public void notifyCollision(CollisionEvent ce) {
// notify to all listeners
for (CollisionListener cl : this.cls){
cl.collisionEvent(ce);
}
}
public void checkForCollisions(){
// check for collisions
for (GameObject go1 : gameObjects){
for (GameObject go2 : gameObjects){
// first part is ok cause we are looking for the same object
if (go1 != go2 && go1.interesects(go2)){
this.notifyCollision(new CollisionEvent(go1, go2));
}
}
}
}
CollisionEvent
类可能如下所示:
public class CollisionEvent {
private GameObject go1, go2;
public CollisionEvent(GameObject g1, GameObject g2){
this.go1 = go1;
this.go2 = go2;
}
public GameObject getGameObject1(){
return this.go1;
}
public GameObject getGameObject2(){
return this.go2;
}
}
我希望你觉得这很有用。如果你这样做,read more。
一个非常有用的优化是只有移动对象在移动时检查碰撞,这样你只需要一个循环:
// in GameObject
public void checkForCollisions(){
// check for collisions
for (GameObject go2 : gameObjects){
// first part is ok cause we are looking for the same object
if (this != go2 && this.interesects(go2)){
this.notifyCollision(new CollisionEvent(go1, go2));
}
}
}
如果这是您正在寻找的行为,您还可以通过直接通知碰撞的对象来优化(以设计为代价,why?)。这次CollisionEvent只能有一个参数(相应地重新考虑其余的代码),GameObject类将有notifyCollision
和collisionEvent
方法:
// in GameObject
public void checkForCollisions(){
// check for collisions
for (GameObject go2 : gameObjects){
// first part is ok cause we are looking for the same object
if (this != go2 && this.interesects(go2)){
go2.notifyCollision(new CollisionEvent(go2));
}
}
}
您也可以在没有事件对象的情况下直接在侦听器上调用方法。