How to implement collision effects in the game?

I am creating a game with QT. Each GraphicsScene object inherits from GraphicsPixmapItem (Player, Obstacles, bombs ...). I would like to use collision effects. For example, when a player receives a bonus, he can select it. Within QT, I can get collidings elements, but I don’t know what type they are, since the instanceof function is missing. Any tips?

edit: I get a collision "event" that I want to do is handle different collisions. I made another question with better wording.

+7
c ++ qt
source share
4 answers

Design considerations:

I cannot recommend inheriting Game objects from their graphical representation. What for? You might want to have several graphic images of one game object (for example, in game mode or in a minimap or something else). The "Player" relationship has a "graphical representation", not the "Player" - this is a "graphical representation". The best solution is to use composition, not inheritance. Another nice effect is the possibility of encapsulating another collision detection, if you are unhappy with the fact that Qt is provided, decoupling ... It is also true that for a simple game this may be enough.

For a fairly simple game logic, inheritance is when other objects respond to the active object. Probably too simplistic for any more complex game mechanics.

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

If the interaction becomes complicated (many active objects behave on their own), you may need to define your objects:

  • There is RTTI, but is it not recommended that you recommend: How much does RTTI cost? In short: expensive, hard to maintain.

  • You can use double dispatch. Identifies objects using two virtual calls. Problems. Just a little syntax, sometimes difficult to maintain (especially when you add new objects), property rights issues (see more). Wikipedia game example:


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

  • "listing"

virtual id function

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

or as a member

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

or using a template with automatic id initialization (small syntax for the mind, leave it: o)

  • and others

Now for the game loop:

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

you will encounter:

Ownership Issues:

the player loses health when hit by an asteroid, and the asteroid is subsequently destroyed.

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

now consider also

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

: duplicity of code or fuzzy game mechanics

The solution for the poor: call someone else to help you: o)

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

one idea:
Inheritance Each object that a player may encounter has a CollideWithPlayer method that does whatever the object requires.

C ++ e.g. psuedo code

 class Item : GameObject { public: CollideWithPlayer( Player p ); } class PointBag : Item { public: CollideWithPlayer( Player p ) { p.points += 5000; } } 
+4
source share

You can use an external library, such as Nvidia PhysX or Bullet, which allows you to configure callbacks in case of conflict. Using libraries that will not use the Qt collision system, instead, each frame will simulate physics and then update the GraphicsPixmapItem properties to reflect their state in the physical simulation.

+1
source share

You can see the following Qt example: Colliding Mice example.

It's quite simple, and it will give you a pretty nice introduction to basic Qt collision handling.

Quickly summarizes, each object will have a bounding box that will give you the space that it uses ... Then you will use these bounding boxes to find out if the elements are touching each other or not ...

Hope this helps!

0
source share

All Articles