Aktuelle Zeit: 12.05.2024, 18:06

Alle Zeiten sind UTC + 1 Stunde




Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: 07.10.2009, 19:22 
Offline

Registriert: 15.10.2007, 20:08
Beiträge: 31
Hallo,
es ist nicht wirklich ein Problem, aber irgendwie umständlich. Bei meinem Raumschiffspiel läuft der Start in etwa so ab:

main() -> initialisiert -> Game::Game() -> initialisiert -> Ship::Ship()

das sieht im code aber so aus:
Code:
new Ship(m_sceneManager,m_videoDriver,&m_modelList,vector3df(0,0,0),2,10,1,80,10);


m_sceneManager, m_videoDriver und m_modelList sind membervariablen von Game. Ich muss die alle mitgeben damit Ship sich selbst anzeigen kann. Gibt es nicht eine bessere methode auf die Mutterklasse zugreifen zu können?

Danke im Vorraus


Nach oben
 Profil  
 
BeitragVerfasst: 07.10.2009, 20:37 
Offline
Moderator
Benutzeravatar

Registriert: 25.03.2007, 18:11
Beiträge: 834
Wohnort: Hagen, NRW
Füg einfach in der Game klasse getter methoden für die attribute hinzu und übergib ship einfach nur einen zeiger auf die game instanz.
Dann kannst du in Ship über die getter methoden drankommen.

_________________
Phenom X4 9950 BE | 6144MB DDR2-800 | GeForce 8800GT 512MB | Asus M3A32-MVP Deluxe | 2TB HDD | 520W Seasonic NT | Soprano Tower | Samsung 22" TFT + Fujitsu-Siemens 17" TFT + Toshiba 42" FullHD LCD | Windows 7 Proessional x64
Behind the Brain


Nach oben
 Profil  
 
BeitragVerfasst: 07.10.2009, 21:38 
Offline

Registriert: 15.10.2007, 20:08
Beiträge: 31
Auf die idee bin ich auch schon gekommen, nur wenn ich dann z.B. Game* game in den Konstruktor nehme, ist Game an dieser Stelle unbekannt. Wenn ich dann aber die Game.h include habe ich eine art include undendlichschleife. :?


Nach oben
 Profil  
 
BeitragVerfasst: 08.10.2009, 06:11 
Offline
Benutzeravatar

Registriert: 16.10.2007, 07:56
Beiträge: 229
Wohnort: Regensburg
das klingt mir wie ein altbekanntes C++ Problem. Kann man so lösen:

erstmal sollte immer mit #ifdef dafür gesorgt werden, dass die Klasse nur einmal definiert wird:

Code:
#ifndef _C_GAME
  #define _C_GAME

class CGame {
  ...
}

#endif


Dann kannst du in so einem Fall noch eine Foreward-Deklaration von CGame in dem anderen Header machen:

Code:
#ifndef _C_SHIP
  #define _C_SHIP

class CGame;
class CShip {
  ...
  public:
    CShip(CGame *theGame);
    ...
};


mit der "#ifndef" - "#define" Sache wird sichergestellt, dass, auch wenn Schleifen in den Includes sind, die Klasse nur einmal definiert wird. Solange du allerdings nur einen Pointer auf eine andere Klasse hast muss der C++ Compiler die genaue Klasse nicht kennen, es reicht, ihm zu sagen, dass es die Klasse gibt (das wäre dann "class CGame;" im zweiten Codeteil).

Danach erst in CShip.cpp die Header-Datei "CGame.h" einbinden, dann sollte das funktionieren. Ich hoffe, ich konnte helfen.

_________________
Bild


Nach oben
 Profil  
 
BeitragVerfasst: 13.10.2009, 08:34 
Offline

Registriert: 16.01.2008, 12:31
Beiträge: 79
Ich mache das ein bischen anders.

Zuerst hat meine "App" Klasse erstmal eine statische Methode die mir einen Zeiger auf das Irrlicht-Device gibt, so kann ich von überall daran ohne Parameter durch zig Methoden zu schleifen.

Als zweites habe ich "GameStateManager" und GameStates
Code:
class IGameState {
private:

public:
  ~IGameState() {}
  virtual void OnEnter()=0;
  virtual void OnUpdate(irr::f64 timeElapsed)=0;
  virtual void OnRender()=0;
  virtual void OnLeave()=0;
  virtual bool OnEvent(const irr::SEvent &e)=0;
protected:
  IGameState() {}
};
// klasse ohne fehlerhandling und verkürzt.
class GameStateManager {
private:
  IGameState *_currentGameState;
 
public:
  void OnUpdate(irr::f64 timeElapsed) {
    _currentGameState->OnUpdate(timeElapsed);
  }
  void OnChangeState(IGameState *newState) {
    if (_currentGameState)
      _currentGameState->OnLeave();
    _currentGameState = newState;
    _currentGameState->OnEnter();
  }
  // weitere methoden für render, events usw. ala OnUpdate
};


