dcsimg
A Flash Developer Resource Site

Results 1 to 10 of 10

Thread: Referencing Stage from class

  1. #1
    Junior Member
    Join Date
    May 2008
    Posts
    18

    Referencing Stage from class

    Hello,
    I am trying to make my first as3 class based game and so i was wondering if i could get some help. although the game wont have fancy graphics, i just would like to understand the way it works...currently, i am at a point where im getting :

    1067: Implicit coercion of a value of type flash.display:Stage to an unrelated type Stage.
    in my main file robot.fla, im using

    var robo:robot=new robot(stage);
    //var starenemy:enemy1=new enemy1(this.stage);
    addChild(robo);

    inside that robot.as
    ....
    public class robot extends Sprite {
    import flash.display.Stage;
    private var _stage:Stage;
    ....
    public function robot(stageRef:Stage):void {
    _stage = stageRef;
    ...
    }
    amongst other things and i cant reference anything from the stage.

    I think im going nuts trying to figure out how to correctly reference things to the stage. so can you take a look and guide me and tell me how i can proceed?
    Attached is the zip file
    Attached Files Attached Files
    Code:
    sup.

  2. #2
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    You should either:
    (a). wait until the class is added to the stage (i.e. put an event listener within it like:
    this.addEventListener(Event.ADDED_TO_STAGE,this.go tadd);
    )
    and then you can just reference stage lowercase and it will pick up the reference... or
    (b). pass a reference to the main timeline, not the stage. The main timeline is a movieclip, and it is equivalent to your document class. So...

    var robo:robot=new robot(this);
    //var starenemy:enemy1=new enemy1(this);
    addChild(robo);

    inside that robot.as
    ....
    public class robot extends Sprite {
    private var _timeline:Object;
    ....
    public function robot(timeline:Object):void {
    _timeline = timeline;

    //here you can reference the stage as _timeline.stage
    ...
    }

  3. #3
    Junior Member
    Join Date
    May 2008
    Posts
    18
    Hello, method B worked for me which still leaves me with another weird happening. the object is fired erratically.
    Can you take a look and see whats going on? Cos currently, my roboarm is rotating correctly but the bullet is firing at a weird unknown direction.

    below is the code :
    Code:
    private var robbody:body=new body();
    private var robarm:arm = new arm();
    private var bulletnum:Number;
    private var _stage:Object;
    
    public function robot(tl:Object):void {
    		_stage = tl;
    		robbody.x = robarm.x = 225;
    		robbody.y = robarm.y = 250;
    		_stage.stage.addChild(robbody);
    		_stage.stage.addChild(robarm);
    		addEventListener(Event.ADDED_TO_STAGE, addListeners);
    }
    private function moveArm(e:MouseEvent):void {
    	if ((mouseX - robarm.x) > 0) {
    		robarm.rotation = Math.atan((robarm.y - mouseY) / (robarm.x - mouseX))*180/Math.PI;
    	} else {
    		robarm.rotation =180+Math.atan((robarm.y - mouseY) / (robarm.x - mouseX))*180/Math.PI;
    	}
    		e.updateAfterEvent();
    }
    private function shootMe(e:MouseEvent):void {
    	if (!robarm.hitTestPoint(mouseX,mouseY,false)) {
    		var bullet:bomb1=new bomb1();
    		bullet.x=robarm.x;
    		bullet.y=robarm.y;
    		bullet.rotation=robarm.rotation;
    		_stage.stage.addChild(bullet);
    		_stage.stage.swapChildren(robarm,bullet);
    		bullet.addEventListener(Event.ENTER_FRAME,moveIt,false,0,true);
    }
    }
    private function moveIt(e:Event):void {
    	with (e.target) {
    		x+= 10*Math.sin(rotation*(Math.PI/180));
    		y-= 10*Math.cos(rotation*(Math.PI/180));
    		if (x>=550||x<=0||y>=400||y<=0) {
    		e.target.removeEventListener(Event.ENTER_FRAME, moveIt);
    		_stage.stage.removeChild(e.target);
    		}
    	}
    }
    private function addListeners(e:Event):void {
    	_stage.stage.addEventListener(MouseEvent.MOUSE_MOVE, moveArm);
    	_stage.stage.addEventListener(MouseEvent.CLICK, shootMe);
    }
    Any more help?
    Attached Files Attached Files
    Code:
    sup.

  4. #4
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    uh... just from reading the code, it looks like you're using the bullet's rotation to determine the slope of its trajectory. Actually, the math you have there:
    x+= 10*Math.sin(rotation*(Math.PI/180));
    should work perfectly if instead of bullet.rotation you were talking about roboarm.rotation, and the bullet's rotation was 0. But since the bullet is already rotated to the arm's rotation, you shouldn't need to adjust its x and y according to the sin and cos of the angle...you should only need to move it along its x-axis, which has already been properly rotated.

    I didn't have time to actually test it so I don't know for sure, that's just what it looks like to me...

    Josh

  5. #5
    Junior Member
    Join Date
    May 2008
    Posts
    18
    Hey Josh, thanks for your valuable time and helping me fix the first thing.
    Ok i tried various methods including:
    ...
    bullet.rotation=0;
    bullet.Angle=robarm.rotation;
    ...
    x+=10*Math.sin(e.target.Angle*(Math.PI/180));
    y-=10*Math.cos(e.target.Angle*(Math.PI/180));
    ...
    (This moves erratically again)
    AND
    ...
    bullet.rotation=robarm.rotation;
    ...
    x+=10;
    (as you said to just move it along x axis as rotation is already set)
    (This moves along a straight line)

    Any more suggestions?
    Code:
    sup.

  6. #6
    Junior Member
    Join Date
    May 2008
    Posts
    18
    Ok got it to work. I realised i was 90 degrees short of all the "fires" so i decided to add 90degrees to the shot made.
    Works fine now ..

    ....
    bullet.rotation=0;
    bullet.Angle=robarm.rotation+90;

    ....

    x+=10*Math.sin(e.target.Angle*(Math.PI/180));
    y-=10*Math.cos(e.target.Angle*(Math.PI/180));

    ...
    Thanks ALOT JOSH...
    Code:
    sup.

  7. #7
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    Hey cool! Glad I could help.

    Listen; just a tip...it's not the best practice to always be sending main timeline / stage references down your class chains. It's a hard habit to kick and I still fall into it sometimes -- especially if I need "super" objects like dialog boxes or dropdown menus that have to appear at random times on top of everything else in the movie. But usually it's better to create holder sprites for groups of related classes and add them just once to the stage. It makes it a lot easier to clean up, there's less risk of regenerating things and losing references (for example, if your script calls shootMe more than once, bullet will be re-referenced to a new bomb1, and you'll lose the old reference, making it much harder to remove from the stage)... and this can lead to memory build-up, especially in games, and make things run slower and slower as the game progresses. If you make a sprite called robotholder, in the robot class, and make robot, bullet and robarm children of it, you can add them all from the document class and never need to call the stage from this class at all.

    When you need to actually access the stage because something needs to be done that overrides all other graphics (like a dialog box), it's good to create a singleton class that holds a main timeline reference as a static var so you can always have access to it from any class without having to pass it. Grant Skinner has a good example of how to do that here:
    http://www.gskinner.com/blog/archive...ingletons.html
    That makes it a lot easier to call the stage from any class and you don't have to worry about passing the reference down through several different layers.

    Cheers,
    Josh

  8. #8
    Junior Member
    Join Date
    May 2008
    Posts
    18
    Ok I vaguely understand what you mean by the "accessing stage class" but actually i only want to access the stage class to get some hard values like stage width/height, rotation and some other values which i dont think can be available elsewhere. Other than that i try to leave all refrencing and other things within the class.

    I would really appreciate it if when you have the time, you could just look at that sample code i sent above, (just add the +90) and it will fire properly. what i do is i add the shot, removeChild after it gets off the stage so that i dont keep unwanted stuff.
    If I am really doing something wrong, it would be cool if you could send me a "better practice" way so i can learn from there..cos i really cant understand what you mean.
    If you ARE going to look at the code, can you just drop me a reply so i can expect an email from you.
    my email is yankeedoodles@hotmail.com

    BTW. nice site i like the typewriter...heh
    Code:
    sup.

  9. #9
    Senior Member joshstrike's Avatar
    Join Date
    Jan 2001
    Location
    Alhama de Granada, España
    Posts
    1,131
    Heyy. I just took a look.
    Sorry for the jargonese, I'm just saying this...
    Your class robot extends Sprite. So, it's a sprite that can be added to the stage. Right now, robot gets created as robo, and basically does a bunch of things that place other sprites like bullet and robarm on the stage. Then you add robo itself to the stage from the document class; but there is no reason to add robo to the stage because it itself has no graphics. It's just created a bunch of graphics and then added them to the stage. This is like what classes usually did in AS2, where everything got added to root.

    So look at the constructor function for robot...
    Code:
    private var robbody:body=new body();
    		private var robarm:arm = new arm();
    		private var bulletnum:Number;
    		private var _stage:Stage;
    
    		public function robot(stageRef:Stage):void {
    			_stage = stageRef;
    			robbody.x = robarm.x = 225;
    			robbody.y = robarm.y = 250;
    			_stage.addChild(robbody);
    			_stage.addChild(robarm);
    			_stage.addEventListener(Event.ADDED_TO_STAGE, addListeners);
    		}
    You could improve this a couple of ways:

    Code:
    public var robbody:body=new body();
    		public var robarm:arm = new arm();
                    //let's make these public, so anybody can call robo.robarm or robo.robbody and get information about it. 
    		private var bulletnum:Number;
    
    		public function robot():void {
    //no need to pass a stage reference. 
    			robbody.x = robarm.x = 225;
    			robbody.y = robarm.y = 250;
    			this.addChild(robbody);
    			this.addChild(robarm);
    			this.addEventListener(Event.ADDED_TO_STAGE, addListeners);
    //this is good because we know no other functions will be called until the 
    //robo itself is actually added to the stage. 
    //At that point, you can just use this.stage instead of having to have a ref. 
    //passed in from above.
    		}
    Now that you've added robbbody and robarm to your robo itself, and added robo to the stage, you can position both of them simultaneously as a group by changing robo.x or robo.y from the main timeline...or you can make the parts move separately via robo.robarm, etc. ...the whole advantage to a class extending Sprite or MovieClip is that it can add children to itself, and it itself can be added to the stage and moved around as a group...

    Hope this makes sense...gotta get offline now, but good luck with this and let me know how it's goin!

  10. #10
    Junior Member
    Join Date
    May 2008
    Posts
    18
    Hey josh,
    Thanks alot for that explanation. I think I pretty much understand what you are trying to say.
    What i did was i removed that addChild(robo) and i realised that the robot was still adding to the stage but the addEventListener(Event.ADDED_TO_STAGE) wouldnt work cos it wasnt really added..internally other stuffs were added.

    SO, now im gonna try and do things the "clean way" and repost after im done..probably tomorrow cos even i have to go offline now

    THANKS A TON

    Murtaza
    Code:
    sup.

Posting Permissions

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




Click Here to Expand Forum to Full Width

HTML5 Development Center