So, at the insistence of my co-worker Mario I’ve been reading up a bit on Flex. I can’t say it’s been love at first site, but I’m giving it a solid chance and I’ll post my thoughts on the tech after I’ve solidified on the matter.
Anywho, here’s my first app. It’s a simple Tic-Tac-Toe game, which took longer, and is uglier than it should be, since I haven’t quite figured out what I’m doing yet. Not that that’s ever stopped me from posting before.
Amazing eh?
The MXML File:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx = "http://www.adobe.com/2006/mxml" layout = "absolute" width = "220" height = "190" creationComplete = "reset(this)" > <mx:Script source = "TicTacToe.as" /> </mx:Application>
My Tile Class
package components {
import flash.events.MouseEvent;
import mx.controls.Button;
public class Tile extends Button {
public function Tile(x:int,y:int,click:Function) {
super();
this.x = x;
this.y = y;
this.label = "";
this.addEventListener(MouseEvent.CLICK,click);
}
public function belongsTo(player:String):Boolean {
return this.label == player;
}
public function isEmpty():Boolean {
return belongsTo("");
}
}
}
And finally, my actual game code:
import components.*;
import mx.controls.Alert;
private const START_X:int = 90;
private const START_Y:int = 80;
private const TILE_SIZE:int = 50;
private const TILE_BUFFER:int = 5;
private const BOARD_SIZE:int = 3;
private const PLAYER_X:String = "X";
private const PLAYER_O:String = "O";
private var turn:String;
private var container:DisplayObjectContainer;
private var board:Array;
private function isValidMove(tile:Tile):Boolean {
return(tile.label == "");
}
private function takeTurn(tile:Tile):void {
tile.label = turn;
if(turn == PLAYER_X) {
turn = PLAYER_O;
} else {
turn = PLAYER_X;
}
}
private function toggle(e:MouseEvent):void {
var tile:Tile = Tile(e.target);
if(!isValidMove(tile)) {
return;
}
takeTurn(tile);
if(playerWon(PLAYER_X)) {
endGame("Yay, " + PLAYER_X + " won!");
}
if(playerWon(PLAYER_O)) {
endGame("Yay, " + PLAYER_O + " won!");
}
if(!movesAreAvailable()) {
endGame("Everybody loses. Losers.");
}
}
private function endGame(message:String):void {
Alert.show(message);
reset(container);
}
private function movesAreAvailable():Boolean {
var i:int, j:int;
for(i = 0; i < BOARD_SIZE; i++) {
for(j = 0; j < BOARD_SIZE; j++) {
if(board[i][j].isEmpty()) {
return true;
}
}
}
return false;
}
private function playerWon(player:String):Boolean {
var i:int, j:int;
var status:Boolean;
for(i = 0; i < BOARD_SIZE; i++) {
status = true;
for(j = 0; j < BOARD_SIZE; j++) {
status = status && board[i][j].belongsTo(player);
}
if(status) {
return status;
}
}
for(i = 0; i < BOARD_SIZE; i++) {
status = true;
for(j = 0; j < BOARD_SIZE; j++) {
status = status && board[j][i].belongsTo(player);
}
if(status) {
return status;
}
}
status = true;
for(i = 0; i < BOARD_SIZE; i++) {
status = status && board[i][i].belongsTo(player);
}
if(status) {
return status;
}
status = true;
for(i = 0; i < BOARD_SIZE; i++) {
status = status && board[i][BOARD_SIZE - (i + 1)].belongsTo(player);
}
return status;
}
private function reset(applicationContainer:DisplayObjectContainer):void {
var tile:Tile;
board = new Array(BOARD_SIZE);
container = applicationContainer;
turn = PLAYER_X;
while(container.numChildren) {
container.removeChildAt(0);
}
for(var i:int = 0; i < BOARD_SIZE; i++) {
board[i] = new Array(BOARD_SIZE);
for(var j:int = 0; j < BOARD_SIZE; j++) {
board[i][j] = new Tile(
START_X + j * (TILE_SIZE + TILE_BUFFER),
START_Y + i * (TILE_SIZE + TILE_BUFFER),
toggle
);
container.addChild(board[i][j]);
}
}
}
On a side note, big thanks to Alex Gorbatchev for my new syntax highlighter plugin and a round of applause for Mark Walters for the AS3 extension to said excellent plugin.