Aktuelle Zeit: 20.04.2025, 03:05

Alle Zeiten sind UTC + 1 Stunde




Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Intro-Menu-Game
BeitragVerfasst: 08.04.2007, 18:37 
Offline

Registriert: 08.04.2007, 18:19
Beiträge: 12
Hallo erstmal,
also ich will ein Spiel machen, aber ich weiss nicht wie ich das mit der typischen Intro->Menu->Game Schaltung machen soll.
So ähnlich wie in der DEMO von Irrlicht wollt ich es haben, aber ich kapier diesen (fast undokumentierten) Code nicht wircklich, schon weil er mehrere Seiten lang ist.
Ich hoffe ihr könnt mir helfen. Irgend ein kleines Beispiel wäre gut, am besten dokumentiert.


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 08.04.2007, 19:19 
Offline
Benutzeravatar

Registriert: 08.04.2007, 17:06
Beiträge: 25
Am besten legst du 3 Klassen an CIntro, CMainMenu, CGame; Dann erstellst du mit enum eine Aufzählung, die den jeweiligen Spielzustand festlegt. In der Hauptklasse CMain laufen dann alle Klassen zusammen und du erstellst dort die Spielzustandsvariable. Je nachdem welchen Wert diese hat läuft dann eben das Intro, Hauptmenü oder Spiel.

Bsp:
Code:
enum GameState
{
GS_INTRO,// Intro
GS_MAINMENU, // Hauptmenü
GS_GAME, // Spiel
GS_NONE // Aus und vorbei
};
class CMain
{
GameState m_GameState;
CGame* m_pGame; // Klassen für die Spielzustände
CMainMenu* m_pMainMenu;
CIntro* m_pIntro;

void SetGameState(GameState NewGameState);
void Render();
};

beim rendern:
Code:
void CMain::Render()
{
switch(m_GameState)
{
case GS_INTRO:
m_pIntro->Render()

//usw.
}
}


Neuen Spielzustand setzen
Code:
void setGameState(GameState NewGameState)
{
// Alten Spielzustand entladen
switch(m_GameState)
{
case GS_INTRO:
m_pIntro->Unload();
// usw.
}
// Neuen Spielzustand setzen
mGameState = NewGameState
// Neuen Spielzustand laden
switch(m_GameState)
{
case GS_INTRO:
m_pIntro->Load();
// usw.
}
}

Und die Spielklassen enthalten eben die Variablen die du brauchst und folgende Elementarfunktionen:
Init();
Exit();
Render();
Move();
Load();
Unload();
Je nachdem was du eben brauchst ;)
Hoffe das hilft dir[/code]

_________________
MfG
Fred


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 08.04.2007, 21:54 
Offline

Registriert: 08.04.2007, 18:19
Beiträge: 12
Danke, jetzt hab ich wenigstens den Ablauf verstanden!
Hat geholfen, thx. :wink:


Nach oben
 Profil  
 
 Betreff des Beitrags:
BeitragVerfasst: 09.04.2007, 13:40 
Offline
Benutzeravatar

Registriert: 25.03.2007, 18:57
Beiträge: 172
@CPP: ich gebe dir den Tipp einfach mal die Demo aufzurufen und an ihm rumzuprobieren. Ich z.B. habe am anfang versucht einfach mal dieses auswählen von Opengl... wegzumachen und versucht nur directx9 aufzurufen. Wenn das nicht geht halt opengl. Danach habe ich dann das auswählen von Fullscreen verändert. Das ging soweit, dass ich dann Später nurnoch 5 Buttons hatte, die mittelbündig waren und als hintergrund einfach nur ein Bild. Dadurch habe ich es geschafft den Kompletten Code von CMainMenu zu verstehen und kann mich nun CDemo zuwenden


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 14.07.2007, 13:32 
Offline

Registriert: 14.07.2007, 13:06
Beiträge: 2
Hallo Ihr alle!

Ich bin ein Irrlicht-anfänger und in C++ versuche ich gerade die "Vererbung" zu verstehen. Daher möchte ich von euch wissen, ob ich auf dem richtigen Weg bin.
Ich habe die in diesem thema angesprochenen Klassen "CIntro,CMainMenu und CGame" von einer Basis-Klasse CGameState abgeleitet. Funktionieren tut das ganze, jetzt will ich nur wissen, ob das auch optimal ist, oder ich hier noch was verbessern kann.

Zuerst die C_Gamestates.h

Zitat:
#include "main.h"

class C_GameStates : public IEventReceiver
{
protected:
IrrlichtDevice* m_device;
IVideoDriver* m_driver;
ISceneManager* m_smgr;
char* m_Text;

public:
C_GameStates();
~C_GameStates();

bool OnEvent(SEvent event);

virtual int Init();
virtual int Exit();
virtual int Render();
};

