Question

I'm trying to create a grid where the users can 'draw' across it and change the colors of the grid squares to a chosen color.

In this code, I'm creating the grid with squares. I've got the functionality 'working', but it's only working on the last square instanced.

How do I get it to work on all the squares, not just the last one?

Thank you for any help you can give me.

JD-

package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;


public class ClassBoxColor extends MovieClip {
    public var boxColor = "0xFFFFFF";
    public var lineColor = "0x666666";

    public function ClassBoxColor() {

        // ****Create the Grid****
        var xpos:Number;
        var xposStart:Number = 20;  // Initial Placement of grid along x axis
        var ypos:Number = 100;      // Initial Placement of grid along y axis
        var xNum:Number = 10;       // Size of Grid across in squares
        var yNum:Number = 10;       // Size of Grid across in squares

        for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
            xpos = xposStart;
            for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
                // Draw the square
                var colorBox:Sprite = new Sprite();
                colorBox.graphics.beginFill(boxColor, 1 );
                colorBox.graphics.lineStyle(1, lineColor);
                colorBox.graphics.drawRect(0,0,20,20);
                colorBox.x = xpos;
                colorBox.y = ypos;
                colorBox.buttonMode = true;
                addChild(colorBox);
                xpos += 20;
            }
            ypos += 20;
        }

        // LISTENERS

        Grey_btn.addEventListener(MouseEvent.CLICK, setGrey);           // This button instance is onstage
        DarkGrey_btn.addEventListener(MouseEvent.CLICK, setDarkGrey);   // This button instance is onstage

        stage.addEventListener(MouseEvent.MOUSE_DOWN, drawColor);
        stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawColor);
        colorBox.addEventListener(MouseEvent.CLICK, changeColor);

        // FUNCTIONS & ACTIONS

        Grey_btn.buttonMode = true;
        DarkGrey_btn.buttonMode = true;

        CurrentBoxColor_txt.text = boxColor;// Display the currently selected color in the CurrentBoxColor_txt instance textfield that is onstage

        function setGrey(event:MouseEvent):void {
            boxColor = "0xCCCCCC";
            CurrentBoxColor_txt.text = boxColor;
        }
        function setDarkGrey(event:MouseEvent):void {
            boxColor = "0x666666";
            CurrentBoxColor_txt.text = boxColor;
        }
        function changeColor(event:MouseEvent):void {
            colorBox.graphics.clear();
            colorBox.graphics.lineStyle(1, lineColor);
            colorBox.graphics.beginFill(boxColor, 1);
            colorBox.graphics.drawRect(0,0,20,20);
            colorBox.graphics.endFill();
        }
        function drawColor(event:MouseEvent):void {
            //colorBox.addEventListener(MouseEvent.MOUSE_DOWN, changeColor);
            colorBox.addEventListener(MouseEvent.ROLL_OVER, changeColor);
        }
        function stopDrawColor(event:MouseEvent):void {
            //colorBox.removeEventListener(MouseEvent.MOUSE_DOWN, changeColor);
            colorBox.removeEventListener(MouseEvent.ROLL_OVER, changeColor);
        }
    }
}

}

Was it helpful?

Solution

You really need a rework on this entire class. You have all of your code and methods defined directly in the constructor, some instance names not defined, etc. I'm interested in how you got this to compile. As a sidenote, don't put Class in the name of your AS class.

What you need to have is a ColorBox class that handles very simple stuff like rollover, etc to manage color by itself. Leave the creation/placement of the box outside of the single ColorBox class.

Here is a rework of the same class working fine in Flash Player 10. I separated things into two classes. Some of the names/style you started with are still in play. I didn't rewrite every single line.

ColorBox is a box. That's it. It does nothing but manage color.

ColorBoxRoot is the document root class. Set your FLA to this class and let'er rip. Open a new fla to test. I stripped the button code as well as the textfield code but added in a trace where the textfield used to be.

Hope this helps!

//ColorBox.as

