如何在游戏中实现碰撞效果?

ami*_*che 7 c++ qt

我用QT制作游戏.我的GraphicsScene上的每个对象都继承自GraphicsPixmapItem(Player,Obstacles,炸弹......).我想暗示碰撞效果.例如,当玩家获得奖金时,他可以选择它.使用QT框架我可以得到collidings项目,但我不知道它们是哪种类型,因为没有instanceof函数.有小费吗 ?

编辑:我得到碰撞"事件"我想要做的事情是处理不同的碰撞.我用更好的措辞提出了另一个问题.

MaR*_*MaR 9

设计注意事项:

我不建议从图形表示继承Game对象.为什么?您可能希望拥有一个游戏对象的多个图形表示(如游戏视图中的一个或小视图中的另一个,或其他).关系是"玩家"具有"图形表示​​"而不是"玩家"是"图形表示​​".更好的解决方案是使用组合而不是继承.如果你对Qt提供的那个不满意,那么其他好的效果可以封装其他碰撞检测,解耦,......真相也就是说,对于简单的游戏来说,它就足够了.

对于足够简单的游戏逻辑,继承其他对象对活动对象的反应.对于任何更复杂的游戏机制来说可能过于简单化了.

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

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

如果交互变得复杂(许多活动对象自行运行),您可能需要识别对象:

  • 有RTTI,但是很难推荐:RTTI有多贵? 简而言之:昂贵,难以维护.

  • 您可以使用双重调度.使用两个虚拟调用标识对象.问题:相当多的语法,有时很难维护(特别是当你添加新对象时),所有权问题(见更多).维基百科的游戏示例:


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;
  }
};
Run Code Online (Sandbox Code Playgroud)
  • "列举"

虚函数id

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

class Asteroid() {
  virtual getId() { return ASTEROID; }
};
Run Code Online (Sandbox Code Playgroud)

或作为会员

class GameObject() {
  ID getId() { return id; }
protected:
  GameObject(ID id):id(id) {}
private:
  ID id;
};
Run Code Online (Sandbox Code Playgroud)

或者使用自动初始化id的模板(有点令人难以置信的语法,让我们省略它:o)

  • 和别的

现在为这样的游戏循环:

for each object
  update by (fixed) time step
  detect collisions and resolve them
Run Code Online (Sandbox Code Playgroud)

你会遇到:

所有权问题:

受到小行星撞击后,玩家失去健康,小行星被摧毁后...

Asteorid::collideWithPlayer(Player& p) { p.loseHealth(100); this->explode(); }
Run Code Online (Sandbox Code Playgroud)

现在也考虑一下

Player::collideWithAsteroid(Asteroid& a) { this->loseHealth(100); a.explode(); }
Run Code Online (Sandbox Code Playgroud)

结果:代码两面性或不清楚的游戏机制

穷人的解决方案:打电话给别人帮助你:o)

Asteorid::collideWithPlayer(Player& p) { resolveCollision(p, *this); }
Player::collideWithAsteroid(Asteroid& a) { resolveCollision(*this, a); }
resolveCollision(Player, Asteroid) { p.loseHealth(100); a.explode(); }
Run Code Online (Sandbox Code Playgroud)

  • c ++是游戏开发IMO的最佳选择之一.您可以在需要时更好地控制内存和访问低级别调用.但我有偏见,因为除了c ++和java之外,我从来没有试过用任何东西制作游戏. (2认同)