Ich hab dann also einen GameState fürs Intro, Menü und einen für das laufende Spiel.
Ressourcen und Spielobjekte die ich benötige habe ich alle so in Klassen verpackt das diese grundsätzlich erstmal alles alleine Laden können.

Wie ich die dann weitergebe bin ich mir aber auch noch nicht zu 100% sicher.
Entweder ich erzeuge eine neue Klasse "Parameter" die zeiger auf alles enthält und die ich dann als Parameter weiterreiche um, eben nicht immer mehr Parameter einbauen zu müssen, oder ich mache aus den globale Klassen Singletons auf die ich dann auch von überall zugreifen kann ohne Parameter-Orgien zu veranstalten.
Die dritte Möglichkeit ist alles was für den jeweiligen GameState benötigt wird in der OnEnter-Methode zu laden, da ich aber keine Ahnung habe wie lange das dauern kann weiss ich noch nicht ob ich das dort machen werde oder nicht.


Nach oben
 Profil  
 
BeitragVerfasst: 13.10.2009, 15:07 
Offline
Benutzeravatar

Registriert: 16.10.2007, 07:56
Beiträge: 229
Wohnort: Regensburg
Mein Beitrag war nur als Beispiel gedacht ... für meine Projekte benutz ich (natürlich) auch eine Finite State Machine. Die States haben die Methoden "activate", "deactivate" und "update". "activate" wird von StateManager aufgerufen, wenn der State aktiviert wird. Da wird alles an Initialisierung gemacht, bei "deactivate" werden die Sachen wieder aufgeräumt. Die "update" Methode des aktiven States wird vom StateManager in der Schleife aufgerufen, in der auch die Szene gezeichnet wird. Damit funktioniert das alles ziemlich problemlos. Der Statemanager hat auch eine Methode, mit deren Hilfe eine Neuinitialisierung gestartet wird, dann wird das IrrlichtDevice neu erzeugt und alle States neu angelegt. Damit kann ich, während das Programm läuft, auch schön die Bildschirmauflösung und so ändern.

Die Statemachine ist im Augenblick tief in meinem Spiel "Marbles2 - the Race" verankert, vielleicht trenn ich (wenn das Spiel mal fertig ist) die State Machine raus und veröffentlich sie als Code Snippet, das hilft sicher dem Einen oder Anderen weiter. Im Augenblick gehts mir aber darum, das Spiel fertig zu machen.

_________________
Bild


Nach oben
 Profil  
 
BeitragVerfasst: 14.10.2009, 11:20 
Offline

Registriert: 16.01.2008, 12:31
Beiträge: 79
Weiss ich doch, mit dem Beispiel, mein Beitrag bezog sich auch auf den OP. Ich wollte Ihm ein etwas konkreteres Beispiel geben, für den Fall das er nicht genau weiss wie er das auseinander nimmt.

Mh eine Methode für die Neuinitialisierung hört sich interessant an, bei mir wird das IrrlichtDevice in meiner "app" Klasse erzeugt und dann von dort per statischer Methode geholt.

Was ich ganz sicher noch ändern werde, später irgendwann, aktuell werden die GameStates bei mir mit einem "State *obj = new State()" mittem im Code bei Bedarf erzeugt.
Da werde ich noch ne Klasse mit statischer Factory-Methode umzubauen, ist ein bischen sauberer was Erweiterungen angeht.


Nach oben
 Profil  
 
BeitragVerfasst: 18.10.2009, 23:31 
Offline

Registriert: 15.10.2007, 20:08
Beiträge: 31
Zerotags Antwort befasst sich schon mit meinem nächsten Problem. Und zwar das Hauptmenü und das eigentliche Spiel voneinander zu trennen. Ich habe schon überlegt ob ich mir diese GameStates mit einem enum realisiere und dann überall prüfe wo ich mich gerade befinde.

Die ganzen Pointer habe ich erstmal so gelassen weil nichts anderes funktioniert hat. Nur jetzt bin ich an dem Punkt angekommen wo das Hauptmenü implementiert werden muss und ich habe keinen Ansatz wie ich das innerhalb eines devices machen könnte.

Edit:

Vielleicht mache ich es so:
Code:
while(m_device->Run())
{
  switch(m_gamestate)
  {
  case GAMESTATE_MENU:
    ...
    break;
  case GAMESTATE_INGAME:
    ...
    break;
  }
}


Was meint ihr?

Edit:

Ich hab nun Struktur da rein gebracht. Bei den GameStates Geholfen hat mit letztendlich dieser Link: http://gamedevgeek.com/tutorials/managi ... ates-in-c/

Vorallem das Beispielprojekt gibt viel aufschluss über eine geeignete Struktur des Codes.

Das Problem mit der Includeschleife habe ich gelöst indem ich die Problematischen header mit #ifndef eingepackt, und überall wo es möglich ist reference definitions benutzt habe.


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de