Skip to main content
Known Participant
April 19, 2011
Answered

What is the best way of dealing with an "implicit coercion" of an array to a sprite?

  • April 19, 2011
  • 2 replies
  • 1173 views

Hello everyone!

     With continued help from this forum I am getting closer to having a working program. I look forward to being able to help others like myself once I finish learning the AS3 ropes.

     I will briefly explain what I am trying to achieve and then follow it up with my question.

Background

     I have created a 12 x 9 random number grid that populates each cell with a corresponding image based on each cell's numeric value. I have also created a shuffle button that randomizes the numbers in the grid. The problem I am running into is getting my button-click event to clear the current images off the grid in order to assign new ones (i.e. deleting the display stack objects in order to place news ones in the same locations).

Question

     My question is this: what is the best way to handle an implicit coercion from an array to a sprite? I have pasted my entire code below so that you can see how the functions are supposed to work together. My trouble apparently lies with not being able to use an array value with a sprite (the sprite represents the actual arrangement of the grid on the display stack while the array starts out as a number than gets assigned an image which should be passed to the sprite).

============================================================================

package 
{
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.getDefinitionByName;

public class Blanko extends MovieClip
{
      // Holds 12*9 grid of cells.
      var grid:Sprite;
      // Holds the shuffle button.
      var shuffleButton:Sprite;
      // Equals 12 columns, 9 rows.
      var cols:int = 12;
      var rows:int = 9;
      // Equals number of cells in grid (108).
      var cells:int = cols * rows;
      // Sets cell width and height to 40 pixels.
      var cellW:int = 40;
      var cellH:int = 40;
      // Holds 108 cell images.
      var imageArray:Array = [];
      // Holds 108 numerical values for the cells in the grid.
      var cellNumbers:Array = [];
 
      // Constructor calls "generateGrid" and "makeShuffleButton" functions.
      public function Blanko()
      {
           generateGrid();
           makeShuffleButton();
      }
 
  // Creates and displays the 12*9 grid.
  private function generateGrid():void
  {
       grid = new Sprite;
       var i:int = 0;


       for (i = 0; i < cells; i++)
       {
            cellNumbers.push(i % 9 + 1);
       }
       trace("Before shuffle: ", cellNumbers);
       shuffleCells(cellNumbers);
       trace("After shuffle: ", cellNumbers);
       var _cell:Sprite;
    

       for (i = 0; i < cells; i++)
       {

            // This next line is where the implicit coercion occurs. "_cell" is a sprite that tries

               to temporarily equal an array value.
            _cell = drawCells(cellNumbers);
            _cell.x = (i % cols) * cellW;
            _cell.y = (i / cols) * cellH;
            grid.addChild(_cell);
       }
  }
 
  // Creates a "shuffle" button and adds an on-click mouse event.
  private function makeShuffleButton():void
  {
       var _label:TextField = new TextField();
       _label.autoSize = "center";
       TextField(_label).multiline = TextField(_label).wordWrap = false;
       TextField(_label).defaultTextFormat = new TextFormat("Arial", 11, 0xFFFFFF, "bold");
       _label.text = "SHUFFLE";
       _label.x = 4;
       _label.y = 2;
       shuffleButton = new Sprite();
       shuffleButton.graphics.beginFill(0x484848);
       shuffleButton.graphics.drawRoundRect(0, 0, _label.width + _label.x * 2, _label.height +
                                            _label.y * 2, 10);
       shuffleButton.addChild(_label);
       shuffleButton.buttonMode = shuffleButton.useHandCursor = true;
       shuffleButton.mouseChildren = false;
       shuffleButton.x = grid.x + 30 + grid.width - shuffleButton.width;
       shuffleButton.y = grid.y + grid.height + 10;
       this.addChild(shuffleButton);
       shuffleButton.addEventListener(MouseEvent.CLICK, onShuffleButtonClick);
  }
 
  // Clears cell images, shuffles their numbers and then assigns them new images.
  private function onShuffleButtonClick():void
  {
   eraseCells();
   shuffleCells(cellNumbers);
   trace("After shuffle: ", cellNumbers);


   for (var i:int = 0; i < cells; i++)
   {
    drawCells(cellNumbers);
   }
  }
 
  // Removes any existing cell images from the display stack.
  private function eraseCells(): void
  {
   while (imageArray.numChildren > 0)
   {
    imageArray.removeChildAt(0);
   }
  }
 
  // Shuffles cell numbers (randomizes array).
  private function shuffleCells(_array:Array):void
  {
   var _number:int = 0;
   var _a:int = 0;
   var _b:int = 0;
   var _rand:int = 0;
  
   for (var i:int = _array.length - 1; i > 0; i--)
   {
    _rand = Math.random() * (i - 1);
    _a = _array;
    _b = _array[_rand];
    _array = _b;
    _array[_rand] = _a;
   }
  } 
 
  // Retrieves and assigns a custom image to a cell based on its numerical value.
  private function drawCells(_numeral:int):Array
  {
   var _classRef:Class = Class(getDefinitionByName("skin" + _numeral));
   _classRef.x = 30;
   imageArray.push(_classRef);
   imageArray.addChild(_classRef);
   return imageArray;
  }
}
}
===========================================================================

     Any help with this is greatly appreciated. Thanks!

