Sunday, August 12, 2012

Creating a Pentomino game using AS3: Part 25

Today we'll add the ability to set names for saved levels and start working on reading and displaying saved levels.

Firstly go to save_screen MovieClip in Flash and add a second frame there - add an input text field with id "tName" and a button with id "btn_save_final". This will be the step that comes after the user presses "Save level locally" - he will be asked to pick a name for the level before saving it.

In save_screen.as, add a line that stops the MC at first frame in the constructor:

stop();

In the onSave() function, go to second frame and add a listener for btn_save_final button that calls onSaveFinal handler function:

private function onSave(evt:MouseEvent):void {
this.gotoAndStop(2);
btn_save_final.addEventListener(MouseEvent.CLICK, onSaveFinal);
}

The handler calls closeHandler, removes the event listener and the window, and saves the level using Pentomino.saveLevelLocal(). We pass a thrid value here - tName.text:

private function onSaveFinal(evt:MouseEvent):void {
closeHandler.call();
btn_save_final.removeEventListener(MouseEvent.CLICK, onSaveFinal);
this.parent.removeChild(this);
Pentomino.saveLevelLocal(currentGrid, currentShapes, tName.text);
}

Full save_screen.as class:

package  
{
import flash.display.MovieClip;
import flash.events.MouseEvent;

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

public class save_screen extends MovieClip
{

private static var Pentomino:MovieClip;
private var currentGrid:Array;
private var currentShapes:Array;
private var closeHandler:Function;

public function save_screen(pentominoReference:MovieClip, getGrid:Array, getShapes:Array, onClose:Function) 
{
stop();
Pentomino = pentominoReference;
currentGrid = getGrid;
currentShapes = getShapes;
closeHandler = onClose;
btn_play.addEventListener(MouseEvent.CLICK, onPlay);
btn_save.addEventListener(MouseEvent.CLICK, onSave);
btn_cancel.addEventListener(MouseEvent.CLICK, onCancel);
}

private function onPlay(evt:MouseEvent):void {
removeEverything();
Pentomino.playLevel(currentGrid, currentShapes);
}

private function onSave(evt:MouseEvent):void {
this.gotoAndStop(2);
btn_save_final.addEventListener(MouseEvent.CLICK, onSaveFinal);
}

private function onSaveFinal(evt:MouseEvent):void {
closeHandler.call();
btn_save_final.removeEventListener(MouseEvent.CLICK, onSaveFinal);
this.parent.removeChild(this);
Pentomino.saveLevelLocal(currentGrid, currentShapes, tName.text);
}

private function onCancel(evt:MouseEvent):void {
closeHandler.call();
removeEverything();
}

private function removeEverything():void {
btn_play.removeEventListener(MouseEvent.CLICK, onPlay);
btn_save.removeEventListener(MouseEvent.CLICK, onSave);
btn_cancel.removeEventListener(MouseEvent.CLICK, onCancel);
this.parent.removeChild(this);
}

}

}

In main.as in the saveLevelLocal() function we take this third parameter and apply its value to levelObject's "name" property:

