0
votes

I have implemented a VERY simple State Loop based off of some examples in the book: "The Essential guide to Flash Games" by Jeff and Steve Fulton; In this state machine I have a loop that updates the stage to the target gameState var through an Enter_Frame event.

Inside my Menu state I have a button with a MovieClip inside the OVER state that would normally loop ad infinitum so long as the button is in the OVER state, but the clip does not even play through once; I'm guessing its due to the Enter_Frame event placing a new instance every frame, My question is: Is there a better way to update the State loop only when the gameState var is changed or does that sound like the wrong guess at the problem?

Let me know if this is too vague on the details, I was not sure if posting the code snippets would really help for this question... Thanks for reading and for any responses ahead of time! Here's the code! :-)

//imports here  
public class Loop extends MovieClip {
    public static const STATE_MMENU:int = 10;
    public static const STATE_OPTIONS:int = 11;
    public static const STATE_NGAME:int = 20;
    public static const STATE_CHARSELECT:int = 21;
    public static const STATE_BATMAP:int = 22;
    public static const STATE_BATSTORY:int = 23
    public static const STATE_BATTLE:int = 30;
    public static const STATE_DOMDICEPHASE:int = 31;
    public static const STATE_ROLLPROCESS:int = 32;
    public static const STATE_WINLOSSPHASE:int = 33;

    public var gameState:int = 0;

    public function Loop():void {

        addEventListener(Event.ENTER_FRAME, gameLoop);
        gameState = STATE_MMENU;
    }

    public function gameLoop(e:Event):void{
        switch(gameState){
            case STATE_MMENU:        mainMenu();            break;
            case STATE_OPTIONS:      optionsMenu();         break;
            case STATE_NGAME:        newGame();             break;
            case STATE_CHARSELECT:   charaSelect();         break;
            case STATE_BATMAP:       battleMap();           break;
            case STATE_BATSTORY:     battleStory();         break;
            case STATE_BATTLE:       battlePhase();         break;
            case STATE_DOMDICEPHASE: domDicePhase();        break;
            case STATE_ROLLPROCESS:  rollProcessPhase();    break;
            case STATE_WINLOSSPHASE: winLossPhase();        break;
        }
}
        //insert functions for phases/states here lol :-0

        public function mainMenu(){
        var titleText:title_gfx = new title_gfx();
        titleText.x = 520;      titleText.y = 150;
        addChild(titleText);

        var newGameSel:newGame_btn = new newGame_btn();
        newGameSel.x = 512;     newGameSel.y = 300;
        addChild(newGameSel);
        //newGameSel.addEventListener(Mouse.MouseEvent.CLICK, newGameButton);

I'm inserting the button with the movieclip inside the mainMenu() function... Thanks again!

1
It's kind of weird to place a new instance every frame. Maybe you could dispatch an event when the gameState var changes and in the listener for that event update the buttons. It would probably be helpful to post some code if you need more pointers. From your question, I can't figure out what you're doing in the enter_frame event. - Cristina Georgescu
I posted some code! Thank you for looking! :-D An aside If I place that button on the stage it works as intended, just gets sluggish after a few seconds so I'm not too sure weather this is me bogging the P.C. down or what lol - SkeleDog
How are you adding the buttons in mainMenu? You should probably instantiate them only once if they aren't instantiated already. Kind of weird that the button gets sluggish. Do you have any code in the button? - Cristina Georgescu
In the code I have just added a sample of what the main menu looks like so far, I just instantiate the button like normal edit the .x and .y add it to the display list, I was kind of wondering if I shouldn't have this happen only if theres not already an instance? Is this possible through a for loop, maybe I could have the first iteration trigger an if statement checking if the instance is present? There is no code in the button. I'm trying to NOT code in the timeline as much as possible. I guess this is just me trying to REALLY learn something instead of just being lazy lol - SkeleDog

1 Answers

0
votes

You're basically adding a new titleText and newGameSel every frame. If you're FPS is 24, every second you're adding 24 movieclips for each button. You could keep a global boolean variable, like isMainMenuCreated, which initially is false, and you set it to true after you instantiate the buttons for the first time.

 public var gameState:int = 0;
 public var isMainMenuCreated:Boolean = false;

 //rest of your code

 public function mainMenu():void { 
    if(isMainMenuCreated) return;

    //code for button instantiation and placing
    isMainMenuCreated = true;
 }

That's one way to do it. Other way would be to remove the ENTER_FRAME event listener in the mainMenu function and re-add it after you click the new game button. The latter would be more performant, as you're only keeping the game state loop when needed. You don't really need to update the main menu screen 24 times per second when the player does nothing.

Another thing to consider is if you really need a game loop in your game. Some games, like action games, where you need to update the graphics in real time (think platformers) need a game loop. Point and click games don't need a game loop.