Home / Tutorials / Various Techniques / Making objects snap to a grid /

Flash Tutorials

Making objects snap to a grid - Page 1

Posted by : awesty on Apr 21, 2008

 

5.0/5

In this tutorial you will learn how to make MC's (movie clips) snap to a grid through actionscript using some basic math. I am using Adobe Flash CS3, but Flash 8 and Flash MX 2004 will work fine as well. If you are using CS3 just make sure you select an AS (Actionscript) 2.0 file.

Here is what we will be making.

Draw a 10x10 circle on the stage. Make it a MC (F8), set its registration to the center. Before you click OK, hit the button that reads 'advanced' if it hasn't already been pressed. Tick the checkbox that labeled 'Export for ActionScript'. In the 'identifier' text box enter 'ball'.

Now draw a 1px line horizontally across the stage (make sure it is wider than the stage). Select it and hit F8 to convert it to a MC. Make its registration point on the middle left. Tick 'Export for ActionScript' and give it an identifier of 'length'.

Draw another 1px line but make this one vertical (make sure it is higher than the stage). Select it and hit F8 to convert it to a MC. Make its registration point the top middle. Tick 'Export for ActionScript' and give it an identifier of 'height'. Theses last two MC's have been so we can draw the grid through actionscript, and resize the grid by changing the value of a single variable.

Delete all of the MC's that are on the stage (do not delete them from the library though!) and select the frame. Open the actions panel (F9) and enter this code.

var drag:Boolean = false;
var i:Number;
var h:Number;
var grid:Number = 25;

for (i=0; (i*grid)<Stage.height; i++) {
    attachMovie("length","l"+i,getNextHighestDepth());
    _root["l"+i]._y = i*grid;
}
for (h=0; (h*grid)<Stage.width; h++) {
    attachMovie("height","h"+h,getNextHighestDepth());
    _root["h"+h]._x = h*grid;
}
attachMovie("ball","ball",getNextHighestDepth());
ball._x = grid+(random(Stage.width)-(grid*2));
ball._y = grid+(random(Stage.height)-(grid*2));

ball.onPress = function() {
    drag = true;
    startDrag(this);
};
ball.onRelease = function() {
    drag = false;
    stopDrag();
};

onEnterFrame = function () {   
    if (!drag) {       
        if (Math.abs(Math.floor(ball._x/grid)-(ball._x/grid))<Math.abs(Math.ceil(ball._x/grid)-(ball._x/grid))) {
            ball._x = Math.floor((ball._x/grid))*grid;
        }else{
            ball._x = Math.ceil((ball._x/grid))*grid;
        }
        if (Math.abs(Math.floor(ball._y/grid)-(ball._y/grid))<Math.abs(Math.ceil(ball._y/grid)-(ball._y/grid))) {
            ball._y = Math.floor((ball._y/grid))*grid;
        }else{
            ball._y = Math.ceil((ball._y/grid))*grid;
        }
    }
};

The first 4 lines are just declaring variables. Drag is a boolean variable that tells us if the ball if being dragged or not. 'i' and 'h' are numbers for the for statements that make that grid. Gird is just the size of the grid. Once you have all the code in try changing the value of grid and see what happens.

Lines 6-13 are what make the grid. There are 2 for statements that attach the horizontal and vertical lines onto the stage. How many there are and how far away they are spaced depends on the grid variable.

Lines 14-16 are attaching the ball to the stage and placing it randomly on the stage. It makes sure it is placed the distance of 'grid' away from the edges, so that it won't appear off the screen.

Lines 18-25 are so you can drag the ball. If you are dragging the drag variable is true. If you aren't it is false. if(Math.abs(Math.floor(ball._x/grid)-(ball._x/grid))<Math.abs(Math.ceil(ball._x/grid)-(ball._x/grid))){ What that does is it divides the ball's x by the grid variable, leaving a number which will most likely have a decimal (if not it doesn't matter. It then rounds it down to the nearest whole number (Math.floor()). It then subtracts the original number (ball._x/grid) from the newely rounded number, and then turns it into a positive number (Math.abs()). It then does the same thing, but instead of rounding down the number it rounds the number up, and then checks which of the results were greater. If the second one is, it runs the script that will snap the ball to the nearest grid line on the right, if the first on is it will snap to the left. There is probably an easier way to do this, but this makes sense to me. If you need help understanding it just post below. ball._x = Math.floor((ball._x/grid))*grid; So if the ball needs to be snapped to the left, this script will run. What it does is makes ball's x equal to Math.floor((ball._x/grid))*grid. That divides the balls x by the value of grid, and then rounds that down. It then multiplies that number by the value of gird. That number will be equal to the nearest grid line on the left. ball._x = Math.ceil((ball._x/grid))*grid; This script runs if the ball needs to snap to the right. It is exactly the same as the script above, except the rounds the number up, therefore resulting in the x coordinate of the nearest grid line on the right.

The rest of the code is exactly the same as the last bits of code I just explained, but they snap the ball up and down.

no comment

Add comment

Please login to post comments.