Archived

This topic is now archived and is closed to further replies.

BungoMan85

problem with beginning sequence for game

Recommended Posts

im making a simple sprite based 2d game and ive come across a serious conceptual roadblock (at least for me). i want my game (the moment it is started and the engine has been initialized) to begin with a short "movie". in must the same way like at the beginning of the earlier final fantasy games where itd just display simple text (well they seemed more like sprites that were text, but still sprites... anyways). for the life of me i cant figure out how the bloodly hell im gonna tell it to begin to load a "movie" (much less how im gonna store the data for the movie, such as sprite positions and such) and then when a button is pressed begin a menu loop or the main game loop or whatever. in general i need to know HOW im going to switch between different update modes. i cant seem to come up with a general way that would let me easily and efficiently switch between the following update modes: 1. movie (basicly spries moving by themselves, for times when the player doesnt need to be in control and such) 2. menu (of any kind) 3. world map (when the player is moving around in the world map) 4. town/dungeon (when the player is moving around in a town or dungeon, similar to the world map, but i feel it would be a food idea to distinguish between the two) 5. battle (when the player is in a battle, im thinking something along the lines of final fantasy 4,5,or 6) 6. modes 3-5 with a menu of some kind

Share this post


Link to post
Share on other sites
The way I would do it is use a game state. This is a simple global variable, which can take values of what current state the game is in, set up as follows:

enum GameState { STARTINGMOVIE, STARTINGMENU, MENU, WORLDMAPMENU, TOWNDUNGEONMENU, BATTLEMENU, WORLDMAP, TOWNDUNGEON, BATTLE, WORLDMAPMOVIE, TOWNDUNGEONMOVIE } gCurrState;

you''d use a switch loop inside the main game loop to process the current game state, and would have a function to change the game state, which looks at the current game state and processes it accordingly. I suggest you always keep the WORLDMAP or TOWNDUNGEON, MENU and BATTLE game data loaded in, and then load the movie data whenever you want to display a movie. This way, you save having to load the files in, each time you come across a battle.

Share this post


Link to post
Share on other sites
For the movies, I would store paths for the sprites to follow and a length of time for them to follow it in. The paths could be a series of lines, or bezier currves or whatever.

For separating you different parts, I would do what OklyDokly said. However, there''s a previously featured article called "Eliminating the Win32 message pump and solving the ALT-TAB problem" or something like that which I found helpful and I''m currently using a combination of the two systems that works very well.

tj963

Share this post


Link to post
Share on other sites
well that is kind of what i had figured id do. and i think im sloooooooowly starting to get through the roadblock of retardedness thats been keeping me from understanding. but im wondering... is this how companies like squaresoft would do it? i mean im not trying to create something as great as final fantasy. but i want to at least have something that is somewhat professional as far as its design goes. i know that sounds WAAAAAAAAAAAAAAAAAAAAAAY overzealous, but i think that if i learn it the right way (ie the way that a real game developer would do it) then i wont have to spend forever doing it the wrong way and then relearning the right way when people laugh at my inefficient and crappy code lol

Bungo!

Share this post


Link to post
Share on other sites
oh, i didnt remember to mention this earlier...

would it be a better idea to load ALL of every area''s data on startup or load it each time a different area is loaded? in theory it shouldnt take but a few seconds load it ALL... but im worried. some of the data will be HUGE and im concerned about how if i do it that way my game will require like 400 megs of ram to just load the data (assuming i load ALL of it. cause i plan on having extensive maps and such when im done, unless i can figure out a better way of storing it all).

would load times of a second or so be tolerable every scene? the first way would be super easy but inefficient. the second way can be complicated (if i want it to be) but should in theory be a lot less memory taxing

Bungo!

Share this post


Link to post
Share on other sites
>>well that is kind of what i had figured id do. and i think im sloooooooowly starting to get through the roadblock of retardedness thats been keeping me from understanding. but im wondering... is this how companies like squaresoft would do it?<<

