Tasarım hususlar:
Onların grafik gösteriminden Oyun nesneleri devralan tavsiye edemez. Niye ya? Bir oyun nesnesinin birden fazla grafik gösterimine sahip olmak isteyebilirsiniz (oyun görünümünden biri veya mini haritadaki veya başka herhangi bir şekilde). İlişki "Oynatıcı" bir "grafik gösterimi" dir ve "Oynatıcı" bir "grafik temsili" değildir. Daha iyi çözüm, kalıtım değil, kompozisyon kullanmaktır. Qt, decoupling tarafından sağlanan bir ile mutlu değilseniz, diğer çarpma tespiti diğer çarpışma tespiti mümkün olabilir ... Gerçek de, basit bir oyun için olsa yeterli olabilir.
Yeterli oyun mantığı, diğer nesnelerin etkin nesnelere tepki verdiği kalıtım için. Daha karmaşık oyun mekaniği için muhtemelen çok basit.
class Asteroid {
public:
virtual void CollideWithPlayer(Player&) { p.loseHealth(100); }
};
class ExplodingAsteroid: Asteroid {
public:
virtual void CollideWithPlayer(Player&) { explode(); p.loseHealth(1000); }
};
etkileşim size nesneleri tanımlamak gerekebilir (kendi başlarına davranan birçok etkin nesneler) karmaşık alırsa:
RTTI olan var
ama eee bkz tavsiye etmek zor: How expensive is RTTI? yılında kısa: pahalı, bakımı zor.
Çift gönderimi kullanabilirsiniz. İki sanal çağrı kullanarak nesneleri tanımlar. Sorunlar: Biraz sözdizimi, bazen bakımı zor (özellikle yeni nesneler eklediğinizde), sahiplik sorunları (daha fazlasını görün). Wikipedia'dan Oyun örnek:
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;
}
};
sanal fonksiyon id
class GameObject() {
virtual getId() { return GAME_OBJECT; }
};
class Asteroid() {
virtual getId() { return ASTEROID; }
};
veya üye olarak
class GameObject() {
ID getId() { return id; }
protected:
GameObject(ID id):id(id) {}
private:
ID id;
};
veya id oto başlatma ile şablonu kullanarak (biraz akıl almaz sözdizimi, hadi ihmal edelim: o)
Oyun gibi böyle bir döngü için:
for each object
update by (fixed) time step
detect collisions and resolve them
karşılaşacağınız:
Mülkiyet sorunları: asteroid tarafından vurulduktan ve göktaşı sonradan tahrip edildiğinde
oyuncu sağlığını kaybeder ..
Asteorid::collideWithPlayer(Player& p) { p.loseHealth(100); this->explode(); }
şimdi de
Player::collideWithAsteroid(Asteroid& a) { this->loseHealth(100); a.explode(); }
düşünün sonuç: kod yinelenen veya belirsiz oyun mekaniği
yoksul adamın çözüm: başkası size yardımcı olmak için çağrı: o)
Asteorid::collideWithPlayer(Player& p) { resolveCollision(p, *this); }
Player::collideWithAsteroid(Asteroid& a) { resolveCollision(*this, a); }
resolveCollision(Player, Asteroid) { p.loseHealth(100); a.explode(); }
+1. Resimler daha iyi yapardı. ;-) –
açıklamanız için çok teşekkürler. Bu, C++ oyun devresi için iyi bir seçim değil mi? – amirouche
C++, oyun dev IMO için en iyi seçimlerden biridir. Bellek üzerinde daha fazla kontrole ve gerektiğinde düşük seviyeli çağrılara erişime sahipsiniz. Ama ben önyargılıyım çünkü C++ ve java hariç hiçbir şeyde oyun oynamaya çalışmadım. –