Tuesday, August 7, 2012

Creating a Pentomino game using AS3: Part 20

Today we'll add the ability to play the level that was created in the editor.

Bascially our goal is to somehow transfer data between two frames in Flash. We can do this by creating a document class for the game and some functions to communicate with different classes through the main document class.

Firstly go to your Flash project and go to the second frame (the one that contains pentomino_game instance). Give the pentomino_game object an id "game".

Now we need to provide a class path for the main document. This can be done by unselecting anything you have selected in Flash under the Publish tab in Properties. Set the class path to "main".

Create main.as class file. It's a simple class that extends MovieClip and currently has 1 public function besides the constructor - playLevel(). Give it two parameters - grid and shapes, both are arrays. Inside the function, use gotoAndStop() method to go to the second frame, and call game's playLevel function (which we will add shortly). Pass the grid and shapes values there as well.

package  
{
import flash.display.MovieClip;

/**
 * Open-source pentomino game engine
 * @author Kirill Poletaev
 */

public class main extends MovieClip
{

public function main() 
{
}

public function playLevel(grid:Array, shapes:Array):void {
gotoAndStop(2);
game.playLevel(grid, shapes);
}

}

}

Go to pentomino_game.as class now and add a public function playLevel(). It receives grid and shapes arrays. Inside the function apply the received values to mapGrid and availableShapes. Calculate grid values, draw the grid, position canPutShape object and update available shape counters:

public function playLevel(grid:Array, shapes:Array):void {
mapGrid = grid;
availableShapes = shapes;

// grid settings
calculateGrid();
gridShape.x = gridStartX;
gridShape.y = gridStartY;

// draw tiles
drawGrid();

// can put shape
canPutShape.x = gridStartX;
canPutShape.y = gridStartY;

// update available shapes
for (var i:int = 0; i < shapeButtons.length; i++) {
shapeButtons[i].count.text = String(availableShapes[i]);
}
}

Take the level creation part from the constructor. Instead, add default level arrays for grid and shapes array and call the playLevel() function to generate the default level:

public function pentomino_game() 
{
// default map
var defaultGrid:Array = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
];

var defaultShapes:Array = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2];

playLevel(defaultGrid, defaultShapes);

shapeValues = [
[[0, 0], [0, 1], [0, 2], [0, -1], [0, -2]],
[[0, 0], [0, -1], [0, 1], [1, 0], [1, -1]],
[[0, 0], [0, 1], [0, 2], [0, -1], [ -1, -1]],
[[0, 0], [0, 1], [0, -1], [ -1, 0], [1, -1]],
[[0, 0], [ -1, 0], [ -2, 0], [0, -1], [1, -1]],
[[0, 0], [0, 1], [0, -1], [1, -1], [ -1, -1]],
[[0, 0], [1, 0], [ -1, 0], [1, -1], [ -1, -1]],
[[0, 0], [ -1, 0], [ -2, 0], [0, -1], [0, -2]],
[[0, 0], [0, 1], [ -1, 1], [1, 0], [1, -1]],
[[0, 0], [0, 1], [0, -1], [1, 0], [ -1, 0]],
[[0, 0], [ -1, 0], [ -2, 0], [1, 0], [0, -1]],
[[0, 0], [0, 1], [1, 1], [0, -1], [-1, -1]]
];

addChild(gridShape);
addChild(canPutShape);

// add shape buttons
for (var i:int = 0; i < 4; i++) {
for (var u:int = 0; u < 3; u++) {
var shapeButton:MovieClip = new select_shape();
shapeButton.x = 528 + u * 62;
shapeButton.y = 55 + i * 62;
addChild(shapeButton);
shapeButton.bg.alpha = 0.3;
shapeButton.count.text = String(availableShapes[3 * i + u]);
shapeButton.shape.gotoAndStop(3 * i + u + 1);
shapeButtons.push(shapeButton);
shapeButton.addEventListener(MouseEvent.ROLL_OVER, buttonOver);
shapeButton.addEventListener(MouseEvent.ROLL_OUT, buttonOut);
shapeButton.addEventListener(MouseEvent.MOUSE_DOWN, buttonDown);
}
}

// cursor
cursor = new game_shape();
addChild(cursor);
cursor.mouseEnabled = false;
cursor.mouseChildren = false;
cursor.visible = false;
addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheel);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
addEventListener(Event.ENTER_FRAME, everyFrame);
addEventListener(MouseEvent.MOUSE_UP, mouseUp);

// buttons
btn_reset.addEventListener(MouseEvent.CLICK, doReset);
btn_mainmenu.addEventListener(MouseEvent.CLICK, doMainmenu);
}

Now go to pentomino_editor.as class. Declare a new static variable Pentomino:

private static var Pentomino:MovieClip;

Apply its value in the constructor like this:

Pentomino = (root as MovieClip);

Now in doSave() function call Pentomino's playLevel() function and pass mapGrid and available shapes data:

private function doSave(evt:MouseEvent):void {
if (checkSave()) {
var shapes:Array = [];
for (var i:int = 0; i < shapeButtons.length; i++) {
shapes.push(shapeButtons[i].count.value);
}
Pentomino.playLevel(mapGrid, shapes);
}
}

Now we can play the levels that are created in the editor!

Thanks for reading!

The results:


No comments:

Post a Comment