package  
{
import flash.display.MovieClip;
import flash.net.SharedObject;

/**
 * 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);
}

public function saveLevelLocal(grid:Array, shapes:Array, levelName:String):void {
var sharedObject:SharedObject = SharedObject.getLocal("myLevels");
if (sharedObject.data.levels == null) sharedObject.data.levels = [];
var levelObject:Object = new Object;
levelObject.grid = grid;
levelObject.shapes = shapes;
levelObject.name = levelName;
sharedObject.data.levels.push(levelObject);
sharedObject.flush();
}

}

}

In saved_levels.as declare 3 new variables: levels, pages and currentPage:

private var levels:Array = [];
private var pages:int;
private var currentPage:int;

The levels array takes values from SharedObject's levels array, unless it's null. The pages value is calculated in the constructor. We also call a function goPage(1) in the constructor:

public function saved_levels() 
{
savedLevels = SharedObject.getLocal("myLevels");
btn_back.addEventListener(MouseEvent.CLICK, doBack);
if (savedLevels.data.levels != null) levels = savedLevels.data.levels;
tInfo.text = levels.length + " levels (" + savedLevels.size + "B)";
pages = Math.floor(levels.length / 3) + 1;
goPage(1);
}

Before we move on to goPage() function, open the saved_levels MovieClip in Flash and set the ids of 3 saved level item MovieClips to item1, item2 and item3.

Now we'll add the goPage() function. The function receives page number and updates the tPage text field, then sets alpha of all level items to 0 and mouseEnabled and mouseChildren values to false. Then we calculate the index in the levels array for each level in the page (there are 3 levels on each page) and if that item on that specific page exists, set the respective level item's alpha to 1, mouseEnabled and mouseChildren to true, and tTitle's text value to the "name" property of the respective level item in the array.

private function goPage(pageNum:int):void {
currentPage = pageNum;
tPage.text = "Page " + currentPage + "/" + pages;
item1.alpha = item2.alpha = item3.alpha = 0;
item1.mouseEnabled = item2.mouseEnabled = item3.mouseEnabled = false;
item1.mouseChildren = item2.mouseChildren = item3.mouseChildren = false;

if (levels[3 * (currentPage-1)] != null) {
item1.alpha = 1;
item1.mouseEnabled = true;
item1.mouseChildren = true;
item1.tTitle.text = levels[3 * (currentPage-1)].name;
}

if (levels[3 * (currentPage-1)+1] != null) {
item2.alpha = 1;
item2.mouseEnabled = true;
item2.mouseChildren = true;
item2.tTitle.text = levels[3 * (currentPage-1)+1].name;
}

if (levels[3 * (currentPage-1)+2] != null) {
item3.alpha = 1;
item3.mouseEnabled = true;
item3.mouseChildren = true;
item3.tTitle.text = levels[3 * (currentPage-1)+2].name;
}
}

That's all for now.

Full saved_level.as code so far:

package  
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.net.SharedObject;

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

public class saved_levels extends MovieClip
{
private var savedLevels:SharedObject;
private var levels:Array = [];
private var pages:int;
private var currentPage:int;

public function saved_levels() 
{
savedLevels = SharedObject.getLocal("myLevels");
btn_back.addEventListener(MouseEvent.CLICK, doBack);
if (savedLevels.data.levels != null) levels = savedLevels.data.levels;
tInfo.text = levels.length + " levels (" + savedLevels.size + "B)";
pages = Math.floor(levels.length / 3) + 1;
goPage(1);
}

private function goPage(pageNum:int):void {
currentPage = pageNum;
tPage.text = "Page " + currentPage + "/" + pages;
item1.alpha = item2.alpha = item3.alpha = 0;
item1.mouseEnabled = item2.mouseEnabled = item3.mouseEnabled = false;
item1.mouseChildren = item2.mouseChildren = item3.mouseChildren = false;

if (levels[3 * (currentPage-1)] != null) {
item1.alpha = 1;
item1.mouseEnabled = true;
item1.mouseChildren = true;
item1.tTitle.text = levels[3 * (currentPage-1)].name;
}

if (levels[3 * (currentPage-1)+1] != null) {
item2.alpha = 1;
item2.mouseEnabled = true;
item2.mouseChildren = true;
item2.tTitle.text = levels[3 * (currentPage-1)+1].name;
}

if (levels[3 * (currentPage-1)+2] != null) {
item3.alpha = 1;
item3.mouseEnabled = true;
item3.mouseChildren = true;
item3.tTitle.text = levels[3 * (currentPage-1)+2].name;
}
}

private function doBack(evt:MouseEvent):void {
(root as MovieClip).gotoAndStop(1);
}
}

}

Thanks for reading!

No comments:

Post a Comment