2009-12-09 11 views
7

Estoy construyendo un juego con QT. Todos los objetos en mi GraphicsScene heredan de GraphicsPixmapItem (Player, Obstacles, Bombs ...). Me gustaría implementar los efectos de colisión. Por ejemplo, cuando el jugador obtiene un bono, puede elegirlo. Con el marco de QT puedo obtener los elementos de collidings, pero no sé qué tipo son, ya que no hay instancia de función. Algun consejo ?¿Cómo implementar efectos de colisión en un juego?

editar: Tengo el "evento" de colisión, lo que quiero hacer es manejar las diferentes colisiones. Hice otro question con una mejor redacción.

Respuesta

9

consideraciones de diseño:

No puedo recomendar heredar Los objetos del juego de su representación gráfica. ¿Por qué? Es posible que desee tener múltiples representaciones gráficas de un objeto del juego (como una en la vista del juego u otra en minimapa, o lo que sea). La relación es "Jugador" tiene una "representación gráfica" y no "Jugador" es una "representación gráfica". La mejor solución es usar composición y no herencia. Otro efecto agradable es la posible encapsulación de otras detecciones de colisión si no estás contento con uno provisto por Qt, desacoplamiento, ... La verdad también es que para juegos simples puede ser suficiente.

Para una lógica de juego lo suficientemente simple, la herencia donde otros objetos reaccionan al objeto activo. Probablemente demasiado simplista para cualquier mecánica de juego más compleja.

class Asteroid { 
public: 
    virtual void CollideWithPlayer(Player&) { p.loseHealth(100); } 
}; 

class ExplodingAsteroid: Asteroid { 
public: 
    virtual void CollideWithPlayer(Player&) { explode(); p.loseHealth(1000); } 
}; 

Si la interacción se pone (muchos objetos activos comportarse por sí mismos) complejos puede que tenga que identificar sus objetos:

  • Hay'S es RTTI, pero erm es difícil lo recomienda: How expensive is RTTI? En corto: costoso, difícil de mantener.

  • Puede usar el envío doble. Identifica objetos usando dos llamadas virtuales. Problemas: bastante sintaxis, a veces es difícil de mantener (especialmente cuando se agregan objetos nuevos), problemas de propiedad (ver más). ejemplo del juego de Wikipedia:


class SpaceShip {}; 
class GiantSpaceShip : public SpaceShip {}; 

class Asteroid { 
public: 
    virtual void CollideWith(SpaceShip&) { 
    cout << "Asteroid hit a SpaceShip" << endl; 
    } 
    virtual void CollideWith(GiantSpaceShip&) { 
    cout << "Asteroid hit a GiantSpaceShip" << endl; 
    } 
}; 

class ExplodingAsteroid : public Asteroid { 
public: 
    virtual void CollideWith(SpaceShip&) { 
    cout << "ExplodingAsteroid hit a SpaceShip" << endl; 
    } 
    virtual void CollideWith(GiantSpaceShip&) { 
    cout << "ExplodingAsteroid hit a GiantSpaceShip" << endl; 
    } 
}; 

  • "enumeración"

virtual de la función Identificación del

class GameObject() { 
    virtual getId() { return GAME_OBJECT; } 
}; 

class Asteroid() { 
    virtual getId() { return ASTEROID; } 
}; 

o como miembro

class GameObject() { 
    ID getId() { return id; } 
protected: 
    GameObject(ID id):id(id) {} 
private: 
    ID id; 
}; 

o el uso de la plantilla con la inicialización automática de Identificación (un poco de sintaxis alucinante, vamos a omitir: o)

  • y otros

Ahora para bucle de juego como este:

for each object 
    update by (fixed) time step 
    detect collisions and resolve them 

se encontrará con:

problemas Propiedad:

jugador pierde la salud al ser golpeado por asteroides y asteroides se destruye después ..

Asteorid::collideWithPlayer(Player& p) { p.loseHealth(100); this->explode(); } 

consideran ahora también

Player::collideWithAsteroid(Asteroid& a) { this->loseHealth(100); a.explode(); } 

resultado: duplicidad de código o mecánica de juego incierta

solución

del hombre pobre: ​​llamar a otra persona para ayudarle a: o)

Asteorid::collideWithPlayer(Player& p) { resolveCollision(p, *this); } 
Player::collideWithAsteroid(Asteroid& a) { resolveCollision(*this, a); } 
resolveCollision(Player, Asteroid) { p.loseHealth(100); a.explode(); } 
+0

+1 para disertación excelente. Las imágenes lo mejorarían. ;-) –

+0

muchas gracias por su explicación. ¿Es cierto que C++ no es una buena opción para el desarrollo de juegos? – amirouche

+2

C++ es una de las MEJORES opciones para juego dev IMO. Tiene más control sobre la memoria y acceso a llamadas de bajo nivel cuando sea necesario. Pero estoy predispuesto ya que nunca intenté hacer un juego en nada excepto C++ y java. –

4

una idea:
Herencia: cada objeto un jugador puede chocar con tiene un método CollideWithPlayer que hace cualquiera que sea el objeto necesita

C++ como pseudo código, por ejemplo,

class Item : GameObject { 
public: 
    CollideWithPlayer(Player p); 
} 

class PointBag : Item { 
public: 
    CollideWithPlayer(Player p) { p.points += 5000; } 
} 
1

Usted podría usar una biblioteca externa como Nvidia PhysX o Bullet que le permitiría establecer devoluciones de llamadas para cuando ocurran las colisiones. Al usar tales bibliotecas, que no usarían el sistema de colisión de Qt, en cada fotograma simularía la física y luego actualizaría las propiedades del elemento GraphicsPixmap para reflejar su estado dentro de la simulación física.

0

Puede echar un vistazo a la siguiente Qt Ejemplo: Colliding Mice Ejemplo.

Es bastante fácil y te dará una buena introducción al manejo básico de colisiones con Qt.

resume rápidamente, cada objeto tendrá un cuadro delimitador que le dará el espacio que utiliza ... A continuación, utiliza estos cuadros delimitadores saber si los elementos están en contacto con los demás o no ...

Espero que esto ayude !

+1

http://doc.trolltech.com/4.6/graphicsview-collidingmice.html –

+0

http://web.archive.org/web /20100409105849/http://doc.trolltech.com/4.6/graphicsview-collidingmice.html – Fuhrmanator

Cuestiones relacionadas