package { import flash.display.MovieClip; import flash.display.Sprite; import flash.events.*;

[Event(name="colorChange")]
public class ColorBox extends MovieClip{
//  CONSTANTS
    public static const COLOR_CHANGE:String = "colorChange";
    public static const DEFAULT_WIDTH:uint = 20;
    public static const DEFAULT_HEIGHT:uint = 20;

//  PROPERTIES
    private var _boxColor:uint = 0xFFFFFF;
    public function get boxColor():uint{ return _boxColor; }

    private var _lineColor:uint = 0x666666;

//  CONSTRUCTOR
    public function ColorBox(){
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

//  EVENT LISTENERS
    private function onAddedToStage(event:Event):void{
        stage.addEventListener(MouseEvent.MOUSE_DOWN, setGrey);
        stage.addEventListener(MouseEvent.MOUSE_UP, resetColors);

        updateDisplay();

        addEventListener(MouseEvent.ROLL_OVER, setGrey);
        addEventListener(MouseEvent.ROLL_OUT, setDarkGrey);
    }

//  PRIVATE METHODS
    private function resetColors(event:Event=null):void{
        _boxColor = 0xFFFFFF;
        updateDisplay();
    }

    private function setGrey(event:MouseEvent):void {
        _boxColor = 0xCCCCCC;
        updateDisplay();
        dispatchEvent(new Event(COLOR_CHANGE));
    }
    private function setDarkGrey(event:MouseEvent):void {
        _boxColor = 0x666666;
        updateDisplay();
        dispatchEvent(new Event(COLOR_CHANGE));
    }

    private function updateDisplay():void {
        graphics.clear();
        graphics.lineStyle(1, _lineColor);
        graphics.beginFill(_boxColor, 1);
        graphics.drawRect(0,0,20,20);
        graphics.endFill();
    }
}

}

//ColorBoxRoot.as

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

/**
 * Document root class; Create a new FLA (empty) and set this class as the document root
 */
public class ColorBoxRoot extends MovieClip{
//  STAGE OBJECTS
    //public var Grey_btn:DisplayObject;
    //public var DarkGrey_btn:DisplayObject;

//  CONSTRUCTOR
    public function ColorBoxRoot(){
        addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
    }

//  EVENT LISTENERS
    /**
     * Called once the swf stage is ready
     */
    private function onAddedToStage(event:Event):void{
        initializeUI();
        createGrid();
    }

//  PRIVATE METHODS
    /**
     * Always try to initialize your UI in a method so you can recall it later to "reset" things, if needed
     */
    private function initializeUI():void{
        //Grey_btn.buttonMode = true;
        //DarkGrey_btn.buttonMode = true;
    }

    /**
     * Creates the ColorBox grid
     */
    private function createGrid():void{
        var xpos:Number;
        var xposStart:Number = 20;      // Initial Placement of grid along x axis
        var ypos:Number = 100;          // Initial Placement of grid along y axis
        var xNum:Number = 10;           // Size of Grid across in squares
        var yNum:Number = 10;           // Size of Grid across in squares
        var colorBox:ColorBox;

        for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
                xpos = xposStart;
                for (var xaxis:Number = 1; xaxis <= xNum; xaxis++){
                        // Draw the square
                        colorBox = new ColorBox();
                        colorBox.addEventListener(ColorBox.COLOR_CHANGE, onBoxColorChange);
                        colorBox.name = "box" + xaxis + "_" + yaxis; //jcbii: give it an identifiable name; just for fun
                        colorBox.x = xpos;
                        colorBox.y = ypos;
                        addChild(colorBox);
                        xpos += ColorBox.DEFAULT_HEIGHT; //jcbii: never hardcode these values; use dynamic values as much as possible
                }
                ypos += ColorBox.DEFAULT_WIDTH; //jcbii: never hardcode these values; use dynamic values as much as possible
        }
    }

    private function onBoxColorChange(event:Event):void{
        trace(event.target.name, ColorBox(event.target).boxColor);
    }
}

}

OTHER TIPS

