0

I am creating a game in Flash and I am creating a main menu for the game (With buttons like 'Play', 'How to Play', 'Hiscores' etc.) and was wondering what is the best way to go about it?

All of my Actionscript code is in external .as files and I've used classes throughout but I was having trouble figuring out how to get it so that the menu will be shown as soon as the game is ran. The main problem is that there are timers in my game that have event handlers attached to them and I was trying to think of the best way to essentially stop these timers until the user actually clicks 'Play', otherwise the objects spawn over the top of the menu and the timer ticks down.

Would stopping the timers but then adding an event handler to the play button to start the timers be a good idea? I am trying to figure out the best way to do this for future reference.

Thank you for any assistance.

Edit: Tried Cherniv's advice, getting some errors.

Main.as:

package  {
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import flash.ui.Mouse;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.text.TextFormat;
    import flash.text.TextField;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.net.URLLoader;
    import flash.system.LoaderContext;
    import flash.display.Sprite;
    import flash.net.Socket;


    public class Main extends MovieClip {

    public static var gameLayer:Sprite = new Sprite;
    public static var endGameLayer:Sprite = new Sprite;
    public static var menuLayer:Sprite = new Sprite;

    public var gameTime:int;
    public var levelDuration:int;

    public var crosshair:crosshair_mc;
    static var score:Number;

    var enemyShipTimer:Timer;
    var enemyShipTimerMed:Timer;
    var enemyShipTimerSmall:Timer;

    static var scoreHeader:TextField = new TextField();
    static var scoreText:TextField = new TextField();
    static var timeHeader:TextField = new TextField();
    static var timeText:TextField = new TextField();

    public function Main()
    {
        var mainMenu:myMenu = new myMenu;
        addChild(gameLayer);
        addChild(endGameLayer);
        addChild(menuLayer);

        playBtn.addEventListener(MouseEvent.CLICK, startButtonPressed);
    }

    function startButtonPressed(e:Event)
    {
        levelDuration = 30;
        gameTime = levelDuration;
        var gameTimer:Timer = new Timer(1000,levelDuration);
        gameTimer.addEventListener(TimerEvent.TIMER, updateTime);
        gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeExpired)
        gameTimer.start();

        scoreHeader = new TextField();
        scoreHeader.x = 5;
        scoreHeader.text = String("Score: ");
        gameLayer.addChild(scoreHeader);

        scoreText = new TextField();
        scoreText.x = 75;
        scoreText.y = 0;
        scoreText.text = String(0);
        gameLayer.addChild(scoreText);

        timeHeader = new TextField();
        timeHeader.x = 490;
        timeHeader.y = 0;
        timeHeader.text = String("Time: ");
        gameLayer.addChild(timeHeader);

        timeText = new TextField();
        timeText.x = 550;
        timeText.y = 0;
        timeText.text = gameTime.toString();
        gameLayer.addChild(timeText);

        var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
        scoreHeader.setTextFormat(scoreFormat);
        scoreText.setTextFormat(scoreFormat);
        timeHeader.setTextFormat(scoreFormat);
        timeText.setTextFormat(scoreFormat);

        enemyShipTimer = new Timer(2000);
        enemyShipTimer.addEventListener("timer", sendEnemy);
        enemyShipTimer.start();

        enemyShipTimerMed = new Timer(2500);
        enemyShipTimerMed.addEventListener("timer", sendEnemyMed);
        enemyShipTimerMed.start();

        enemyShipTimerSmall = new Timer(2750);
        enemyShipTimerSmall.addEventListener("timer", sendEnemySmall);
        enemyShipTimerSmall.start();

        crosshair = new crosshair_mc();
        gameLayer.addChild(crosshair);

        crosshair.mouseEnabled = crosshair.mouseChildren = false;

        Mouse.hide();

        gameLayer.addEventListener(Event.ENTER_FRAME, moveCursor);
        resetScore();
    }

    function sendEnemy(e:Event)
    {
        var enemy = new EnemyShip();
        gameLayer.addChild(enemy);
        gameLayer.addChild(crosshair);
    }

    function sendEnemyMed(e:Event)
    {
        var enemymed = new EnemyShipMed();
        gameLayer.addChild(enemymed);
        gameLayer.addChild(crosshair);
    }

    function sendEnemySmall(e:Event)
    {
        var enemysmall = new EnemyShipSmall();
        gameLayer.addChild(enemysmall);
        gameLayer.addChild(crosshair);
    }

    static function updateScore(points)
    {
        score += points;
        scoreText.text = String(score);
        var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
        scoreHeader.setTextFormat(scoreFormat);
        scoreText.setTextFormat(scoreFormat);
    }

    static function resetScore()
    {
        score = 0;
        scoreText.text = String(score);
    }

    function updateTime(e:TimerEvent):void
    {
        trace(gameTime);
        // your class variable tracking each second, 
        gameTime--;
        //update your user interface as needed
        var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
        timeText.defaultTextFormat = scoreFormat;
        timeText.text = String(gameTime);
    }

    function timeExpired(e:TimerEvent):void
    {
        var gameTimer:Timer = e.target as Timer;
        gameTimer.removeEventListener(TimerEvent.TIMER, updateTime)
        gameTimer.removeEventListener(TimerEvent.TIMER, timeExpired)
        // do whatever you need to do for game over
    }

    function moveCursor(event:Event) 
    {
      crosshair.x=mouseX;
      crosshair.y=mouseY;
    }
  }
}