//////////////////////////////////////////////////////////////////////

class C_Intro : public C_GameStates
{

public:
C_Intro();
~C_Intro();

bool OnEvent(SEvent event);

public:
int Init();
int Exit();
int Render();
};
//////////////////////////////////////////////////////////////////////

class C_MainMenu : public C_GameStates
{

public:
C_MainMenu();
~C_MainMenu();

bool OnEvent(SEvent event);

public:
int Init();
int Exit();
int Render();
};

//////////////////////////////////////////////////////////////////////

class C_Game : public C_GameStates
{

public:
C_Game();
~C_Game();

bool OnEvent(SEvent event);

public:
int Init();
int Exit();
int Render();
};


Und die C_Gamestates.cpp sieht so aus:
Zitat:
#include <iostream.h>
#include "C_GameStates.h"

C_GameStates::C_GameStates()
{

}

C_GameStates::~C_GameStates()
{

}

bool C_GameStates::OnEvent(SEvent event)
{
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_ESCAPE &&
event.KeyInput.PressedDown == true)

{
m_device->closeDevice();
}

return false;

}

int C_GameStates::Init()
{
cout << m_Text << " wurde initialisiert\n";
m_device = createDevice(EDT_DIRECT3D9, dimension2d<s32>(SCREEN_WIDTH, SCREEN_HIGHT), 32,
true, false, false, this);

if (m_device == 0)
return 1;

m_device->setWindowCaption(L"GameState Test");

m_driver = m_device->getVideoDriver();
m_smgr = m_device->getSceneManager();

return 0;
}

int C_GameStates::Render()
{
cout << m_Text << " wird gerendert\n";

while(m_device->run())
{

m_driver->beginScene(true, true, video::SColor(0,200,200,200));
m_smgr->drawAll();
m_driver->endScene();
}

return 0;
}

int C_GameStates::Exit()
{
cout << m_Text <<" wird geschlossen\n";

m_device->drop();

return 0;
}
//////////////////////////////////////////////////////////////////////
//------------------------Klasse CIntro ANFANG----------------------------

C_Intro::C_Intro()
{
m_Text = "Intro";
}

C_Intro::~C_Intro()
{

}

int C_Intro::Init()
{

C_GameStates::Init();

m_smgr->loadScene("media\\test.irr");

m_smgr->addCameraSceneNodeFPS();

return 0;


}

int C_Intro::Render()
{
C_GameStates::Render();

return 0;
}

int C_Intro::Exit()
{
C_GameStates::Exit();

return 0;
}

bool C_Intro::OnEvent(SEvent event)
{
C_GameStates::OnEvent(event);

return false;

}
//------------------------Klasse CIntro ENDE----------------------------
//////////////////////////////////////////////////////////////////////
//------------------------Klasse CMainMenue ANFANG----------------------------
C_MainMenu::C_MainMenu()
{
m_Text = "MainMenu";
}

C_MainMenu::~C_MainMenu()
{

}

int C_MainMenu::Init()
{

C_GameStates::Init();

m_smgr->loadScene("media\\test.irr");

m_smgr->addCameraSceneNodeFPS();

return 0;


}

int C_MainMenu::Render()
{
C_GameStates::Render();

return 0;
}

int C_MainMenu::Exit()
{
C_GameStates::Exit();

return 0;
}

bool C_MainMenu::OnEvent(SEvent event)
{
C_GameStates::OnEvent(event);

return false;

}

//------------------------Klasse CMainMenue ENDE----------------------------
//////////////////////////////////////////////////////////////////////
//------------------------Klasse CGame ANFANG----------------------------
C_Game::C_Game()
{
m_Text = "Game";
}

C_Game::~C_Game()
{

}

int C_Game::Init()
{

C_GameStates::Init();

m_smgr->loadScene("media\\test.irr");

m_smgr->addCameraSceneNodeFPS();

return 0;


}

int C_Game::Render()
{
C_GameStates::Render();

return 0;
}

int C_Game::Exit()
{
C_GameStates::Exit();

return 0;
}

bool C_Game::OnEvent(SEvent event)
{
C_GameStates::OnEvent(event);

return false;

}

//------------------------Klasse CGame ENDE----------------------------

Dann noch die main.h
Zitat:
#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

#pragma comment(lib, "Irrlicht.lib")

#define SCREEN_WIDTH 1024
#define SCREEN_HIGHT 768

und die main.cpp
Zitat:
#include "main.h"
#include "C_GameStates.h"


#include <iostream.h>


int main()
{
C_GameStates* GS;

GS = new C_Intro;
GS->Init();
GS->Render();
GS->Exit();

GS = new C_MainMenu;
GS->Init();
GS->Render();
GS->Exit();

GS = new C_Game;
GS->Init();
GS->Render();
GS->Exit();

delete GS;
return 0;

}