Can't say I've ever used AS but.. shouldn't you add the listener inside the for? You're overwriting colorBox with every iteration so at the end only the last one will be referenced by it (this is where i would rant that it even compiles, since colorBox seems accesible out of scope; the C programmer in me is crying).

Im pretty new with AS3, but looks like you problem is when you initialize your squares. And calling changeColor() on colorBox. You only have one colorbox which you play around with, not 10 as you want to have(?). Below isn't the best solution for it, but its closest to a solution for your current code base.

Make an Array called colorboxArray and add your colorboxes to it.

var colorBoxArray:Array = new Array();
 for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
         xpos = xposStart;
         for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
         // Draw the square
          var colorBox:Sprite = new Sprite();
          colorBoxArray[yaxis] = colorBox;
          ..
          colorBoxArray[yaxis].addEventListener(MouseEvent.CLICK, changeColor);
          ..
 }

And call changeColor on the colorBoxArray[IdOfTheBoxYouWantToChangeColorOn]

A better way of doing this would be to move out all your above functions to a class called "Box", and create instances of your Box class in your above creation loop, add listeners to all your boxes and your set. I like arrays though ;(

not tested but should be working ... use MouseEvent::buttonDown, to look, whether button is down ...

package {
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.text.TextField;


    public class ClassBoxColor extends MovieClip {
        public var boxColor = "0xFFFFFF";
        public var lineColor = "0x666666";

        public function ClassBoxColor() {

            // ****Create the Grid****
            var xpos:Number;
            var xposStart:Number = 20;      // Initial Placement of grid along x axis
            var ypos:Number = 100;          // Initial Placement of grid along y axis
            var xNum:Number = 10;           // Size of Grid across in squares
            var yNum:Number = 10;           // Size of Grid across in squares

            for (var yaxis:Number = 1; yaxis <= yNum; yaxis++) {
                xpos = xposStart;
                for (var xaxis:Number = 1; xaxis <= xNum; xaxis++) {
                    // Draw the square
                    var colorBox:Sprite = new Sprite();
                    colorBox.graphics.beginFill(boxColor, 1 );
                    colorBox.graphics.lineStyle(1, lineColor);
                    colorBox.graphics.drawRect(0,0,20,20);
                    colorBox.x = xpos;
                    colorBox.y = ypos;
                    colorBox.buttonMode = true;
                    addChild(colorBox);
                    colorBox.addEventListener(MouseEvent.CLICK, changeColor);
                    colorBox.addEventListener(MouseEvent.ROLL_OVER, changeColor);
                    xpos += 20;
                }
                ypos += 20;
            }

            // LISTENERS

            Grey_btn.addEventListener(MouseEvent.CLICK, setGrey);                   // This button instance is onstage
            DarkGrey_btn.addEventListener(MouseEvent.CLICK, setDarkGrey);   // This button instance is onstage

            // FUNCTIONS & ACTIONS

            Grey_btn.buttonMode = true;
            DarkGrey_btn.buttonMode = true;

            CurrentBoxColor_txt.text = boxColor;// Display the currently selected color in the CurrentBoxColor_txt instance textfield that is onstage

            function setGrey(event:MouseEvent):void {
                boxColor = "0xCCCCCC";
                CurrentBoxColor_txt.text = boxColor;
            }
            function setDarkGrey(event:MouseEvent):void {
                boxColor = "0x666666";
                CurrentBoxColor_txt.text = boxColor;
            }
            function changeColor(event:MouseEvent):void {
                if ((event.type == MouseEvent.CLICK) || (event.buttonDown)) {
                    colorBox.graphics.clear();
                    colorBox.graphics.lineStyle(1, lineColor);
                    colorBox.graphics.beginFill(boxColor, 1);
                    colorBox.graphics.drawRect(0,0,20,20);
                    colorBox.graphics.endFill();
                }
            }
        }
    }
}

generally, i think you approach is not very clean ... your class has dependancies on some Grey_btn and DarkGrey_btn and other external things ... this is bad style ... really ... also there are a few things i don't understand perfectly, but ok ... that's maybe my fault ... :)

good luck anyway ... ;)

greetz

back2dos

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top