Sunday, September 2, 2012

Creating a Pentomino game using AS3: Part 46

Today we'll add a feature that shows how many a default level has been solved.

The data on how many times each level has been beaten is stored in a SharedObject, the same one we use for storing saved levels. Except that instead of using the "levels" array, we're using "defaultLevels", which only stores the number which represents how many times the level has been solved.

Firstly, open your project in Flash, open the level_select MovieClip and add a new text field on screen, give it an id "tSolved".

Go to level_select.as.

In the constructor we open the "myLevels" SharedObject and see if defaultLevels is null. If it is, we change it to a new array full of 0's - add as many 0 as there are total default levels:

var i:int
savedLevels = SharedObject.getLocal("myLevels");
if (savedLevels.data.defaultLevels == null) {
savedLevels.data.defaultLevels = [];
for (i = 0; i < levels.length; i++) {
savedLevels.data.defaultLevels.push(0);
}
savedLevels.flush();
}

Full constructor:

public function level_select() 
{
var i:int
savedLevels = SharedObject.getLocal("myLevels");
if (savedLevels.data.defaultLevels == null) {
savedLevels.data.defaultLevels = [];
for (i = 0; i < levels.length; i++) {
savedLevels.data.defaultLevels.push(0);
}
savedLevels.flush();
}

(root as MovieClip).stop();
btn_back.addEventListener(MouseEvent.CLICK, doBack);

levelHolder = new MovieClip();
for (i = 0; i < 5; i++) {
var level:MovieClip = new level_item();
levelHolder.addChild(level);
levelItems.push(level);
level.x = (level.width + distance) * i;
levelWidth = level.width;
}
addChild(levelHolder);
levelHolder.y = 120;
levelHolder.x = -(levelWidth + distance) * 2 + levelWidth / 2;
goX = levelHolder.x;
selectLevel();
setChildIndex(btn_next, numChildren - 1);
setChildIndex(btn_prev, numChildren - 1);
addEventListener(Event.ENTER_FRAME, onFrame);
btn_next.addEventListener(MouseEvent.CLICK, goNext);
btn_prev.addEventListener(MouseEvent.CLICK, goPrev);
updatePage();
}

We will update the text field data in updatePage() function.

The pattern for the text is "solved x times", where x is the number. We need to check if the number ends with 1 to change "times" to "time" in that case:

public function updatePage():void {
tPage.text = (currentLevel + 1) + "/" + levels.length;
var solutions:String = savedLevels.data.defaultLevels[currentLevel].toString();
tSolved.text = "solved " + solutions + " " + ((solutions.charAt(solutions.length-1)=="1")?("time"):("times"));
}

Full level_select.as code so far:

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

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

public class level_select extends MovieClip
{

private var levels:Array = [
{grid:
[
[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]
],
shapes:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
title:
"Standard 10x6"
},
{grid:
[
[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]
],
shapes:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
title:
"Standard 2"
},
{grid:
[
[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]
],
shapes:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
title:
"Standard 3"
},
{grid:
[
[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]
],
shapes:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
title:
"Standard 4"
},
{grid:
[
[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]
],
shapes:
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
title:
"Standard 5"
}
];

public var currentLevel:int = 0;
private var distance:int = 100;
private var levelHolder:MovieClip;
private var levelItems:Array = [];
private var goX:int;
private var levelWidth:int;
private var savedLevels:SharedObject;

public function level_select() 
{
var i:int
savedLevels = SharedObject.getLocal("myLevels");
if (savedLevels.data.defaultLevels == null) {
savedLevels.data.defaultLevels = [];
for (i = 0; i < levels.length; i++) {
savedLevels.data.defaultLevels.push(0);
}
savedLevels.flush();
}

(root as MovieClip).stop();
btn_back.addEventListener(MouseEvent.CLICK, doBack);

levelHolder = new MovieClip();
for (i = 0; i < 5; i++) {
var level:MovieClip = new level_item();
levelHolder.addChild(level);
levelItems.push(level);
level.x = (level.width + distance) * i;
levelWidth = level.width;
}
addChild(levelHolder);
levelHolder.y = 120;
levelHolder.x = -(levelWidth + distance) * 2 + levelWidth / 2;
goX = levelHolder.x;
selectLevel();
setChildIndex(btn_next, numChildren - 1);
setChildIndex(btn_prev, numChildren - 1);
addEventListener(Event.ENTER_FRAME, onFrame);
btn_next.addEventListener(MouseEvent.CLICK, goNext);
btn_prev.addEventListener(MouseEvent.CLICK, goPrev);
updatePage();
}

public function updatePage():void {
tPage.text = (currentLevel + 1) + "/" + levels.length;
var solutions:String = savedLevels.data.defaultLevels[currentLevel].toString();
tSolved.text = "solved " + solutions + " " + ((solutions.charAt(solutions.length-1)=="1")?("time"):("times"));
}

private function goNext(evt:MouseEvent):void {
currentLevel++;
selectLevel();
levelHolder.x = -(levelWidth + distance) * 1 + levelWidth / 2;
updatePage();
}

private function goPrev(evt:MouseEvent):void {
currentLevel--;
selectLevel();
levelHolder.x = -(levelWidth + distance) * 3 + levelWidth / 2;
updatePage();
}

public function selectLevel():void {
setLevelPreview(0, currentLevel - 2);
setLevelPreview(1, currentLevel - 1);
setLevelPreview(2, currentLevel);
setLevelPreview(3, currentLevel + 1);
setLevelPreview(4, currentLevel + 2);

if (currentLevel < levels.length - 1) {
btn_next.alpha = 1;
btn_next.mouseEnabled = true;
}else {
btn_next.alpha = 0;
btn_next.mouseEnabled = false;
}

if (currentLevel > 0) {
btn_prev.alpha = 1;
btn_prev.mouseEnabled = true;
}else {
btn_prev.alpha = 0;
btn_prev.mouseEnabled = false;
}
}

private function setLevelPreview(ind:int, num:int):void {
if (num >= 0 && num < levels.length) {
levelItems[ind].alpha = 1;
levelItems[ind].mouseChildren = true;
levelItems[ind].setLevel(levels[num].grid, levels[num].shapes, levels[num].title, num);
}else {
levelItems[ind].alpha = 0;
levelItems[ind].mouseChildren = false;
}
}

private function onFrame(evt:Event):void {
levelHolder.x += Math.round((goX - levelHolder.x) / 5);
}

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

}

