我用QT构建游戏。我的GraphicsScene上的每个对象都继承自GraphicsPixmapItem(Player,Obstacles,Bombbs ...)。我想暗示碰撞效果。例如,当玩家获得悬停奖金时,他可以选择。 通过QT框架,我可以得到collidings项目,但我不知道它们是哪种类型,因为没有instanceof函数。有小费吗 ?如何在游戏中实现碰撞效果?
编辑:我得到的碰撞“事件”我想要做的事情是处理不同的碰撞。我做了另一个更好的措辞question。
我用QT构建游戏。我的GraphicsScene上的每个对象都继承自GraphicsPixmapItem(Player,Obstacles,Bombbs ...)。我想暗示碰撞效果。例如,当玩家获得悬停奖金时,他可以选择。 通过QT框架,我可以得到collidings项目,但我不知道它们是哪种类型,因为没有instanceof函数。有小费吗 ?如何在游戏中实现碰撞效果?
编辑:我得到的碰撞“事件”我想要做的事情是处理不同的碰撞。我做了另一个更好的措辞question。
设计考虑因素:
我不能推荐从它们的图形表示继承游戏对象。为什么?您可能希望有一个游戏对象的多个图形表示(例如游戏视图中的一个或小地图中的另一个或其他)。关系是“玩家”具有“图形表示”而不是“玩家”是“图形表示”。更好的解决方案是使用组合而不是继承。其他好的效果是可能封装其他碰撞检测,如果你不满意Qt提供的一个,解耦,...真相也是,对于简单的游戏,它可以是足够的。
对于足够简单的游戏逻辑来说,其他对象对活动对象作出反应的地方是继承。对于任何更复杂的游戏机制来说,这可能太简单了。
class Asteroid {
public:
virtual void CollideWithPlayer(Player&) { p.loseHealth(100); }
};
class ExplodingAsteroid: Asteroid {
public:
virtual void CollideWithPlayer(Player&) { explode(); p.loseHealth(1000); }
};
如果交互变得复杂(许多活动对象表现自己),你需要确定你的对象:
还有就是RTTI,但ERM很难推荐查看:How expensive is 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;
}
};
虚函数ID
class GameObject() {
virtual getId() { return GAME_OBJECT; }
};
class Asteroid() {
virtual getId() { return ASTEROID; }
};
或作为成员
class GameObject() {
ID getId() { return id; }
protected:
GameObject(ID id):id(id) {}
private:
ID id;
};
,或者使用模板,ID的自动初始化(有点令人难以置信的语法,让我们忽略它:O)
现在为这样的游戏循环:
for each object
update by (fixed) time step
detect collisions and resolve them
你会遇到:
所有权问题:
球员失去健康的小行星击中小行星,并随后被摧毁后..
Asteorid::collideWithPlayer(Player& p) { p.loseHealth(100); this->explode(); }
现在也在考虑
Player::collideWithAsteroid(Asteroid& a) { this->loseHealth(100); a.explode(); }
结果:代码重复或游戏机制不清
穷人的解决方案:给别人打电话,以帮助您:O)
Asteorid::collideWithPlayer(Player& p) { resolveCollision(p, *this); }
Player::collideWithAsteroid(Asteroid& a) { resolveCollision(*this, a); }
resolveCollision(Player, Asteroid) { p.loseHealth(100); a.explode(); }
一个想法:
继承:每个对象玩家可以与碰撞有CollideWithPlayer方法,做什么对象需要
类似于C++例如伪代码
class Item : GameObject {
public:
CollideWithPlayer(Player p);
}
class PointBag : Item {
public:
CollideWithPlayer(Player p) { p.points += 5000; }
}
你可以使用像Nvidia PhysX或Bullet这样的外部库,它可以让你为冲突发生时设置回调。通过使用这样的库,谁不会使用Qt的碰撞系统,相反,每个帧都可以模拟物理过程,然后更新GraphicsPixmapItem的属性以在物理模拟中反映它们的状态。
你可以看看下面的Qt例子:Colliding Mice Example。
这很容易,它会给你一个很好的介绍Qt的基本碰撞处理。
快速汇总,每个对象将有一个边框,会给你它使用的空间......然后,您将使用这些边框知道项目是否都在触摸对方或不...
希望这可以帮助 !
http://doc.trolltech.com/4.6/graphicsview-collidingmice.html – 2009-12-09 19:08:51
http://web.archive.org/web /20100409105849/http://doc.trolltech.com/4.6/graphicsview-collidingmice.html – Fuhrmanator 2018-02-28 21:08:49
+1优秀论文。图片会让它变得更好。 ;-) – 2009-12-09 20:34:55
非常感谢您的解释。 C++对于游戏开发来说不是一个好选择吗? – amirouche 2009-12-09 21:02:23
C++是游戏开发IMO的最佳选择之一。在需要时,您可以更多地控制内存并访问低级调用。但是我有偏见,因为我从来没有尝试过除C++和java之外的任何游戏。 – 2009-12-09 21:47:15