2009-12-09 2 views
7

QT로 게임을 제작합니다. 내 GraphicsScene의 모든 객체는 GraphicsPixmapItem (Player, Obstacles, bombs ...)에서 상속받습니다. 나는 충돌 효과를 내포하고 싶습니다. 예를 들어, 플레이어가 보너스를 가져 왔을 때 그는 그것을 선택할 수 있습니다. QT 프레임 워크에서 콜리 전 항목을 얻을 수 있지만 instanceof 기능이 없으므로 어떤 유형인지는 알 수 없습니다. 어떤 팁?게임에서 충돌 효과를 구현하는 방법은 무엇입니까?

편집 : 나는 "충돌"이벤트를 얻고 싶습니다. 다른 충돌을 처리합니다. 나는 더 나은 표현으로 또 다른 question을 만들었다.

답변

9

디자인 고려 사항 :

내가 그들의 그래픽 표현에서 게임 오브젝트를 상속 권장하지 않습니다. 왜? 하나의 게임 객체에 대한 여러 개의 그래픽 표현 (게임보기 또는 미니 맵의 다른 것과 같은 것 등)을 원할 수 있습니다. 그 관계는 "Player"는 "그래픽 표현"이며 "Player"는 "그래픽 표현"입니다. 더 좋은 해결책은 상속이 아니라 합성을 사용하는 것입니다. 다른 멋진 효과는 Qt가 제공하는 것에 만족하지 않는다면 다른 충돌 감지를 캡슐화 할 수 있습니다. 즉, 디커플링 (decoupling) ... 진실 또한 간단한 게임이라면 충분할 수 있습니다.

게임 논리가 단순하기 때문에 다른 개체가 활성 개체에 반응하는 상속. 아마도 더 복잡한 게임 메카닉에 비해 너무 단순합니다.

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

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

상호 작용이 당신이 당신의 개체를 식별해야합니다 (자신에 행동 많은 활성 객체) 복잡한 들어갔을 경우 :

는 RTTI입니다있다
  • 을하지만, 음보고 추천하기 어렵다 : 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(); } 
+0

+1 우수한 논문입니다. 그림이 더 좋을 것입니다. ;-) –

+0

많은 설명에 감사드립니다. C++이 게임 개발자에게 좋은 선택이 아니라는 것이 사실입니까? – amirouche

+2

C++는 게임 개발사 IMO를위한 최고의 선택 중 하나입니다. 필요한 경우 메모리 및 저수준 호출에 대한 액세스를보다 효율적으로 제어 할 수 있습니다. 하지만 나는 C++과 java를 제외하고는 게임을 만들려고 시도한 적이 없기 때문에 편견을 가지고 있습니다. –

4

하나의 아이디어 :
상속 : 각과 충돌 할 수있는 선수가 객체 예를 들어 사이비 코드처럼

C++를 필요로 어떤 않는 CollideWithPlayer 메소드가 객체

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

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

당신 Nvidia PhysX 또는 Bullet과 같은 외부 라이브러리를 사용하여 충돌이 발생할 때 콜백을 설정할 수 있습니다. Qt의 충돌 시스템을 사용하지 않는 라이브러리를 사용하면 모든 프레임에서 물리를 시뮬레이션 한 다음 물리 시뮬레이션 내에서 상태를 반영하도록 GraphicsPixmapItem의 속성을 업데이트 할 수 있습니다.

0

다음 Qt 예를 살펴볼 수 있습니다. 충돌 마우스 예.

꽤 쉽습니다. Qt를 사용하는 기본 충돌 처리에 대해 아주 잘 소개 할 것입니다.

빠르게 요약, 각 개체는 ... 그런 다음 항목이 서로를 만지거나하지 여부를 알고이 경계 상자를 사용합니다 ... 당신이 사용하는 공간을 제공하는 경계 상자를해야합니다

희망이 도움이!

+1

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

+0

http://web.archive.org/web /20100409105849/http://doc.trolltech.com/4.6/graphicsview-collidingmice.html – Fuhrmanator

관련 문제