Autor Thema: OOP bei Spiel  (Gelesen 6262 mal)

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« am: 06. November 2005, 15:47 »
Hallo.

Ich habe mir einige Klassen für ein 2D-Jump 'n' Run-Spiel gebastelt. Wie kann das folgende Problem elegant lösen?

Ich habe eine Stammklasse, World, von der ich in WinMain eine Instanz erzeuge. Sie beinhaltet u.a. die Klasse Graphics für Grafikfunktionen, sowie Hero für den Helden und bis zu 1024 andere Objekte. Alles läuft problemlos. Nun aber möchte ich (für jedes Frame) die Objekte bewegen lassen (void Object::Move()). Ich werde noch weitere Kreaturentypen hinzufügen, die dann auch primitive KI haben werden. Doch mein Problem ist: Wie können die Objekte auf die Welt (wo befindet sich was; unsigned long *World::world) zugreifen? Muss ich da für jeden Aufruf von Move() einen Zeiger mitgeben? Oder beim Konstruktor des Objekts einen Zeiger auf *world? Ich möchte dieses Problem so lösen, dass ich immer noch eine objektorientiertheit habe, also nicht etwa mit globalen Vars oder so. Danke.

Anmerkung:
- Ich verwende Polymorphie, d.h. ich werde alle Gegner von Object bzw. Creature ableiten
- TEXTURE, WORLD und ähnliches sind enum's


class World
{
public:
World();
~World();
void CalcFrame();
Hero *hero;
private:
void DrawFrame();
unsigned long GetAbsoluteX(D3DXVECTOR2 pos);
unsigned long GetAbsoluteY(D3DXVECTOR2 pos);
unsigned long GetRelativeX(D3DXVECTOR2 pos);
unsigned long GetRelativeY(D3DXVECTOR2 pos);
WORLD GetWorld(unsigned long x, unsigned long y);
void LoadWorld(unsigned long w);
Graphics graphics;
Object *object[1024];
unsigned long worldSize;
unsigned long *world;
float horizScrolling;
STATUS status;
unsigned long progress;
};

class Object
{
public:
Object(D3DXVECTOR2 pos, unsigned long w, unsigned long h);
~Object();
virtual void Move() = 0;
D3DXVECTOR2 pos;
unsigned long width;
unsigned long height;
TEXTURE texture[8];
};

class Item : public Object
{
public:
Item(D3DXVECTOR2 pos, unsigned long w, unsigned long h, OBJECT t);
~Item();
void Move();
OBJECT type;
};

class Creature : public Object
{
public:
Creature(D3DXVECTOR2 pos, unsigned long w, unsigned long h);
~Creature();
};

class Hero : public Creature
{
public:
Hero(D3DXVECTOR2 pos, unsigned long w, unsigned long h);
~Hero();
void Move(WORLD (*world)(unsigned long, unsigned long));
void SpacePressed();
bool jumpActive;
unsigned long jumpCount;
bool keyRight;
bool keyLeft;
};

SSJ7Gohan

  • Beiträge: 398
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. November 2005, 16:09 »
Gib einfach jedem Object im Konstruktor einen Pointer auf World mit.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. November 2005, 18:09 »
du könntest auch einen singleton nutzen. das ist zwar nur eine globale variable als design pattern verpackt, aber immerhin hast du so 2 zusätzliche buzzwords in der feature list.

gegen eine (1) globale variable spricht nun wirklich nichts. vor allem nicht bei einem so zentralen objekt, wie ein world-objekt.
Dieser Text wird unter jedem Beitrag angezeigt.

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 07. November 2005, 17:50 »
Ja, ich habe World *world jetzt global gemacht und außerdem noch stark vereinfacht, sodass ich nur noch 3 Klassen (World, Object, Graphics) brauche.

 

Einloggen