views:

375

answers:

4

I building a game with QT. Every objects on my GraphicsScene inherits from GraphicsPixmapItem (Player, Obstacles, bombs...). I would like to implment collision effects. For example when the player gets hover a bonus he can pick it. With the QT framework I can get the collidings items but I don't know which type they are as there isn't instanceof function. Any tips ?

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

+4  A: 

one idea :
Inheritance : Each object a player can collide with has a CollideWithPlayer method that does whatever the object needs

c++ like psuedo code for example

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

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

You could use an external library like Nvidia PhysX or Bullet which would let you set up callbacks for when collisions occur. By using such libraries, who would not use Qt's collision system, instead, every frame you would simulate the physics and then update the properties of the GraphicsPixmapItem to reflect their state within the physics simulation.

Maxime
A: 

Hey,

You could have a look at the following Qt Example : Colliding Mice Example.

It's quite easy and it will give you a pretty much nice introduction to basic collisions handling with Qt.

Quickly summarized, each object will have a bounding box that will give you the space it uses... You'll then use these bounding boxes to know whether items are touching each others or not...

Hope this helps !

Andy M
http://doc.trolltech.com/4.6/graphicsview-collidingmice.html
Adam W
+8  A: 

Design considerations:

I can't recommend inheriting Game objects from their graphic representation. Why? You may want to have multiple graphic representations of one game object (like one in game view or another one in minimap, or whatever). The relation is "Player 'has-a' graphic representation" and not "Player 'is-a' graphic representation". Better solution is to use composition and not inheritance. Other nice effect is possible encapsulation of other collision detection if you are not happy with one provided by Qt, decoupling, ... Truth also is, that for simple game it can be sufficient though.

For simple enough game logic, inheritance where other objects react to 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 interaction gets complex(many active objects behaving on their own) you may need to identify your objects:

  • There's is RTTI, but erm it's hard to recommend see: http://stackoverflow.com/questions/579887/how-expensive-is-rtti In short: expensive, hard to maintain.

  • You can use double-dispatch. Identifies objects using two virtual calls. Problems: Quite a bit of syntax, sometimes difficult to maintain (especially when you add new objects), ownership problems (see more). Game example from 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;
  }
};


  • "enumeration"

virtual function id

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 template with auto initialization of id (a little mind-boggling syntax, let's omit it :o)

  • and others


Now for game loop like this:

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

you will encounter:

Ownership problems:

player loses health when being hit by asteroid and asteroid is destroyed afterwards..

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

now consider also

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

result: code duplicity or unclear game mechanics

poor man's solution: 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(); }
MaR
+1 for excellent dissertation. Pictures would make it better. ;-)
Thomas Matthews
thanks a lot for your explanation. Is that true that c++ is not that a good choice for game dev ?
phmr
c++ is one of the BEST choices for game dev IMO. You have more control over memory and access to low level calls when needed. But I am biased since I never tried to make a game in anything except for c++ and java.
Adam W