A Flash Developer Resource Site

Results 1 to 4 of 4

Thread: target Sprite from subclass

  1. #1
    Member
    Join Date
    Apr 2001
    Location
    Cape Town
    Posts
    99

    target Sprite from subclass

    Hi I am fairly new to custom classes. I create a Sprite in a subclass, add it to the stage. Now I need to target it from another class, but I am going wrong somewhere. This is shorten code, so hope I did not delete some important parts. But you should be able to follow the basic structure.


    Main class:

    package myClasses
    {
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.MovieClip;
    import myClasses.stagePlacement;

    public class Main extends MovieClip
    {

    public var startbtn:Sprite = new Sprite();
    static public var stageRef:Stage;
    public function Main()
    {
    stageRef = stage;
    addChild(startbtn);
    startbtn.graphics.beginFill(0x000000);
    startbtn.graphics.drawRoundRect(0,0,60,20,5,5);
    startbtn.x = 450;
    startbtn.y = 50;
    startbtn.graphics.endFill();
    startbtn.buttonMode = true;
    startbtn.addEventListener(MouseEvent.CLICK,GameSta rt);


    }
    public function GameStart(e:MouseEvent)
    {
    var myGame= new stagePlacement();

    }


    }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////

    stagePlacement class

    package myClasses
    {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.events.Event;
    import myClasses.paddleMove;

    public class stagePlacement
    {
    public var PlayerPaddle:Sprite = new Sprite();
    public var Game= new paddleMove();

    public function stagePlacement()
    {

    Main.stageRef.addChild(PlayerPaddle);
    PlayerPaddle.graphics.beginFill(0x000000);
    PlayerPaddle.graphics.drawRect(0,0,10,70);
    PlayerPaddle.x = 10;
    PlayerPaddle.y = 10;
    PlayerPaddle.graphics.endFill();
    PlayerPaddle.name="mypaddle"

    }
    }
    }

    ////////////////////////////////////////////////////////////////////////////////////////////

    paddleMove class

    package myClasses
    {
    import flash.events.Event;

    public class paddleMove
    {

    public function paddleMove()
    {
    Main.stageRef.addEventListener(Event.ENTER_FRAME,c ontolMovement);

    }
    function contolMovement(e:Event):void

    {
    Main.stageRef.PlayerPaddle.alpha=10
    //This is the line of code that cannot find the target.

    }
    }
    }

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Please format code with [code] tags.

    There's a lot of anti-patterns here. I would really like to discuss those and steer you in the right direction, but I'll answer the asked question first.

    The reason it doesn't work is that the stage has no property named PlayerPaddle. There is no way to give the stage such a property, since the stage is not a dynamic class. You have probably made the mistake of thinking that the stage is the root. It's not.

    Now, although you did not give your paddleMove instance any reference to the PlayerPaddle instance, you could technically use getChildByName to get it from the stage. But don't do that. It's like fixing a pothole in a collapsing bridge by filling it with silly putty. It may work once or twice, but that's not a good fix, and it's not the right problem.

    You should not add things directly to the stage. When you think you want to do this, what you probably want instead is to add them to the root. And when you think you want to do that, it's probably because you have not made a properly encapsulated design. stageRef is an anti-pattern. If you find yourself using it, think really hard about your assumptions that lead you there.

    What you really want to do is design a set of classes such that each only needs to know about the ones it directly interacts with. And it should only directly interact with the ones it needs to. Why would something called paddleMove need to change the alpha value of another instance. Why would you have something called paddleMove in the first place?

    Let me start over.

    You want to make some sort of game with a moving paddle. Okay, that gives us two good candidates for classes: Game and Paddle. Notice that both are nouns. They are things, not processes or behaviors.
    Game will be your document class. It'll be the root. Game will be responsible for the game logic and setting itself up. If you'd like, you could create another class to be responsible for the game controls or UI. I'd call that GameControls or UI. Paddle will be the paddle. It doesn't do much except show up and react to input.

  3. #3
    Member
    Join Date
    Apr 2001
    Location
    Cape Town
    Posts
    99
    Thanks for reply. But i still do not get this class thing. In my base class I call a menu, when I click on button I must display something. So I create a container in my baseClass. Add my menuclass to the baseClass_Container and add the baseClass_Container to the stage. But when I click on the button created in the menu I cannot get the object to display.

    I get the following error:
    TypeError: Error #2007: Parameter child must be non-null.
    at flash.display:isplayObjectContainer/addChild()
    at myClasses::menu/GameStart()

    Actionscript Code:
    package myClasses{

        import flash.display.MovieClip;
        import flash.display.Sprite;

        import myClasses.menu;

        public class game extends MovieClip {
            public var BaseContainer=new Sprite();
            public var myMenu=new menu();
            public function game() {
                BaseContainer.addChild(myMenu);
                addChild(BaseContainer);
            }
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////

    package myClasses
    {
        import flash.display.Sprite;
        import flash.display.Stage;
        import flash.events.MouseEvent;
        import flash.events.Event;
        import flash.text.TextField;
        import flash.display.MovieClip;
        import myClasses.paddle;
        import flash.display.DisplayObject;

        public class menu extends MovieClip
        {

            public var startbtn:Sprite = new Sprite();
            public var helpbtn:Sprite = new Sprite();
            public var menuContainer:Sprite=new Sprite();
            public var startbtnname:TextField = new TextField();
            public var helpbtnname:TextField = new TextField();
           

            public function menu()
            {
                addChild(startbtn);
                startbtn.graphics.beginFill(0x000000);
                startbtn.graphics.drawRoundRect(0,0,60,20,5,5);
                startbtn.x = 450;
                startbtn.y = 50;
                startbtn.graphics.endFill();
                startbtn.buttonMode = true;
                startbtn.addEventListener(MouseEvent.CLICK,GameStart);

                                       
                addChild(startbtnname);
                startbtnname.text = "Start Game";
                startbtnname.x = 450;
                startbtnname.y = 50;
                startbtnname.textColor = 0xffffff;
                startbtnname.mouseEnabled = false;

               
            }
            public function GameStart(e:MouseEvent)
            {
                var Mypaddles = new paddle(5,160);
                addChild(Mypaddles as DisplayObject)
               
                removebtns();

            }
                   

            function removebtns():void
            {
                removeChild(startbtn);
                removeChild(startbtnname);
            }
           
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////

    package myClasses{
        import flash.display.Sprite;

        public class paddle {
            public var Paddle:Sprite = new Sprite();
    public var paddleContainer:Sprite = new Sprite();
            public function paddle(xpos:uint,ypos:uint) {
                Paddle.graphics.beginFill(0x000000);
                Paddle.graphics.drawRect(0,0,10,70);
                Paddle.graphics.endFill();
                Paddle.x=xpos;
                Paddle.y=ypos;
                paddleContainer.addChild(Paddle)
            }
        }
    }
    Last edited by eye4see; 01-13-2012 at 04:36 AM.

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    The immediate cause of that error is that Mypaddles is not a DisplayObject, and you cannot magically turn it into one by using "as DisplayObject". The "as" operator attempts to do a cast, and if that cast fails, it returns null instead of throwing an exception. That's why I recommend to always use the explicit cast syntax instead. That would have been something like:
    Code:
    addChild(DisplayObject(Mypaddles));
    Of course, that won't work either, but it will at least fail with a meaningful error message.

    Since the paddle class does not explicitly extend any other class, it implicitly extends Object. If you need instances of paddle to go on the display, then they should extend some sort of DisplayObject. I recommend Sprite. Then, you would not have to cast Mypaddles in the first place, because the compiler would know that it is of an appropriate type.

    Now, assuming you get that straightened out, you will have a paddle on the display. Congrats. You will not see it though, since it doesn't have anything in it. You forgot to add paddleContainer to the paddle. BUT, since the only reason you had paddleContainer in the first place was because paddle itself wasn't a DisplayObjectContainer, you can now remove paddleContainer and have paddle add Paddle to itself. Or even better, remove Paddle also, and have paddle simply draw in its own graphics.

    There, now you'll see a paddle. But it won't do anything. The problem is that the only thing that knew about the paddle you created was the GameStart function. Mypaddles is a local variable in there, so after the function completes, the only reference to the paddle is the fact that its on the display. Since I presume you'll want to interact with the paddle at some point, you should think about keeping a reference somewhere.

    But that somewhere should not be menu. In fact, menu should not create and place the paddle at all. menu should simply be a menu. It should be responsible for displaying some choices, reporting selections, and cleaning itself up.

    So instead of doing the paddle stuff in GameStart, have menu just dispatch an event that game is listening for which indicates a game is beginning. game will then act on that message however is appropriate (by starting a game), including creating, placing, and keeping track of a paddle.

    I would once again like to remind you of common naming convention. Classes begin with UpperCase. variables and functions begin with lowercase. So you'd have Game, Menu, and Paddle classes. And baseContainer, gameStart, myPaddles, and paddle variables. Well, some of those you'd lose entirely, but I mean if you were to put your current code in common convention.

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