Results 1 to 10 of 26

Thread: State machine - requesting advice

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Case structure for states can look like this:
    Code:
    // In render loop
    case MainState of
      msIntro: RenderIntro;
      msMenu: RenderMenu;
      msGame: RenderGame;
    end;
    ...
    // In the game loop
    case MainState of
      msIntro: LoopIntro;
      msMenu: LoopMenu;
      msGame: LoopGame;
    end;
    If you need to add another state, you can just make new procedures, and make related code there very cleanly. If you need substates, you can make new similar case inside LoopMenu for example. Depending on implementation, i might use menu classes of nxpascal, similar to IDE components in practise. If i click "Start game" button:
    - In component approach the onClick event would be raised and handled, and then call StartGame() in it. I could simply hide or show entire panels of buttons and things.
    - Oldschool way a StartGame() procedure would be called directly in some onMouseDown/Up/click event. There needs to be some integer variable telling index of button that was mouse-focused, and another variable telling which menu is open.
    Another variables handling fadein, fadeout of states. Usually i only set NewState:=msGame; or something in the StartGame(). After the msGame has faded out, then set MainState:=NewState; . This can happen in the general loop, common for all states.

  2. #2
    Still, seems like hacky solution to me. I JUST DON'T WANT TO FORGET MEANING OF MY CODE AFTER NOT LOOKING INTO IT FZOR 3 MONTHS OR MORE ANYMORE!!!

    Erm... Sorry for that little burst. Anyway, I think there may be a problem with setting states from within other states.

    Problem is that I won't be able to access global variable declared in main program from within other units (each state would get its own unit for clarity sake). Any ideas how to solve it?

  3. #3
    You can always add main unit in uses clause. And for avoiding ciclick dependancies you do it in implementation part of your state units.
    So for instance you have UMain unit as general game unit and several other units each for its own state.
    For you to be able to create theese state objects you need to add theese units into uses section of your UMain file.
    But if you wanna acces objects and variables declared which are in UMain file from theese state units you add UMain file into uses section which you declare in implementation section:
    Code:
    ...
    implementation
    uses UMain //Main game unit
    ...
    Do not add UMain unit into uses section on top of your states units othevise you will cause cicklic redundancies (compiler won't be able to figure out which units need which) and you won't be able to compile your project.

  4. #4
    Quote Originally Posted by Darkhog View Post
    Still, seems like hacky solution to me.
    It is not so teribly hacky. Until now I have always been using such approach. But I still think that your idea is actually better.
    Anywhay in the end it all depends on how good you implement it. You can have great idea but if your implementation of this idea is terible so will be result.

  5. #5
    I have 1 rule of thumb for all applications i ever make: Never add application main unit to uses list of other units. It is really unmodular and bad habit. Only when it's really really necessary for 2 forms needing alot of communication between eachother, then i might consider cross-using.

    Instead you can make for example gameunit.pas or gametypes.pas, and introduce all global types and variables there. This unit would use no other units in itself, but could be included up to all your other units. Kind of like this:
    https://code.google.com/p/nxpascal/s...rc/nxTypes.pas
    nxTypes is included throughout the whole engine, and all of the units have access to nxSetError() for consistent error reporting, types and other little things.

    And on topic, if you would have to make a whole class implementation for each different state, then at least i would consider it more complicated than the case-procedure way. It might be smarter, but it might take a whole lot more code lines

  6. #6
    Well, it might take more lines, but in the end I'll get nice clean and extensible code. And if I declare my state variable in e.g. Unit global, it'll modify same area of memory when accessed from unit A (which includes it) and unit B? Just want to be sure.

    Also thanks for being so helpful. I'll be sure to re-read this thread when I'll do actual state machine implementation (for now I need to get done more important stuff like chunk rendering and tileset handling).

  7. #7
    i've used it in few projects but i can't say i invented it
    http://gamedevgeek.com/tutorials/man...e-states-in-c/
    check out the 'stack of states' thing - really usefull for menus

  8. #8
    Laggyluk, interesting read, thanks.

    Now that I've started actually implementing this, I'll post any problems I'll have with this in this thread.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •