Ellis
Ellis

Reputation: 3088

Changing class properties in AS3

Okay, so I've recently been trying to get my head properly around OOP in AS3. Right now I have a really simple scenario where I've got a class, Paddle, which draws a rectangle. In my document class I create two instances of the Paddle class, paddle1 and paddle2.

I've also created a property for my Paddle class which I want to change the colour of the rectangle that it draws. I want to be able to adjust this property from the main class. I know I could do this by passing in attributes when instantiating the class but it seems like a property would be a better way, and now I want to know if this is the right way of thinking or not.

main class:

    package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Engine extends Sprite 
    {
        private var paddle1:Paddle = new Paddle();
        private var paddle2:Paddle = new Paddle();

        public function Engine() 
        {
            paddle1.x = 30;
            paddle1.color = 0xFF00FF;
            stage.addChild(paddle1);

            paddle2.x = stage.stageWidth - 45;
            paddle2.color = 0xFF0000;
            stage.addChild(paddle2);
        }

    }

}

Paddle class:

package
{
    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.display.Graphics;
    import flash.events.Event;

    public class Paddle extends MovieClip
    {
        public var color:uint = 0xFFFFFF;

        public function Paddle() 
        {
            var child:Shape = new Shape();
            child.graphics.beginFill(color);
            child.graphics.drawRect(0, 260, 15, 80);
            child.graphics.endFill();
            addChild(child);
        }

    }

}

If changing the properties in this way is not the best way of doing things then of course say so. Otherwise, what am I doing wrong that it doesn't work? Seems like it's something to do with the order (by the time the main class changes the colour attribute, it's already created the rectangle and it's too late to change it?)

Thanks :D

EDIT: realised it might help to say what happens when I execute this code. Basically changing the color attribute from the Engine class doesn't change the colour of the rectangle and they both just stay white (FFFFFF)

Upvotes: 1

Views: 638

Answers (3)

Chunky Chunk
Chunky Chunk

Reputation: 17217

What you might do is to allow the constructor to assign a color in addition to creating a setter for the color, having both calls subsequently drawing the paddle (which, by the way, could also be a simple flash.display.Shape):

Paddle.as:

package
{
    //Imports
    import flash.display.Sprite;

    //Class
    public class Paddle extends Sprite
    {
        //Constants
        private static const DEFAULT_COLOR:uint = 0xFF0000;

        //Properties
        private var mColor:uint;

        //Constructor
        public function Paddle(color:uint = DEFAULT_COLOR) 
        {
            mColor = color;

            draw();
        }

        //Draw
        private function draw():void
        {
            graphics.clear();
            graphics.beginFill(mColor);
            graphics.drawRect(0, 0, 15, 80);
            graphics.endFill();
        }

        //Set Color
        public function set color(value:uint):void
        {
            mColor = value;

            draw();
        }

        //Get Color
        public function get color():uint
        {
            return mColor;
        }
    }
}

so now you can create and position as many Paddle instances as you want, each having their own color setter:

Red Instance:

var paddleRed:Paddle = new Paddle();
paddleRed.y = 10;
addChild(paddleRed);

Green Instance:

var paddleGreen:Paddle = new Paddle(0x00FF00);
paddleGreen.y = 126;
addChild(paddleGreen);

Blue Instance:

var paddleBlue:Paddle = new Paddle();
paddleBlue.color = 0x00FF00;
paddleBlue.y = 260;
addChild(paddleBlue);

Upvotes: 1

Foggzie
Foggzie

Reputation: 9821

Why not do both? :D

public class Paddle extends MovieClip
{
    private var color:uint;
    private var rec:Shape;

    public function Paddle(newColor:uint = 0xFFFFFF) // default color
    {
        color = newColor;
        rec = new Shape();
        drawShape();
        addChild(rec);
    }

    public function drawShape()
    {
        child.graphics.clear();
        child.graphics.beginFill(color);
        child.graphics.drawRect(0, 260, 15, 80);
        child.graphics.endFill();
    }

    public function setColor(newColor:uint)
    { 
        color = newColor;
        drawShape();
    }
}

Upvotes: 0

Marty
Marty

Reputation: 39456

The issue you're having is that when you do:

new Paddle();

Your constructor code is run. What this means is that the Rectangle has already been drawn with the color defined at the top of the class. You're then changing the color property after this, which as you can see has no effect.

I suggest you make a draw() function for your Paddle. It could accept a color and be used to draw the Rectangle. It might look like this:

public class Paddle extends MovieClip
{

    private var _child:Shape;


    public function Paddle() 
    {
        _child = new Shape();
        addChild(_child);
    }


    public function draw(color:uint):void
    {
        _child.graphics.clear();
        _child.graphics.beginFill(color);
        _child.graphics.drawRect(0, 260, 15, 80);
        _child.graphics.endFill();
    }

}

This way provides an advantage which is that you can modify the arguments of draw() to accept dimensions for your Rectangle or other elements that will affect the visuals. This will be cleaner and faster than having to add more properties to the class itself if you decide you want to do this.

You're then able to do this:

var paddle1:Paddle = new Paddle();
var paddle2:Paddle = new Paddle();

paddle1.draw(0xFF00FF);
paddle2.draw(0xFF0000);

Upvotes: 1

Related Questions