How to make a full screen grid in ActionScript 3
For the purposes of this discussion, I've created a file named "Grid.as", and added "Grid" as the document class in my "Grid.fla" file. This means it'll automatically run when the .swf runs. The Grid.as code is listed at the end of this post in completion. Here's what the code does.
-
package {
-
import flash.display.*;
Since we'll need several aspects of the display package, we'll just include the whole thing with wild card.
-
public class Grid extends Sprite {
-
private var size:uint = 80;
-
private var bgColor:uint = 0xFFCC00;
-
private var borderColor:uint = 0x666666;
-
private var borderSize:uint = 0;
-
private var rows:Number;
-
private var cols:Number;
Next, we're extending the "Sprite" class, since we don't need a timeline for our purposes.
We're also setting up some basic parameters. Let's take a look at those.
-
private var size:uint = 80;
This is the size of each individual cell. We're assuming the cells will be squares, but I think you'll see how to change that pretty easily in a second.
-
private var bgColor:uint = 0xFFCC00;
-
private var borderColor:uint = 0x666666;
-
private var borderSize:uint = 0;
This establishes the color treatment of each cell. For the purposes here, they're gonna be yella'. With a gray , thin border.
-
private var rows:Number;
-
private var cols:Number;
Finally, we're just establishing a couple of numeric placeholder variables that we can use to control the number of columns and rows in our grid.
-
public function Grid () {
-
this.rows = Math.round(stage.stageWidth / this.size);
-
this.cols = Math.round(stage.stageHeight / this.size);
-
this.drawGrid();
-
}
Next, we're implementing the constructor method, and using some simple math to divide the height and width of the stage by the size of our cells, to come up with a total number of rows and columns, respectively.
At the end of this method, we draw the grid.
-
private function drawGrid () {
-
for (var c=0; c<this.cols; c++) {
-
for (var r=0; r<this.rows; r++) {
-
var toX:Number = c * size;
-
var toY:Number = r * size;
-
this.drawSquare (toX, toY);
-
}
-
}
-
}
This is a nested for loop to draw the cells. You can change the order in which they are drawn (rows first, then cols) without any visual change. However, if you were drawing something that needed to be placed in a specific order, like say the periodic table of elements, you'd want to consider the order here. For now, I'm just looping through the total number of columns, and within each iteration of that loop, I'm looping through the total number of rows, and drawing a cell. I come up with the x/y value with a simple math trick. It goes like this:
Since 0 x * = 0, we can start a loop with 0, increment by 1, and multiply by anything at each increment, and always get 0 the first time, the increment variable the second time, and then exponential increases from there. In this case, the first loop is giving us a toX value of 0 (0 x 80 = 0), and a toY value of 0 (same math).
The second time through that loop, we're still in the first column, so our toX value will still be zero, but now our toY value will be 80 (1 * 80 = 80). The third time gives us a toY of 160 (2 * 80), and so on. When we're done with one iteration of this loop, we've got one column built, and we move on to build the next one.
To test this, simply change this line:
-
for (var c=0; c<this.cols; c++) {
... to this...
-
for (var c=0; c<1; c++) {
When you run this script, you'll get one column on the left side of the screen. That's because we're only building one column. If you reversed the two loops, and limited the outer loop to 1, you'd see that we have one row across the top. Now onto drawing a square.
-
private function drawSquare (toX:Number, toY:Number):void {
-
var child:Shape = new Shape();
-
child.graphics.beginFill (bgColor);
-
child.graphics.lineStyle (borderSize, borderColor);
-
child.graphics.drawRect (toX, toY, size, size);
-
child.graphics.endFill ();
-
addChild (child);
-
}
-
}
-
}
This method simply receives the x / y values, and doesn't send anything back (thus the ":void" part of the declaration).
We then declare a local variable to hold a new Shape object. We put the background color, border size, and border color in place, and simply draw a rectangle. We're passing the rectangle an x / y value, to place this square properly on the screen, and a size value, to ... size it.
You'll notice here that we're sending the size value twice. That's for the width and height. If you wanted the cells to be rectangles rather than squares, I'd recommend writing a function called something like "myRectangle" (since drawRect is taken), and have it reference a height / width value. You'll need to also remove the 'size' parameter at the beginning of this class, and create separate height / width values as well.
Here's the full code:
-
package {
-
import flash.display.*;
-
-
public class Grid extends Sprite {
-
private var size:uint = 80;
-
private var bgColor:uint = 0xFFCC00;
-
private var borderColor:uint = 0x666666;
-
private var borderSize:uint = 0;
-
private var rows:Number;
-
private var cols:Number;
-
-
public function Grid () {
-
this.rows = Math.round(stage.stageWidth / this.size);
-
this.cols = Math.round(stage.stageHeight / this.size);
-
this.drawGrid();
-
}
-
-
private function drawGrid () {
-
for (var c=0; c<this.cols; c++) {
-
for (var r=0; r<this.rows; r++) {
-
var toX:Number = c * size;
-
var toY:Number = r * size;
-
this.drawSquare (toX, toY);
-
}
-
}
-
}
-
-
private function drawSquare (toX:Number, toY:Number):void {
-
var child:Shape = new Shape();
-
child.graphics.beginFill (bgColor);
-
child.graphics.lineStyle (borderSize, borderColor);
-
child.graphics.drawRect (toX, toY, size, size);
-
child.graphics.endFill ();
-
addChild (child);
-
}
-
}
-
}
As a challenge, try different ways to make the cells automatically fill the exact space of the stage, as opposed to using a rounded number of cells / rows, and a fixed width cell. I'll give you a hint, you'll need to establish the 'size' parameter more than once
Enjoy!
You may Leave a comment or Subscribe to Comments RSS or Trackback this entry.
1 comment so far
Leave a comment
Please be polite and on topic. Your e-mail will never be published.
Hey this is great-- I think it's exactly what I am looking for. Not necessarily full-screen, but I have a list of text items that need to be arranged in columns alphabetically going down and wrapping to the next column and so on..
That, and, I am having issues transitioning to AS3 and am stuck on AS2 atm. :(
Thanks for sharing :D