Menu.as:

package  {
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.display.DisplayObject;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;
    import flash.ui.Mouse;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.text.TextFormat;
    import flash.text.TextField;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.net.URLLoader;
    import flash.system.LoaderContext;
    import flash.display.Sprite;
    import flash.net.Socket;

    public class Menu extends MovieClip
    {

    var mainMenu:Menu = new Menu();

    Main.menuLayer.addChild(myMenu);

    playBtn.addEventListener(MouseEvent.CLICK, playBtnPressed);

    function playBtnPressed()
    {
        Main.menuLayer.removeChild(myMenu);
        dispatchEvent(new Event("playButtonPressed"))
    }
    }

My menu is a movieclip named myMenu and the class is set as Menu but I get errors such as:

Main.as, Line 50 1120: Access of undefined property playBtn

I gave the button an instance name of playBtn before I converted the menu to a movieclip so not sure what's going on there. I'm probably missing something really easy but it's a bit confusing for me after typing all day.

Liam
  • 65
  • 10

1 Answers1

0

If you have all of your initialization stuff (including timers initializations) in Main constructor function , so you need to split it to two functions , Main constructor will show the menu , and "start" button will fire the second function , that will include all the initialization stuff

Ivan Chernykh
  • 41,617
  • 13
  • 134
  • 146
  • Ah so just put the menu into the `Main` constructor and everything else (as appropriate) into another function. I'm still not sure about the menu; would it be better to make it into a movieclip and import it to the library or a different way? – Liam May 08 '13 at 13:46
  • Put the menu in Menu class , and then instantiate and run it in the Main class constructor, like `var myMenu:Menu = new Menu();` – Ivan Chernykh May 08 '13 at 14:03
  • Forgive me for being confused (Heads all over the place lately). So, create a movieclip out of the menu and set the class to `Menu` then in the `Main` constructor, instantiate and run it? No need to create a `Menu.as` Actionscript file? – Liam May 08 '13 at 14:06
  • No , your menu `movieclip` is the menu , in its library properties set its class to `Menu` , and class itself put in Menu.as – Ivan Chernykh May 08 '13 at 14:19
  • Yeah, thought so since that's the way I've done it with other objects (i.e. randomly spawning ships are a movieclip with a class called `EnemyShip` and the class code is in the `EnemyShip.as` file) but thought I'd double check to be sure. Thank you. – Liam May 08 '13 at 14:26
  • How can I add event handlers to the buttons if the menu is going to be converted to a movieclip or am I going about this wrong? – Liam May 08 '13 at 23:37
  • Put all buttons' events handlers inside `Menu` Class. When you need to inform your `Main` class that 'start' button pressed then Menu class will dispatch special event , like `dispatchEvent(new Event("startButtonPressed"))` – Ivan Chernykh May 09 '13 at 05:18
  • So I add an event listener to the 'Play' button inside the `Menu` class like `playBtn.addEventListener(MouseEvent.CLICK, playBtnpressed);` then inside the `playBtnpressed` I type what I want it to do i.e. hide the menu, show the game and start the timers then what do I do from there? I'm trying to get a better idea on how to do it correctly so I don't ask questions over and over. – Liam May 09 '13 at 18:03
  • in `playBtnpressed` you hide the menu , and dispatching some custom event as i mentioned before. in main class you catch this custom event , and as you said "show the game and start the timers etc" – Ivan Chernykh May 09 '13 at 18:24
  • So I do the `dispatchEvent` inside the `playBtnpressed` function in the `Menu` class then I catch the event in `Main` and then hide the menu/start the timers? How do I catch an event? – Liam May 09 '13 at 18:41
  • as usual , with `addEventListener`. – Ivan Chernykh May 09 '13 at 18:49
  • @Liam you almost there. Try to put in `Main` class constructor this line: `mainMenu.addEventListener("playButtonPressed", startButtonPressed);` instead of this line: `playBtn.addEventListener(MouseEvent.CLICK, startButtonPressed);` – Ivan Chernykh May 10 '13 at 19:29