2012-04-11 22 views
15

Quiero aprender a crear buenas prácticas de diseño orientado a objetos (OO) para la colisión entre dos situaciones de objetos en el desarrollo del juego.Good Object Oriented Class Design para la detección de colisiones en el desarrollo de juegos

Digamos que tengo una clase SpaceShip y una clase Meteor. Cuando Meteor choca con la Nave Espacial, la Nave Espacial será destruida.

La pregunta: ¿Qué clase debo poner el método para verificar si hay una colisión entre meteorito y nave espacial, así como el método de resolución de colisión (destruir la nave espacial)? ¿Es en la clase SpaceShip o en la clase Meteor? O tal vez debería poner en otra clase, es decir. ¿Clase GameArea o GameController?

Nota: en aras de la simplicidad, suponga que Meteor y SpaceShip están en forma de recurso de imagen. Estoy acostumbrado a usar el lenguaje Java, pero el otro lenguaje también está bien.

+0

Votaría para implementar la detección de colisiones en 'GameController' (o cualquier clase es la gestión de su área de juego), con un' collidedWithObject (GameObject theObject) 'método en' Meteor' y 'SpaceShip' (y cualquier otro objeto que pueda colisionar con cosas) que se llame para notificar a los objetos de una colisión. – aroth

+0

Gracias por su voto. ¿Conoces por casualidad un buen tutorial o libro sobre el diseño de juegos orientado a objetos? – null

Respuesta

1

Bueno, generalmente creo una clase o interfaz (a veces genérica) GameObject que tiene un método collides. Por ejemplo:

template< typename T = int > class GameObject 
{ 
public: 
    bool collides(const GameObject& obj); 
}; 

// usage 
GameObject<int> my_obj, your_obj; 
if(my_obj.collides(your_obj)) { ... }; 

Otra cosa a veces (pero raramente) que hago es crear una clase separada GamePhysics:

template< typename T > class GamePhysics 
{ 
public: 
    /* you may make this static or the class a singleton */ 
    void detect_collision(const T& obj, const T& obj2); 
}; 
+0

Thx. ¿Dónde colocarías el "if (my_obj.collides (your_obj)) {...};" ¿código? ¿Control de juego? – null

+1

@suud en cualquier lugar que necesite para detectar colisiones. el lazo principal, el GameController, el procesador de teselas, etc. – ApprenticeHacker

2

detección de colisiones, en mi opinión, no es parte de un objeto ... debe definirse como algo más: algún administrador de física, etc. De esta forma, sus objetos serán independientes en los algoritmos de colisión.

Otra cosa es que en los juegos, por lo general, el objeto consta de varias capas (componentes): capa de gráficos, capa de física, capa lógica. De esta manera, el administrador de física administra solo el componente de física de objetos determinados.

class GameObject 
{ 
    RenderComponent m_renderComponent; 
    LogicComponent m_aiComponent; 
    PhysicsComponent m_physicsComponent; 
}; 
+0

¿Quiere decir que la lógica de colisión debería residir en la clase PhysicsComponent? – null

+1

sí ... el componente de colisión (por ejemplo, un cuadro delimitador) puede estar dentro del componente de física. – fen

10

Es más natural pensar que la detección de colisiones es una responsabilidad que no pertenece a la nave espacial o Meteor clases. Especialmente cuando esto se complica con múltiples posibilidades de colisión en diferentes direcciones. Si pones esta lógica en ambas clases, necesitarán tener referencias a muchos otros objetos que están a su alrededor que no serían apropiados.

Puede tener esto en una clase separada como CollisionDetector que realiza un seguimiento de las coordenadas de todos los objetos en el espacio del juego y detecta colisiones. La prevención de colisiones también parece ser una responsabilidad separada que debería estar en una clase diferente en mi opinión. Puede tener una clase separada CollisionResolver para esto. Dependiendo de los requisitos, CollisionDetector podría hablar con CollisionResolver.

CollisionResolver puede tener que ser capaz de hablar con naves espaciales, para fines tales como asesorar a cambiar de dirección, o para ordenar disparar misiles hacia el Meteor.

CollisionDetector y CollisionResolver podía sentarse dentro del espacio de juego /* GameController *. etc.

Esto promocionaría Single Responsibility Principle por lo que cada componente estaría haciendo solo una tarea enfocada.

0

En Java (o en cualquier otro lenguaje OO) colocaría un CollisionDetected devolución de llamada/evento en la clase antepasado común de todos los objetos en movimiento de su juego.

Ésta es una descripción simplificada de un juego:

  • En un juego, por lo general hay un juego bucle. Un bucle de juego es como un mientras que (verdadero) bucle que se ejecuta de forma continua (algo así como el hilo de UI principal de una aplicación) y en cada paso comprueba qué ha cambiado con los objetos, qué debe actualizarse y qué eventos deberían ser llamado (y más ...).

  • Para la capacidad de respuesta, este ciclo debe ciclar varias veces por segundo.

  • Dentro de este bucle, un objeto Motor de física debe actualizar continuamente su estado. Este sería un objeto instancia de una clase independiente. Es este motor el que debería detectar colisiones entre objetos y llamar al evento CollisionDetected en todos los objetos que han colisionado.

Es una idea, no la solución definitiva ...

Cuestiones relacionadas