[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] State Machine Organization



Dave, what you describe sounds sensible to me. Until now I never worried about this kind of interface-stacking (never had many interface elements), but my MVC implementations should support what you describe without too much hassle.

But why are you referring to those screen instances as "states"? Or is this just to keep in tone with the thread?



On 7/7/07, Dave LeCompte (really) <dave@xxxxxxxxxxxx> wrote:
"Greg Ewing" < greg.ewing@xxxxxxxxxxxxxxxx> wrote:
> Kris Schnee wrote:
>> The idea is that instead of calling a shop screen from a walking-around
>> screen, which risks having you get into some tangled recursion, the
>> program "drops" from the walking screen back to the main loop, with a
>> state variable saying "the next screen to go to is the shop screen."
>
> This sounds similar to the way I've organised a couple of
> my recent PyGame entries. I have a Shell object at the top
> which implements the main loop. The Shell has an instance
> variable called current_screen which at any moment points
> to one of a number of different Screen subclasses which
> present different user interfaces. The Screen objects have
> methods for drawing the display, handling input events,
> etc.

I did something similar, sort of, for my most recent entry. Everything was
a "state", and I maintained a stack of states. Call this a Hierarchical
Finite State Machine, if you like. When I needed to interrupt a state to
pop up a dialog box (a good example was during my tutorial sequence), I'd
simply push a dialog box state onto my stack. When the dialog was done,
it'd pop itself off, and the old state would be the top of the stack.

Each state would implement OnDraw and OnUpdate events, with a few states
doing quasi-fancy things. For example, those dialog boxes would let their
parents draw first before drawing themselves, which gave the effect of
dialogs being "in front of" the main game screen. When I wanted to go back
to the main menu, I popped everybody off the stack, and pushed a new
instance of the main menu state onto the stack.

That worked pretty well for me, but I ended up keeping some data in the
state objects that probably belonged in a more intelligently encapsulated
place.

Thinking about MVC, this approach does separate out the logic (model) from
the display (view) - I didn't mention it above, but there's also
OnMouseDown and OnKeyDown which gets you the controller, as well. So I
didn't break up M/V/C into three separate classes, but each state object
had a pretty clean division of code.


If people are still looking for arguments in favor of separating out the
update logic from the display, there were two cases where it paid off in
my game:

- As I mentioned above, dialog boxes could be considered "child" states of
main gameplay states. By having the display of the parent state callable
without any update, I could suspend the progress of the game for a
temporary interruption (the "pause" menu that came up when you hit escape
or the window lost focus, tutorial dialog boxes, level intros).

- Having the game logic in one place, unentangled with display code made
it easier (after the challenge was over) to pull it out into a clean
location, so the AI could call it multiple times as a cheap form of
"lookahead". Rather than make the AI smart, it just simulated trying a
bunch of random options, and picked from the best results.


> (I'm going to have to write a wysiwig ascii-art drawing
> editor one day...)

I recently found out about emacs' "artist-mode", which seems just about
the level of quality that I'd need for ASCII art. I've even considered
(ab)using it as a level editor.

http://www.tulrich.com/geekstuff/emacs.html (look for artist-mode, towards
the bottom.)


I really gotta get back to working on my RPG.

-Dave LeCompte