This topic has been closed for replies.
Correct answer Rothrock

If you want to have an array of Sprites that later you clear that is fine. But it doesn't mean that your function should return it.

You need your function to return the sprite so that you can add it to the display list and whatever else you need.

So just have the function get the Sprite, push it into the "toBeClearedInTheFutureArray," and then return a reference to the currently gotten sprite.

2 replies

Participating Frequently
April 19, 2011

I would like to help you but am uncertain what you want to do..  It's too late to read that many lines of code .

Explain just the cell and the loop aspect

Known Participant
April 19, 2011

FeZEC,

     In a nutshell:

  1. first, my loop is supposed to randomize a 12 x 9 grid consisting of the numbers 1 through 9 (using them 12 times each throughout the grid);
  2. second, the loop assigns an image (that I can later program with mouse events) to each cell based on the number that was randomly assigned to it;
  3. third, a separate loop within my "shuffle" button click event deletes the current images in the grid and runs through steps 1 and 2 again to repopulate (or rebuild) the cells.
RothrockCorrect answer
Inspiring
April 19, 2011

If you want to have an array of Sprites that later you clear that is fine. But it doesn't mean that your function should return it.

You need your function to return the sprite so that you can add it to the display list and whatever else you need.

So just have the function get the Sprite, push it into the "toBeClearedInTheFutureArray," and then return a reference to the currently gotten sprite.

Inspiring
April 19, 2011

Well since an Array is not even related to Sprite there is absolutely no way to change an array into a sprite. Perhaps the elements inside the array are sprites? In that case all you need to do is access the element you want.

But your drawCells function returns an array. And that array seems to be full of Class instances. So that also seems strange. Are those actually all Sprites? Maybe you only want the drawCell function to return a Sprite and not an array?

Also drawCells is kind of an odd name for a function that doesn't actually draw anything, but I suppose that is another ball of wax....

Known Participant
April 19, 2011

Rothrock,

     Thank you for the reply. Let me address a few things here in the hopes of allowing you (and others) to better understand my reasoning for doing things in this manner (admittedly, there is probably a much better/easier approach to what I am trying to accomplish which is one of the things I hope to learn/discover from these posts).

     The elements inside my "imageArray" are all individual graphics that I had imported, changed their type to movie clips using .Sprite as their base class (instead of .MovieClip) and then saved as classes. The reason I did this was because the classes could then be referenced via "getDefinitionByName" by each cell value that was being passed to it. In this grid every number from 1 to 9 appears randomly 12 times each (making the 108 cells which populate the grid). I did not, at the time (nor do I now), know of a better method to implement for making sure that each image appears in the cell that has the corresponding value (i.e. every time a cell has the value of 8 then the custom graphic/class "skin8" will be assigned to it so that the viewer will be able to see a more aesthetically pleasing numerical representation, that is to say a slightly more fancy looking number with a picture behind it). I was advised to store these images in an array so that I could destroy them when I reshuffle the grid in order to make room for the new images (but I probably messed up the instructions).

     If the "drawCell" function only returns a sprite rather than the image array itself, doesn't that mean that my "eraseCells" function won't be able to delete the array's children as their values weren't first returned to the global variable which my erasing function is accessing?

     As for the function name "drawCells," you have to keep in mind that a) my program has been redesigned in stages as I add new functionality/remove old functionality (such as removing text labels and formatting which were originally in this function) and b) that my program is called "Blanko."

     I will try and attach an Illustrator exported JPG file that contains the image I am using as the class "skin7" just to give you an example of what I'm trying to use as labels (although it won't let me insert it here in this post, so I will try it in the next post).

Thank you for your help!

Known Participant
April 19, 2011

Here it is, an example of the image class objects that are in my "imageArray" array. Fancy, huh? Every time a cell with the numerical value of 7 gets passed to my "drawCells" function, this little baby gets placed on top of it (eventually I will use it as a button that the user can click, but one step at a time).