0

lots of help from you guys :). My next question is here :).

I have timer in class MyTimer.as and Thief1_mc.as movie clip. How can I addChild(Thief1_mc) on the stage from MyTimer? Everything looks simple, the only problem is "stage" property. MyTimer class cannot send "stage" as an argument because is not on the stage itself. I tried adding MyTimer on the stage in Main class like addChild (MyTimer), the trace says MyTimer is on the stage but I still cannot pass the stage argument to the Thief1_mc. I need this argument to be sent because the class Thief1_mc has to add itself on the stage using the property "stage".

The code:

public class Thief1_mc extends MovieClip
{

    //this variable type Stage will contain stage
    private var stageHolder:Stage;

    public function Thief1_mc()
    {
        //constructor
    }

    //function that creates this object with passed "stage" argument from the caller
    public function createItself(st):void
    {
        //variable that contain the stage so I can use this argument anywhere in the class 
        stageHolder = st;
        //i have to refer to the stage by passed "st" parameter to create this object
        stageHolder.addChild(this);
        //initial position
        this.x = 380;
        this.y = 230;
    }

}

}

MyTimer class and "_thief1.createItself(stage)" caller with stage arument

public class MyTimer extends Sprite
{
    private static var nCount:Number = 120;
    private static var currentCount:Number;
    private static var _timer:Timer = new Timer(1000,nCount);

    private static var _timerDispather:Timer;
    private static var _thief1:Thief1_mc = new Thief1_mc ;

    public function MyTimer()
    {
        // constructor code
    }

    //another timer
    private static function increaseInterval(interval:int):void
    {
        _timerDispather = new Timer(interval);
        _timerDispather.addEventListener(TimerEvent.TIMER, onUpdateTimeAnotherTimer);
        _timerDispather.start();
    }
    //another timer;
    private static function onUpdateTimeAnotherTimer(e:Event):void
    {

        _thief1.createItself(stage);//the most important part
    }

    public static function activateTimer():void
    {
        currentCount = nCount;
        _timer.addEventListener(TimerEvent.TIMER, onUpdateTime);
        _timer.start();
    }

    public static function deactivateTimer():void
    {
        _timer.removeEventListener(TimerEvent.TIMER, onUpdateTime);
        _timer.stop();
        _timer.reset();
        currentCount = nCount;

        //another timer
        _timerDispather.removeEventListener(TimerEvent.TIMER, onUpdateTimeAnotherTimer);
        _timerDispather.stop();
        _timerDispather.reset();
    }

    private static function onUpdateTime(e:Event):void
    {
        currentCount--;


        if (currentCount == 0)
        {
            _timer.removeEventListener(TimerEvent.TIMER, onUpdateTime);
            _timer.stop();
            _timer.reset();

        }
    }
}

}

irnik
  • 139
  • 1
  • 2
  • 13

1 Answers1

1

Your code is backwards in a few places. It does not flow very nicely, and the issues you having now are going to be tenfold at some stage in your project.

Firstly, your MyTimer class should not be extending Sprite. It does not get rendered and does not represent anything graphically.

Secondly, your timer class is taking on more than it should. I would revise it to manage your timers and timer events only. Create a list within your timer class that will contain some other elements which can have a method triggers to do other stuff, like creating and adding Thief1_mc.

A simplified version of this might look like:

public class Updater
{

    private var _timer:Timer;
    private var _toUpdate:Vector.<IUpdatable> = new Vector.<IUpdatable>();


    public function Updater()
    {
        _timer = new Timer(60);
        _timer.start();
        _timer.addEventListener(TimerEvent.TIMER, _notifyUpdatables);
    }


    private function _notifyUpdatables(e:TimerEvent):void
    {
        for each(var i:IUpdatable in _toUpdate)
        {
            i.update(this);
        }
    }


    public function addUpdatable(updatable:IUpdatable):void
    {
        _toUpdate.push(updatable);
    }