Go to pentomino_game.as and find the checkWin() function. Here, we check if currentINdex doesn't equal -1 and defaultIndex is true - add 1 to the solution count of that level in that case.

private function checkWin():void {
didWin = true;
var i:int;
var u:int;
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;

for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) {didWin = false;}
}
}

if (didWin) {
var winScreen:MovieClip = new win_screen(this);
addChild(winScreen);
var savedLevels:SharedObject;
if (currentIndex != -1 && !defaultIndex) {
savedLevels = SharedObject.getLocal("myLevels");
savedLevels.data.levels[currentIndex].played++;
savedLevels.flush();
}
if (currentIndex != -1 && defaultIndex) {
savedLevels = SharedObject.getLocal("myLevels");
savedLevels.data.defaultLevels[currentIndex]++;
savedLevels.flush();
}
}
}

Full code for pentomino_game.as:

package  
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.net.SharedObject;
import flash.utils.ByteArray;

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

public class pentomino_game extends MovieClip
{
private var mapGrid:Array = [];
private var availableShapes:Array = [];
private var shapeButtons:Array = [];
private var shapeValues:Array = [];
private var placedShapes:Array = [];

private var gridShape:Sprite = new Sprite();
private var canPutShape:Sprite = new Sprite();
private var gridStartX:int;
private var gridStartY:int;
private var gridCellWidth:int;

private var cursor:MovieClip;
private var rolledShape:MovieClip;
private var selectedShape:int = 0;
private var canPutHere:Boolean = false;
private var currentValues:Array = [];
private var didWin:Boolean = false;
private var currentIndex:int;
private var defaultIndex:Boolean;

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

public function playLevel(grid:Array, shapes:Array, index:int = -1, def:Boolean = false):void {
mapGrid = grid;
availableShapes = shapes;
currentIndex = index;
defaultIndex = def;

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

private function calculateGrid():void {
var columns:int = mapGrid[0].length;
var rows:int = mapGrid.length;

// free size: 520x460
// fit in: 510x450

// calculate width of a cell:
gridCellWidth = Math.round(510 / columns);

var width:int = columns * gridCellWidth;
var height:int = rows * gridCellWidth;

// calculate side margin
gridStartX = (520 - width) / 2;

if (height < 450) {
gridStartY = (450 - height) / 2;
}
if (height >= 450) {
gridCellWidth = Math.round(450 / rows);
height = rows * gridCellWidth;
width = columns * gridCellWidth;
gridStartY = (460 - height) / 2;
gridStartX = (520 - width) / 2;
}
}

private function drawGrid():void {
gridShape.graphics.clear();
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;

var i:int;
var u:int;

// draw background
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) drawCell(u, i, 0xffffff, 1, 0x999999);
}
}
}