Probably not. I''m not sure if this is what Squaresoft does, but another method is to have a stack of function pointers, and every frame you run through all the function pointers on the stack. When tasks begin/end they can add themselves to the stack or remove themselves from the stack.

In other words, you always have a central sequence of events that get run, and you simply change what those events are. This allows you to add events from anywhere in your game code without having to have one massive switch statement in the heart of your code. This also makes it easy to do things like pop up inventory screens or maps on top of your game screen, since you''re just adding another event onto the stack.

>>would it be a better idea to load ALL of every area''s data on startup or load it each time a different area is loaded?<<

In general, I''d say no. It''s probably easier, at least in the beginning, to load everything up, but you can get yourself into trouble if you end up with too much data. I''d say you''d be better off figuring out a good loading scheme at the start if you plan on having fairly big scenes. Afterall, loading screnes aren''t as annoying as crashes

-John

Share this post


Link to post
Share on other sites
hmmm... that does give me an idea, i dont know enough about function pointers to know how to effectively impliment what you described (im reading about them at http://www.function-pointer.org). but i do like the idea of simply having one central event queue that handles everything.

Bungo!

Share this post


Link to post
Share on other sites
I have a much better, Object-Oriented solution. I can''t take credit for it, but here it goes...

Have an abstract class called AbstractGameMode. Then, just derive game modes from there like:


  BattleMode : public AbstractGameMode {...};  


AbstractGameMode should have virtual functions like DrawOnScreen(), Update(), etc. Then you would just say something like:


  AbstractGameMode a* = new BattleMode ();

a.DrawOnScreen();


There could be some syntax errors in my code since I usually use Java.

Share this post


Link to post
Share on other sites
I use a technique similar to yaroslavd's and it works very well. Once you make a instance of each game mode you have a pointer to the state currently in use, and since all the functions are virtual you just call currentState->Draw() or whatever.

[edited by - punx on May 1, 2003 11:56:25 PM]

Share this post


Link to post
Share on other sites
Bungo, this will appear in article 5/6

The virtual function approach is the one I''ve found to be the best. You have a base class IAppState:


  
class IAppState
{
public:
virtual bool Enter()=0; //tell the state to start up

virtual void Draw()=0;
virtual void Update(float timeStep)=0;
virtual void Leave()=0; //tell the state to shut down

};


You make the functions ''pure virtual'' (virtual with =0 on the end) to force derived classes to implement them, so that way you don''t forget to provide a Leave() function or whatever.

Then you just derive from it, and have a singleton AppStateManager somewhere, which contains an IAppState pointer to the current state, and has a SwitchState() function which calls Enter() and Leave() on the appropriate states.

Superpig
- saving pigs from untimely fates, and when he''s not doing that, runs The Binary Refinery.

Share this post


Link to post
Share on other sites
What I've started doing recently is move the message pump to it's own function. It doesn't matter where the message pump funcs are called, as long as they are called in the same thread that created the window. so my Msg func looks like this: (There is actually more going on in the func, llike my game clock, etc.)


if(PeekMessage(&msg, NULL,0,0,PM_NOREMOVE))
{
if (msg.message == WM_QUIT)
Quit = 2;
GetMessage (&msg, NULL, 0, 0);
TranslateMessage (&msg);
DispatchMessage (&msg);
}



Then in my main func, I call all the substates just like I would in a good old fashoined linear dos game. The contents of these substate funcs look basically like this:


while (!Quit)
{
// Always process messages first
DoSys ();

// Do rest of stuff
}



The Quit flag is a private member of my CGame class. When the WndFunc reieves a WM_CLOSE it sets quit to 1. Also, anytime I want the app to end I just set quit to 1. Quit being non-zero causes all my substate funcs to quit out, and not run if they have yet to be invoked. The reason DoMsgs sets quit to 2 is that the main func needs to wait till all messages have been processed and the WM_QUIT message has been recieved. Once this happens the program ends.

-Zims

[edited by - Zimans on May 2, 2003 1:08:00 PM]

Share this post


Link to post
Share on other sites