<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[OOP bei Spiel]]></title><description><![CDATA[<p>Hallo.</p>
<p>Ich habe mir einige Klassen für ein 2D-Jump 'n' Run-Spiel gebastelt. Wie kann das folgende Problem elegant lösen?</p>
<p>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.</p>
<p>Anmerkung:<br />
- Ich verwende Polymorphie, d.h. ich werde alle Gegner von Object bzw. Creature ableiten<br />
- TEXTURE, WORLD und ähnliches sind enum's</p>
<pre><code>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;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/125417/oop-bei-spiel</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 23:41:15 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/125417.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 06 Nov 2005 14:55:12 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 14:55:12 GMT]]></title><description><![CDATA[<p>Hallo.</p>
<p>Ich habe mir einige Klassen für ein 2D-Jump 'n' Run-Spiel gebastelt. Wie kann das folgende Problem elegant lösen?</p>
<p>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.</p>
<p>Anmerkung:<br />
- Ich verwende Polymorphie, d.h. ich werde alle Gegner von Object bzw. Creature ableiten<br />
- TEXTURE, WORLD und ähnliches sind enum's</p>
<pre><code>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;
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/909564</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/909564</guid><dc:creator><![CDATA[sz]]></dc:creator><pubDate>Sun, 06 Nov 2005 14:55:12 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 15:13:09 GMT]]></title><description><![CDATA[<p>jepp, du könntest die Referenz auf das Worldobjekt einfach in den Constructor von Object mit aufnehmen, also:</p>
<pre><code class="language-cpp">class Object
{
public:
    Object(World* world, D3DXVECTOR2 pos, unsigned long w, unsigned long h);
    ~Object();
    virtual void Move() = 0;
    D3DXVECTOR2 pos;
    unsigned long width;
    unsigned long height;
    TEXTURE texture[8];
};
</code></pre>
<p>und das natürlich entsprechend in den abgeleiteten Klassen ...</p>
<p>[edit]<br />
was sollte daran nich OO sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/909578</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/909578</guid><dc:creator><![CDATA[toast]]></dc:creator><pubDate>Sun, 06 Nov 2005 15:13:09 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 15:27:36 GMT]]></title><description><![CDATA[<p>Ich habe ähnliche Probleme, ich denke mal die beste Lösung wär, wenn man das ganze Problem mit Iteraroen (statisch verwalten) löst. Frag am besten mal im Spieleprogrammierungsforum nach und lade dir mal die dusmania Engine runter. gibts bei:<br />
<a href="http://www.spieleprogrammierer.de/" rel="nofollow">http://www.spieleprogrammierer.de/</a></p>
<p>gucke dir einfach mal das Prinzip an, wie sie programmiert ist.</p>
<p>Man kommt mit Iteratoren wesentlich weiter, als mit Vererbungen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/909597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/909597</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Sun, 06 Nov 2005 15:27:36 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 15:27:24 GMT]]></title><description><![CDATA[<blockquote>
<p>Ich möchte dieses Problem so lösen, dass ich immer noch eine objektorientiertheit habe, also nicht etwa mit globalen Vars oder so.</p>
</blockquote>
<p>Das hab ich bei meinem Spiel auch zuerst gedacht. Aber dann bin ich draufgekommen dass es mit globalen Variablen sehr einfach und meiner Meinung nach kein bisschen unsauber geht.</p>
<p>GameBase.h:</p>
<pre><code>class CTileMap;
class CLap;

namespace GameBase
{
	extern CTileMap *map;
	extern CLap *lap;
}
</code></pre>
<p>GameBase.cpp:</p>
<pre><code>#include &quot;GameBase.h&quot;

CTileMap *GameBase::map=0;
CLap *GameBase::lap=0;
</code></pre>
<p>TileMap.cpp:</p>
<pre><code>#include &quot;GameBase.h&quot;
CTileMap::CTileMap()
{
	GameBase::map=this;
}
</code></pre>
<p>Wenn ich jetzt in einer Datei auf *map zugreifen will mach ich folgendes:<br />
- GameBase.h inkludieren<br />
- Will ich z.B. CTileMap verwenden, muss ich TileMap.h inkludieren. In Gamebase.h ist zwar deklariert dass es diese Klasse gibt, die genaue Definition ist aber unbekannt. Dadurch inkludiere ich nur das was ich brauche.<br />
- Wenn ich GameBase öfters verwende, mach ich einfach</p>
<pre><code>using namespace GameBase;
</code></pre>
<p>Meiner Meinung nach ist das eine schnelle und funktionierende Lösung. Ist mir sauber genug.</p>
<p>Ich hab auch noch eine Alternativlösung parat:</p>
<pre><code>// in gameobject.h
class CGameObject
{
static CTileMap *map;
static CLap *lap;
}

// in der cpp
CTileMap *CGameObject::map=0;
CLap *CGameObject::lap=0;
</code></pre>
<p>Im Konstruktor von CTileMap beispielsweise wird dann folgendes gemacht:</p>
<pre><code>CGameObject::map=this;
</code></pre>
<p>Jede Klasse die mit dem Spiel zu tun hat wird davon abgeleitet und kennt dann diese Instanzen.<br />
So kann man's auch machen - ich hab Variante 1 gewählt.</p>
<p>mfg. Tubos</p>
]]></description><link>https://www.c-plusplus.net/forum/post/909599</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/909599</guid><dc:creator><![CDATA[Tubos]]></dc:creator><pubDate>Sun, 06 Nov 2005 15:27:24 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 19:06:13 GMT]]></title><description><![CDATA[<p>Globale Variablen sind unsauber und schaden der Datenkapselung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/909878</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/909878</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Sun, 06 Nov 2005 19:06:13 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Sun, 06 Nov 2005 23:21:05 GMT]]></title><description><![CDATA[<p>ist bei solchen fällen, wo man weiss, es soll nur EIN objekt einer klasse geben nicht sowas wie ein singleton angesagt? (was ja auch sowas wie ne globale variable ist..) fänd ich im falle von WORLD schon richtig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/910191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910191</guid><dc:creator><![CDATA[prokaion]]></dc:creator><pubDate>Sun, 06 Nov 2005 23:21:05 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 06:06:22 GMT]]></title><description><![CDATA[<p>Man kann ja folgendes machen:</p>
<pre><code class="language-cpp">class Cx
{
   private:
      static Cx m_x;
};
</code></pre>
<p>--&gt; Kannst Die Klasse lokal aufrufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/910213</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910213</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Mon, 07 Nov 2005 06:06:22 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 07:50:39 GMT]]></title><description><![CDATA[<p>Erstmal - wieso sind denn alle Methoden der World-Klasse privat? So kann keine deiner &quot;Objekt&quot;-Klassen etwas damit machen.<br />
Zweitens - wenn du virtuelle Methoden verwendest, solltest du überall die selbe Signatur einsetzen (und die Signatur von Hero::Move() sieht sowieso grauenhaft aus - wenn mich nicht alles täuscht, erwartet die eine Funtion als Parameter, die zwei unsigned in ein Enum verrechnet).</p>
<p>Zu deinem eigentlichen Problem - da du nur eine Welt hast, bietet sich ein globales Objekt &quot;theWorld&quot; imho an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/910249</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910249</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Mon, 07 Nov 2005 07:50:39 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 15:26:21 GMT]]></title><description><![CDATA[<p>Ich tät ein Singleton machen</p>
<pre><code class="language-cpp">class World {
private:
    static World *Instance;
public:
    World();
    static World *Singleton() { return Instance; }
};

World::World() {
  Instance = this;
}
</code></pre>
<p>Ist aber eh Geschmackssache <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/910685</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910685</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Mon, 07 Nov 2005 15:26:21 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 15:29:19 GMT]]></title><description><![CDATA[<p>LordJaxom schrieb:</p>
<blockquote>
<p>Ich tät ein Singleton machen</p>
<pre><code class="language-cpp">class World {
private:
    static World *Instance;
public:
    World();
    static World *Singleton() { return Instance; }
};

World::World() {
  Instance = this;
}
</code></pre>
<p>Ist aber eh Geschmackssache <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Tut man bei dem einfach &quot;Standardsingleton&quot; den Konstruktor nicht private machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/910693</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910693</guid><dc:creator><![CDATA[Pellaeon]]></dc:creator><pubDate>Mon, 07 Nov 2005 15:29:19 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 15:38:21 GMT]]></title><description><![CDATA[<p>Na, keine Haare spalten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> Dann müsste konsequent auch die Methode Singleton noch die Instanz erzeugen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/910701</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910701</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Mon, 07 Nov 2005 15:38:21 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Mon, 07 Nov 2005 18:48:31 GMT]]></title><description><![CDATA[<p>Ich finde dir Sache mit den Globalen Variablen wirklich blöd, denn wo will man sie deklarieren ?!?</p>
<p>Ich hab auch ne ganze Weile dran gesessen und bin dann zum Entschluss gekommen das man mit statischen Variablen, die in der Klasse deklariert sind vielen Problemen aus dem Weg geht.</p>
<p>ZB.:<br />
ihr habt ne Soundclass, die Waves abspielt --&gt; Wollt iht jede Klasse wie Player, Vehicle, World, Weapon von ihr erben lassen oder wo wollt ihr ne Globale deklarieren?</p>
<p>Wenn man ne Enige patch oder nen Wrapper weiß ich ja nicht, wie das mit Globalen Variablen aussehen soll??</p>
]]></description><link>https://www.c-plusplus.net/forum/post/910914</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/910914</guid><dc:creator><![CDATA[Tc++H]]></dc:creator><pubDate>Mon, 07 Nov 2005 18:48:31 GMT</pubDate></item><item><title><![CDATA[Reply to OOP bei Spiel on Tue, 08 Nov 2005 17:33:54 GMT]]></title><description><![CDATA[<p>statische variablen in der klasse sind doch schon fast ein singleton:</p>
<pre><code class="language-cpp">class Single
{
   private:
      static Single* pSingle;

      Single() { ... //konstruier }

      ...
   public:
      static Single* Get()
      {
         if(!pSingle)
            pSingle = new Single( ...//params);
         return pSingle;
      }

      static void Release() { if pSingle delete pSingle; }
      ...
};
</code></pre>
<p>aufruf erfolgt dann mit<br />
Single::Get()-&gt;memberFun();</p>
<p>wenn kein object der klasse existiert wird eins gemacht und memberfun ausgeführt, wenns schon eins gibt wird memberfun sofort ausgeführt. es gibt also immer nur EIN und nur EIN object dieser Klasse...<br />
vor programmschluss nicht vergessen release() aufzurufen. die macht auch nur was, wenn das object existiert.</p>
<p>wenn du das includierst kannst du diese klasse von überall aufrufen, wie ne globale variable.</p>
<p>ich weiss nicht wie gut dir das ins system passt, ich hab damit jedenfalls gute erfahrungen gemacht...</p>
<p>du kannst die auch so machen das andere klassen davon erben, geht auch. aber dann schön aufpassen das du nicht irgendwann in globalen vars erstickst!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/912026</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/912026</guid><dc:creator><![CDATA[prokaion]]></dc:creator><pubDate>Tue, 08 Nov 2005 17:33:54 GMT</pubDate></item></channel></rss>