private function drawCell(width:int, height:int, fill:uint, thick:Number, line:uint):void {
gridShape.graphics.beginFill(fill);
gridShape.graphics.lineStyle(thick, line);
gridShape.graphics.drawRect(width * gridCellWidth, height * gridCellWidth, gridCellWidth, gridCellWidth);
}

private function mouseMove(evt:MouseEvent):void {
cursor.x = mouseX;
cursor.y = mouseY;
checkPut();
}

private function checkPut():void {
if (selectedShape > 0) {
var mousePos:Point = new Point(Math.floor((mouseX - gridStartX) / gridCellWidth), Math.floor((mouseY - gridStartY) / gridCellWidth));
canPutHere = true;
updateCurrentValues();
for (var i:int = 0; i < currentValues.length; i++) {
var cellX:int = currentValues[i][0] + mousePos.x;
var cellY:int = currentValues[i][1] + mousePos.y;
if (cellX < 0 || cellY < 0 || cellX >= mapGrid[0].length || cellY >= mapGrid.length || mapGrid[cellY][cellX]!=1) {
canPutHere = false;
}
}
if (canPutHere) {
cursor.alpha = 0.8;
}
if (!canPutHere) {
canPutShape.graphics.clear();
cursor.alpha = 0.4;
}
}
}

private function drawCanPut():void {
canPutShape.graphics.clear();
var mousePos:Point = new Point(Math.floor((mouseX - gridStartX) / gridCellWidth), Math.floor((mouseY - gridStartY) / gridCellWidth));
for (var i:int = 0; i < currentValues.length; i++) {
var cellX:int = (currentValues[i][0] + mousePos.x) * gridCellWidth;
var cellY:int = (currentValues[i][1] + mousePos.y) * gridCellWidth;
canPutShape.graphics.beginFill(0x00ff00, 0.2);
canPutShape.graphics.drawRect(cellX, cellY, gridCellWidth, gridCellWidth);
}
}

private function mouseWheel(evt:MouseEvent):void {
if (evt.delta > 0) cursor.rotation += 90;
if (evt.delta < 0) cursor.rotation -= 90;
if (selectedShape > 0) checkPut();
}

private function keyDown(evt:KeyboardEvent):void {
if (evt.keyCode == 68) cursor.rotation += 90;
if (evt.keyCode == 65) cursor.rotation -= 90;
if (evt.keyCode == 32) cursor.scaleX *= -1;
if (selectedShape > 0) checkPut();
}

private function updateCurrentValues():void {
currentValues = clone(shapeValues[selectedShape-1]);
for (var i:int = 0; i < 5; i++) {
if (cursor.rotation == 90) {
currentValues[i].reverse();
currentValues[i][0] *= -1;
}
if (cursor.rotation == 180 || cursor.rotation == -180) {
currentValues[i][0] *= -1;
currentValues[i][1] *= -1;
}
if (cursor.rotation == -90) {
currentValues[i].reverse();
currentValues[i][1] *= -1;
}
if (cursor.scaleX < 0 && (cursor.rotation != -90 || cursor.rotation != 90)) {
currentValues[i][0] *= -1;
}
if (cursor.scaleX < 0 && (cursor.rotation == -90 || cursor.rotation == 90)) {
currentValues[i][0] *= -1;
currentValues[i][1] *= -1;
}
}
drawCanPut();
}

private function clone(source:Object):*{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}

private function startDragShape(shapeType:int, rot:int = 0, scalex:Number = 0, scaley:Number = 0):void {
cursor.rotation = rot;
cursor.scaleX = scalex;
cursor.scaleY = scaley;
if (scalex == 0) {
cursor.scaleX = gridCellWidth / 100;
cursor.scaleY = gridCellWidth / 100;
}
cursor.alpha = 0.75;
cursor.visible = true;
cursor.gotoAndStop(shapeType);
}

private function stopDragShape():void {
canPutShape.graphics.clear();
cursor.alpha = 0;
cursor.visible = false;
}

private function everyFrame(evt:Event):void {
if (rolledShape != null) {
rolledShape.rotation += 4;
}
}

private function buttonOver(evt:MouseEvent):void {
if(selectedShape==0){
evt.currentTarget.bg.alpha = 1;
rolledShape = evt.target.shape;
}
}

private function buttonOut(evt:MouseEvent):void {
evt.currentTarget.bg.alpha = 0.3;
rolledShape = null;
}

private function buttonDown(evt:MouseEvent):void {
selectedShape = evt.currentTarget.shape.currentFrame;
if(availableShapes[selectedShape-1]>0){
startDragShape(selectedShape);
availableShapes[selectedShape-1]--;
evt.currentTarget.count.text = availableShapes[selectedShape-1];
evt.currentTarget.bg.alpha = 0.3;
rolledShape = null;
}else {
selectedShape = 0;
}
}