Wie gesagt, mich würde jetzt euere Meinung zu den Klassen interresieren.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 14.07.2007, 16:27 
Offline
Moderator
Benutzeravatar

Registriert: 11.03.2007, 20:25
Beiträge: 556
Wohnort: Frankfurt/Main
aalso..
eigentlich schon ganz solide außer das bei jedem state-wechsel ein neuer device erzeugt wird.. ein einfaches smgr->clear() löscht alle nodes. und die ganzen überladenen methoden sehen etwas sinnlos aus wenn sie sowieso nichts tun.. das kommt ja aber noch.
das onEvent ist ja schön und gut, aber, hast du das schon mal kompiliert? dann merkst du vllt dass diese funktion nie aufgerufen wird.. weil du nicht device->setEventReceiver(this) ausführst..
dass die funktion Init schön im fehlerfall eine 1 zurückgibt wird einfach stillschweigend übergangen..

soo.. das mal beim flüchtigen drübergucken.. dass die verwendung der states auch etwas unglücklich ist, nämlich speicherlecks produziert, sollte dir eigentlich von selbst auffallen, da du ja gewissenhaft ein delete GS; ans ende von main() gesetzt hast.. das problem: die freigabe des per new belegten speichers geschieht nur für den letzten state, C_Game..

_________________
yo. life's so bloody short.
Ihr dachtet Schulfernsehn sei die ultimative Folter? Falsch: Fahrstuhlmusik, extra leise.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 14.07.2007, 19:33 
Offline

Registriert: 14.07.2007, 13:06
Beiträge: 2
Zitat:
außer das bei jedem state-wechsel ein neuer device erzeugt wird.. ein einfaches smgr->clear() löscht alle nodes.

Und wenn ich z.B. das Menü in einer anderen Auflösung anzeigen möchte, geht das dann irgendwie anders, als device löschen und dann ein neues zu erzeugen?
Zitat:
das onEvent ist ja schön und gut, aber, hast du das schon mal kompiliert? dann merkst du vllt dass diese funktion nie aufgerufen wird.. weil du nicht device->setEventReceiver(this) ausführst..

Das verstehe ich jetzt nicht ganz - das onEvent funktioniert so einwandfrei. Ich kann bei jedem GameState die "ESC"- Taste drücken und als Reaktion darauf wird der aktuelle GameState geschlossen und der nächste aufgerufen.
Zitat:
dass die funktion Init schön im fehlerfall eine 1 zurückgibt wird einfach stillschweigend übergangen..

das kommt noch. Wenn die Klassen an sich erst einmal in Ordnung sind, erstelle ich noch einen GameStateManager, der sich unter Anderem auch dadrum kümmert. Und natürlich auch um die freigabe des reservierten Speichers.

Und ansonsten - findet ihr das ganze so schon in Ordnung, oder gibt es da noch was zu verbessern?


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 14.07.2007, 20:17 
Offline
Moderator

Registriert: 25.02.2007, 14:35
Beiträge: 323
Wohnort: Münster
alex hat geschrieben:
Zitat:
das onEvent ist ja schön und gut, aber, hast du das schon mal kompiliert? dann merkst du vllt dass diese funktion nie aufgerufen wird.. weil du nicht device->setEventReceiver(this) ausführst..

Das verstehe ich jetzt nicht ganz - das onEvent funktioniert so einwandfrei. Ich kann bei jedem GameState die "ESC"- Taste drücken und als Reaktion darauf wird der aktuelle GameState geschlossen und der nächste aufgerufen.


@frodenius: Soweit ich jetzt überblicken konnte, übergiebt er ja bereits an createDevice den Eventreceiver (this). Dann ist der Aufruf von device->setEventReceiver(this) nicht mehr nötig.


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 15.07.2007, 08:31 
Offline
Newsposter
Benutzeravatar

Registriert: 12.03.2007, 10:42
Beiträge: 338
Wohnort: Berlin
stimmt er über gibt den this zeiger gleich bei createDevice
Zitat:
Code:
m_device = createDevice(EDT_DIRECT3D9, dimension2d<s32>(SCREEN_WIDTH, SCREEN_HIGHT), 32,
true, false, false, this);


Nach oben
 Profil  
 
 Betreff des Beitrags: Re: Intro-Menu-Game
BeitragVerfasst: 15.07.2007, 16:39 
Offline
Moderator
Benutzeravatar

Registriert: 11.03.2007, 20:25
Beiträge: 556
Wohnort: Frankfurt/Main
uups.. tja wie gesagt.. flüchtig .. ;D :lol:

_________________
yo. life's so bloody short.
Ihr dachtet Schulfernsehn sei die ultimative Folter? Falsch: Fahrstuhlmusik, extra leise.


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

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 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:  
cron
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de