Posted by & filed under Coding.

Some games, I’m thinking tower defense, need to give the player the ability to drag symbols around. But you don’t always want to give the player free reign to drag it anywhere. Maybe you want them to only be able to position symbols in a grid. That’s what we’ll create here using ActionScript 3.

Demo

This is what we’re going to be creating.  Try dragging the green square. It will snap so that it’s always in one of the grid squares.

Getting Started

For the demo, I made a new file with a stage size of 500×500 pixels. The size really doesn’t matter as we’re going to use a bit of math to build the grid.

You’ll also need a symbol. I made a green square called GridCrawler_mc. You can call yours whatever you want, but that’s the class name I’m going to use in the code below.

The size of your symbol isn’t all that important right now. It’s going to be rescaled so that it’s the same dimensions as one of the grid squares before it’s added to the stage. You do want to make sure the registration point is at the center though. The code below makes that assumption.

Code

import flash.events.MouseEvent;

// Create variables

/** Number of cells in each direction */
var gridCount:int = 10;

// Height and width of each cell. We're going to be
// using both in several places so we want to store
// it as a variable.
var cellHeight:int = stage.stageHeight / gridCount;
var cellWidth:int = stage.stageWidth / gridCount;

// Keep track of when the mouse button is down for dragging
var mouseDown:Boolean = false;

// Create an instance of the GridCrawler symbol,
// set it so that it's the same size as a cell,
// position at the top left, add to stage, and
// attach event listeners.
var crawler:GridCrawler_mc = new GridCrawler_mc();
crawler.height = cellHeight;
crawler.width = cellWidth;

crawler.x = crawler.width / 2;
crawler.y = crawler.height / 2;

stage.addChild(crawler);

crawler.addEventListener(MouseEvent.MOUSE_DOWN, eDown);
crawler.addEventListener(MouseEvent.MOUSE_UP, eUp);

// Attach and event listener to the stage to watch
// for mouse moves.
stage.addEventListener(MouseEvent.MOUSE_MOVE, eMove);

// Draw gray gridlines on the stage so that we can see
// the snapping.
drawGridlines();

/**	If the mouse goes down over the symbol set mouseDown
  *	to true so that the eMove function will move it.
  */
function eDown(evt:MouseEvent):void {
	mouseDown = true;
}

/**	Set mouseDown back to false so that the symbol will
  *	no longer move with the mouse.
  */
function eUp(evt:MouseEvent):void {
	mouseDown = false;
}

/**	Move the symbol, but only if the mouse is down
 *
 *	The + height and width / 2 is needed because the registration
 * 	point of the movie clip is at its center.
 */
function eMove(evt:MouseEvent):void {
	if (mouseDown) {
		crawler.x = Math.floor(mouseX / cellWidth) * cellWidth + crawler.width / 2;
		crawler.y = Math.floor(mouseY / cellHeight) * cellHeight + crawler.height / 2;
	}
}

/** This is a helper function that draws the grid on the stage
 * 	so that you can see where the symbol should snap. It's not
 * 	part of the actual logic, and it's likely that you would
 *	not want the grid in your actual game.
 */
function drawGridlines():void {
	graphics.lineStyle(1, 0xcccccc);

	for (var i:int = 0; i <= stage.stageWidth; i += cellWidth) {
		graphics.moveTo(i, 0);
		graphics.lineTo(i, stage.stageHeight);
	}
	for (i = 0; i <= stage.stageHeight; i = i += cellHeight) {
		graphics.moveTo(0, i);
		graphics.lineTo(stage.stageWidth, i);
	}
}

There is a function at the end that draws the grid. You may want to leave that out in your game unless you want a visible grid.

Leave a Reply

Your email address will not be published. Required fields are marked *