2009-12-09 19 views
7

QT ile oyun yapıyorum. GraphicsScene'deki her nesne GraphicsPixmapItem (Player, Engeller, bombalar ...) 'dan miras alır. Çarpışma etkilerini uygulamak istiyorum. Örneğin, oyuncu hover bonus aldığında onu seçebilir. QT çerçevesiyle collidings öğelerini alabilirim ama hangi tür olduklarını bilmiyorum. Herhangi bir ipucu ?Bir oyunda çarpışma etkileri nasıl uygulanır?

düzenleme: Ben "event" çarpışmasını alıyorum, yapmak istediğim şey farklı çarpışmalarla başa çıkmak. Daha iyi bir ifadeyle başka bir question yaptım.

cevap

9

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

  • "numaralandırma"

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)

  • ve diğerleri

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(); } 
+0

+1. Resimler daha iyi yapardı. ;-) –

+0

açıklamanız için çok teşekkürler. Bu, C++ oyun devresi için iyi bir seçim değil mi? – amirouche

+2

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. –

4

bir fikir:
Kalıtım: Her ile çarpışmak bir oyuncu nesne örneğin psuedo kodu gibi

C++ ihtiyacı varsa yapan bir CollideWithPlayer yöntemi vardır nesne

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

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

Sen Nvidia PhysX veya Bullet gibi bir dış kütüphane kullanabilir, bu da çarpışmaların meydana gelmesi durumunda geri aramaları ayarlamanıza izin verir. Qt'ın çarpışma sistemini kullanmayan bu kütüphaneleri kullanarak, her bir kareyi fiziği simüle edip, daha sonra fizik simülasyonu içinde durumunu yansıtmak için GraphicsPixmapItem'in özelliklerini güncelleyeceksiniz.

0

Aşağıdaki Qt örneğine bakabilirsiniz. Örnek: Çarpışan Fare Örneği.

Oldukça kolay ve Qt ile temel çarpışmalara oldukça güzel bir tanıtım sunacaktır.

Hızla özetlenen, her nesne ... Daha sonra ürün birbirlerinin dokunmadan olup olmadıklarını bilmek bu sınırlayıcı kutuları kullanacağız ... size kullandığı alanı verecek bir sınırlayıcı kutu olacak

Bu yardımcı olur umarım !

+1

http://doc.trolltech.com/4.6/graphicsview-collidingmice.html –

+0

http://web.archive.org/web Mükemmel bir tez için /20100409105849/http://doc.trolltech.com/4.6/graphicsview-collidingmice.html – Fuhrmanator