    public function removeUpdatable(updatable:IUpdatable):void
    {
        var index:int = _toUpdate.indexOf(updatable);
        if(index >= 0) _toUpdate.splice(index, 1);
    }

}

From here we need to create an interface which we will implement on classes that we want to be able to call update() on each time the Updater timer ticks:

public interface IUpdatable
{
    function update(updater:Updater):void;
}

Now what I would do in your case is have a class that does extend Sprite and manages the graphics of the application / game. It will implement the IUpdatable interface like I have described and also could deal with adding your Thief1_mc:

public class View extends Sprite implements IUpdatable
{

    public function update(updater:Updater):void
    {
        // Create a Thief.
        var thief:Thief = new Thief();

        updater.addUpdatable(thief);
        addChild(thief);
    }

}

Your Thief can take advantage of the IUpdatable interface we have and be added to the update queue when it is created, as I've done above. Just to have a complete example, here's the Thief class:

public class Thief extends Sprite implements IUpdatable
{

    public function update(updater:Updater):void
    {
        // Make this Thief so some stuff.
        //
    }

}

And here's how you can tie it all together in your document class:

public class App extends Sprite
{

    private var _updater:Updater;
    private var _view:View;


    public function App()
    {
        _updater = new Updater();
        _view = new View();

        _updater.addUpdatable(_view);

        stage.addChild(_view);
    }

}

This might be a bit overwhelming at first, and seem like a lot of work, but you now have a nice clean foundation to add more elements easily.

Rather than having your one class trying to manage timers and add Thieves like you had initially, we've separated the responsibilities and tightened up the flow a little. The Updater deals purely with storing IUpdatable instances and calling their update() method each time the Timer within it ticks. The View class manages the graphics and will also add a Thief each time it is updated via the Updater. The View was added to the stage initially, so all you need to do is add the thieves into itself to have them show up.

If you take this and restructure how the timers work within Updater, I think you'll be where you wanted but with a significantly better understanding and structure.

Marty
  • 39,033
  • 19
  • 93
  • 162
  • Thanks for your answer. I will examine your code but it seems to me a bit complicate for such a simple task. Basically I need to create object on the stage every time MyTimer ticks. My biggest concern here is that MyTimer cannot access property stage even if MyTimer is added on stage by Main class!?! Well, I know that if an object is on stage it should have access to the stage property ??? Thanks again Marty – irnik Apr 17 '13 at 07:22
  • @irnik Sure, for the sake of fixing your specific problem asap, just make a static method in your `MyTimer` class like `public static function setState(stage:Stage)` which then sets a property within the class that you can use to refer to the stage. – Marty Apr 17 '13 at 07:26
  • @irnik Forgive my lengthy answer, but I am confident that you will return here in the near future when your code becomes unmanageable and take some pointers from it :) – Marty Apr 17 '13 at 07:27
  • :) I know Marty but as a newbie I prefer to work with staff I am familiar with :) – irnik Apr 17 '13 at 07:34
  • @irnik True, but it is good to be exposed to good programming styles early on rather than doing myself and a lot of other developers do which is learn the 'easy' way first and then having to backtrack and learn the proper way in the end anyway. – Marty Apr 17 '13 at 07:45
  • Agree, but Marty how you going to explain this issue: I added MyTimer on the stage by addChild(MyTimer) and it still doesn't have access to property stage !?! – irnik Apr 17 '13 at 08:00
  • @irnik Most likely is that your timer event is triggering once before you have access to the stage. – Marty Apr 17 '13 at 08:02
  • yes, that could be the problem. Thanks. I cannot figure out how to use this public static function setState(stage:Stage)? – irnik Apr 17 '13 at 08:05
  • @irnik [Take a look here](http://pastebin.com/1fb20MGS). Basically I've set up a class-level variable `_stage` which will have the stage assigned to it via `setStage()`. Then in the class you can just use `_stage` to refer to the stage. – Marty Apr 17 '13 at 08:11