private function mouseUp(evt:MouseEvent):void {
stopDragShape();
if (selectedShape > 0) {
if (!canPutHere) {
availableShapes[selectedShape-1]++;
shapeButtons[selectedShape-1].count.text = availableShapes[selectedShape-1];
selectedShape = 0;
}
if (canPutHere) {
var mousePos:Point = new Point(Math.floor((mouseX - gridStartX) / gridCellWidth), Math.floor((mouseY - gridStartY) / gridCellWidth));
var newShape:MovieClip = new game_shape();
addChild(newShape);
newShape.x = gridStartX + (mousePos.x+1) * gridCellWidth - gridCellWidth / 2;
newShape.y = gridStartY + (mousePos.y + 1) * gridCellWidth - gridCellWidth / 2;
newShape.rotation = cursor.rotation;
newShape.scaleX = cursor.scaleX;
newShape.scaleY = cursor.scaleY;
newShape.gotoAndStop(selectedShape);
newShape.addEventListener(MouseEvent.MOUSE_DOWN, placedShapeDown);
placedShapes.push(newShape);
for (var i:int = 0; i < currentValues.length; i++) {
var cellX:int = currentValues[i][0] + mousePos.x;
var cellY:int = currentValues[i][1] + mousePos.y;
mapGrid[cellY][cellX] = 2;
}
cursor.parent.setChildIndex(cursor, cursor.parent.numChildren - 1);
selectedShape = 0;
checkWin();
}
}
}

private function placedShapeDown(evt:MouseEvent):void {
selectedShape = evt.currentTarget.currentFrame;

// start dragging
startDragShape(evt.currentTarget.currentFrame, evt.currentTarget.rotation, evt.currentTarget.scaleX, evt.currentTarget.scaleY);

// update grid values
updateCurrentValues();
var shapePos:Point = new Point(Math.floor((evt.currentTarget.x - gridStartX) / gridCellWidth), Math.floor((evt.currentTarget.y - gridStartY) / gridCellWidth));
for (var i:int = 0; i < 5; i++) {
mapGrid[shapePos.y + currentValues[i][1]][shapePos.x + currentValues[i][0]] = 1;
}

// remove shape
for (var u:int = 0; u < placedShapes.length; u++) {
if (placedShapes[u] == evt.currentTarget) {
placedShapes.splice(u, 1);
break;
}
}
evt.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN, placedShapeDown);
evt.currentTarget.parent.removeChild(evt.currentTarget);

checkPut();
}

private function doReset(evt:MouseEvent):void {
resetLevel();
}

public function resetLevel():void {
var i:int;
var u:int;
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;
// change values in array
for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 2) mapGrid[i][u] = 1;
}
}
// delete each shape
for (i = placedShapes.length-1; i >= 0; i--) {
selectedShape = placedShapes[i].currentFrame;
availableShapes[selectedShape-1]++;
shapeButtons[selectedShape-1].count.text = availableShapes[selectedShape-1];
placedShapes[i].parent.removeChild(placedShapes[i]);
placedShapes.pop();
}
placedShapes = [];
selectedShape = 0;
didWin = false;
}

private function doMainmenu(evt:MouseEvent):void {
if (defaultIndex) {
(root as MovieClip).backAndSelect(currentIndex);
}else {
(root as MovieClip).gotoAndStop(1);
}
}

private function checkWin():void {
didWin = true;
var i:int;
var u:int;
var width:int = mapGrid[0].length;
var height:int = mapGrid.length;

for (i = 0; i < height; i++) {
for (u = 0; u < width; u++) {
if (mapGrid[i][u] == 1) {didWin = false;}
}
}

if (didWin) {
var winScreen:MovieClip = new win_screen(this);
addChild(winScreen);
var savedLevels:SharedObject;
if (currentIndex != -1 && !defaultIndex) {
savedLevels = SharedObject.getLocal("myLevels");
savedLevels.data.levels[currentIndex].played++;
savedLevels.flush();
}
if (currentIndex != -1 && defaultIndex) {
savedLevels = SharedObject.getLocal("myLevels");
savedLevels.data.defaultLevels[currentIndex]++;
savedLevels.flush();
}
}
}
}

}

And that's all!

Our Pentomino game now has playable default levels, a level editor, a saved level browser and a level auto solver. It's almost a complete puzzle game!

I hope you learned something from this tutorial series. If you have any commenst, questions or improvements - you are welcome to write the feedback below in the comments section.

Thanks for reading!

Results:


2 comments:

Jury said...

Nice advt of the game on your website!
How to play it?

Kirill Poletaev said...

The game is finished, I am currently looking for a sponsor! It will be out as soon as I find one.

Post a Comment