1

Showing main menu over objects / movieclips?

This is the question I posted and Cherniv helped me out with where to go. However, I have ran into some difficulties when trying to initialize / define a button to add an event handler to it. This is my 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;
    }
  }
}

And this is my 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"))
    }
    }

I gave the button an instance name of playBtn before I converted the menu to a movieclip but I get the error mentioned and not quite sure how to resolve it.

All of the buttons are in the library, nothing is in the timeline as my movieclips and whatnot are added dynamically to the stage through the use of Actionscript in the .as files. I basically need to find a way to dynamically add the menu as the first thing that appears when the game opens and clicking the 'Play' button removes the menu, shows the game layer and starts the timers.

Thank you for any help.

Community
  • 1
  • 1
Liam
  • 65
  • 10
  • did you check export for actionscript? – The_asMan May 10 '13 at 19:28
  • Just add a definition for it: `public var playBtn:MovieClip;` make sure you use the public keyword – BadFeelingAboutThis May 10 '13 at 19:28
  • @LondonDrugs_MediaServices Is this the right thing to do? I basically put my four buttons and whatnot onto the stage in another .fla, highlighted everything and turned it into a movieclip called `myMenu` with AS Linkage as `Menu`. I set each of the buttons instance names before I created the movieclip symbol. Have I done this wrong? – Liam May 10 '13 at 19:32
  • That should work, but your .as files don't know about them until runtime so you have to define them as per my answer – BadFeelingAboutThis May 10 '13 at 19:40
  • So playBtn is only in your Menu class/timeline? not your Main class? – BadFeelingAboutThis May 10 '13 at 19:41
  • All of the buttons are in the library, nothing is in the timeline as my movieclips and whatnot are added dynamically to the stage through the use of Actionscript in the .as files. I basically need to find a way to dynamically add the menu as the first thing that appears when the game opens and clicking the 'Play' button removes the menu, shows the game layer and starts the timers. – Liam May 11 '13 at 01:02

1 Answers1

1

Your class file doesn't know about the playBtn instance because it's only defined at runtime (when dropped on a timeline in flashPro and given an instance name)

All you need to do is define the var in your class:

public var playBtn:MovieClip;  //or if not a movieClip whatever displayobject type it is

flashPro will automatically use that var to store the playBtn instance from your timeline if it has the same instance name as the var.

You also have an issue your Menu.as class. The following two lines:

Main.menuLayer.addChild(myMenu);
playBtn.addEventListener(MouseEvent.CLICK, playBtnPressed);

Need to be contained in a function (probably want it your constructor), so it should look like this:

public class Menu extends MovieClip {

    public var mainMenu:Menu; //I don't think you want this at all in this class

    //creating a function with same name as your class creates a constructor, which is called when you instantiate an object: eg  new Menu();
    public function Menu():void {
        mainMenu = new Menu();     //this seems very strange, and would create an endless overflow of new menu objects, I don't think this is what you want   

        Main.menuLayer.addChild(myMenu);

        //again, you need to either define this var, not sure if it's supposed to be a passed in var from your other class or a separate instance 
        playBtn.addEventListener(MouseEvent.CLICK, playBtnPressed);
    }

    function playBtnPressed()
    {
        Main.menuLayer.removeChild(myMenu);
        dispatchEvent(new Event("playButtonPressed"))
    }
}
BadFeelingAboutThis
  • 14,445
  • 2
  • 33
  • 40
  • I see, but my menu MovieClip is called `myMenu`. I take it I'd change `mainMenu = new Menu();` to `myMenu = new Menu();`? The four buttons in my library are `aboutBtn`, `hiscoresBtn`, `howToPlayBtn` and `playBtn` and they were defined as Buttons (Buttons dropped onto the stage to create the menu and THEN I converted the menu to a movieclip named `myMenu` with a class called `Menu`). All I am trying to do is separate my menu and the rest of the program so that when opening the game, the menu will display but the timers for the game will only start once the 'Play' button has been clicked. – Liam May 10 '13 at 19:40
  • The class is whatever you told the linkage to be. So if the linkage is set to `Menu`, then you'd want `mainMenu:Menu = new Menu();` mainMenu is the name of the instance, Menu is the name of the class/type – BadFeelingAboutThis May 10 '13 at 19:45