2014-01-03 1 views
-1

Я разрабатываю небольшую игру, и теперь я нахожусь в точке, где мне нужно реализовать некоторое обнаружение столкновения. Я использую один связанный список для всех своих игровых объектов. То, как я различаю эти объекты, - это использовать идентификатор объекта. Я могу успешно обнаружить столкновение с объектами с разными идентификаторами, но я не могу эффективно использовать объекты с тем же идентификатором. Я блуждал, если есть простой способ сделать это, и, возможно, кто-то может указать мне пример. Или, может быть, мне просто нужно больше, если заявления. Код ниже работает, но поскольку вы можете видеть, что идентификаторы объектов разные для каждого объекта. Есть ли способ изменить этот код, чтобы он работал с использованием одинаковых идентификаторов. Например, я хочу знать, когда враги касаются друг друга, чтобы я мог ее обнаружить и действовать соответствующим образом.связанное обнаружение столкновения списка с использованием того же идентификатора

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); 

      } 
     } 
     } 

    } 

} 
+1

Не знаком с проблемным пространством, с которым вы имеете дело, но я угадываю [Set] (http://java.sun.com/javase/6/docs/api/java/util/Set.html) идентификатор GameObjects может быть полезен? – hd1

+0

Где вы используете аргументы, переданные функции столкновения? Почему функция столкновения называется заглавными буквами, а не стандартами Java? Какова цель «Столкновения» в отношении его аргументов? –

ответ

0

Ум, чувак, вам нужно реализовать равные и хэш-коды и убедиться, что они работают правильно с модульным тестом.

Оба основных IDE генерируют код для вас. Там также прекрасное обсуждение этого в Joshua Bloch's Effective Java.

What issues should be considered when overriding equals and hashCode in Java?

никогда не должны проверять наличие равных идентификаторов.

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); 
} 

Я добавил пример основной, который реализует как. Возможно, вы захотите что-то другое.

Это частичный код:

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)); 
     } 
    } 
} 

Вы также можете использовать вызов методов на ваших слушателей непосредственно без объекта события.

+0

Спасибо, я нахожу ваш ответ очень полезным. На данный момент это кажется мне немного сложным, но я думаю, это из-за моей недостаточной практики в java. Однако я попытаюсь изо всех сил реализовать этот шаблон в моей игре ... – user3158909

+0

Убедитесь, что вы подходите под свои нужды. Я ни в коем случае не специалист, но я тоже не новичок. Соглашение об именах должно быть приоритетом, и первое, что вы можете сделать, это изменить имя вашего метода «Столкновение» на «столкновение». В отличие от C# или других языков программирования, метод в Java начинается с строчных букв и использует camelCase. –

Смежные вопросы