views:

2595

answers:

4

Hello, 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);
  }
 }
}

}

+2  A: 

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).

Blindy
Reading your code, I don't know why you want to set/remove event listeners inside the stage mouse up/down event, but you can't do it like this. You can either store an array of `colorBoxes` with every color box made and iterate them to add/remove the listener, or set a global variable that signifies disabling the listener and check against it in `changeColor` before doing anything.
Blindy
to the crying c programmer ... ;-P ....ECMA standard 4 (which was basically crushed by microsoft, but served as a basis for AS3) specifies, that local variables are scoped to functions and not to blocks ... the "let" keyword was planned to have block scoped variables ...
back2dos
A: 

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 ;(

Daniel T. Magnusson
A: 

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 ... ;)

back2dos
+1  A: 

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);
 }
}

}

johncblandii
Thank you so much! I'm going to be going through this line by line today to make sure I understand it fully.JD-
JD-
Sweet. Accept answer and shoot me an up vote if it works out for you. ;-) Ping me if you need help understanding what's what.
johncblandii
How did it go JD?
johncblandii