Welcome to my blog. I mainly blog about the basics of running Flash games over the internet, but sometimes I get distracted. Here you will find my efforts at programming turn based Flash games, plus links to all the games I have written. You are free (as in beer) to get all the code, just email me - nicolas_evans at yahoo.com (sorry you cant click on it - I dont want more spam).
Building Multiplayer Games in Flash.

myCommunications.fnMessageSuccess = function ()
{gotoAndPlay("Player1TestMessageID");}
myCommunications.fnMessageFail = function ()
{trace ("fail activated");gotoAndPlay("Player1End") }
myCommunications.fnSendToServer (1) ;
Then it tests the message returned is correct.
if (parseInt(myCommunications.gmyLoadVars.messageID) != 1 +
myCommunications.gnMessageID) {
trace(["MessageID Error",
myCommunications.gmyLoadVars.messageID,
myCommunications.gnMessageID])
_level0.gotoAndStop("ConnectionError")
}
Lastly it repeatedly asks the server (every 3 seconds) if the opponent has made his move.
if (parseInt(myCommunications.gmyLoadVars.messageID) != 1 +
myCommunications.gnMessageID) {
trace(["MessageID Error",
myCommunications.gmyLoadVars.messageID,
myCommunications.gnMessageID])
_level0.gotoAndStop("ConnectionError")
}
myCommunications.fnMessageSuccess = function () {
if (parseInt(myCommunications.gmyLoadVars.pno) == 2) {
gotoAndPlay("Player1LoopEnd");
}
}
myCommunications.fnMessageFail = function ()
{trace ("fail activated");gotoAndPlay("Player1Loop") }
myCommunications.fnLoadVariables("?action=VIEW&filename=" + myScrambleGame.gnGameNumber);
This concludes the explanation, but if you feel I missed a bit (or a lot) out, please comment or email me.
My next task is to convert 3 more games to running over the net, and I will blog if I have any improvements.

class MyCommunications {
private var gsURL:String;
var gmyLoadVars:LoadVars;
var gnMessageID:Number;
private var gnErrorCount:Number;
function MyCommunications (pURL:String) {
gsURL = pURL;
gnErrorCount = 0;
gmyLoadVars = new LoadVars();
gmyLoadVars.onLoad = function(success:Boolean) {
if (success) {
if (gnErrorCount > 0)
gnErrorCount--;
_level0.myCommunications.fnMessageSuccess();
}
else if (gnErrorCount < 5) {
gnErrorCount++;
_level0.myCommunications.fnMessageFail();
}
else {
trace("Error loading/parsing LoadVars.");
_level0.gotoAndStop("FatalError");
}
}
}
function fnLoadVariables(pString:String) {
trace("fnLoadVariables")
gmyLoadVars.load(gsURL + "scramble.jsp" + pString +
"&nocache=" + Math.random(), "GET");
}
function fnSendToServer (pAsPlayer) {
var i:Number,j:Number;
var arTemp:Array = new Array();
j = 0;
arTemp[j++] = gsURL + "scramble.jsp" +
"?action=INSERT" +
"&filename=" + _level0.myScrambleGame.gnGameNumber +
"&pno=" + pAsPlayer +
"&nTurn=" + _level0.myScrambleGame.gnTurn +
"&rnd=" + _level0.myScrambleGame.gnRound +
"&p2score=" + _level0.myScrambleGame.player2Hand.nScore +
"&pwd=" + _level0.myScrambleGame.gsPassword +
"&p1hand=" ;
for (i=0;i<_level0.myScrambleGame.player1Hand.arPlayerTiles.length;i++) {
arTemp[j++] = _level0.myScrambleGame.player1Hand.arPlayerTiles[i]._name + ",";
}
arTemp[j++] = "&p2hand=";
for (i=0;i<_level0.myScrambleGame.player2Hand.arPlayerTiles.length;i++) {
arTemp[j++] = _level0.myScrambleGame.player2Hand.arPlayerTiles[i]._name + ",";
}
arTemp[j++] = "&board=";
for (i=0;i<_level0.myScrambleGame.garBoard.length;i++) {
if (_level0.myScrambleGame.garBoard[i] != "Empty")
arTemp[j++] = _level0.myScrambleGame.garBoard[i]._name;
arTemp[j++] = ",";
}
arTemp[j++] = "&order=" ;
for (i=0;i<_level0.myScrambleGame.garTileOrder.length;i++) {
arTemp[j++] = _level0.myScrambleGame.garTileOrder[i] + ",";
}
arTemp[j++] = "&p1toopen=" + _level0.myScrambleGame.player1Hand.bToOpen +
"&p2toopen=" + _level0.myScrambleGame.player2Hand.bToOpen +
"&p1score=" + _level0.myScrambleGame.player1Hand.nScore +
"&messageID=";
gnMessageID = Math.floor(Math.random() * 1000);
arTemp[j++] = "" + gnMessageID;
gmyLoadVars.load(arTemp.join(""),gmyLoadVars,"POST");
}
function fnParseVariablesFromServer() {
if (parseInt(gmyLoadVars.nErrorNumber) != 0) {
trace("Error received from server " + gmyLoadVars.nErrorNumber)
_level0.gotoAndStop("ConnectionError")
}
_level0.myScrambleGame.gnPlayerNumber = parseInt(gmyLoadVars.pno);
_level0.myScrambleGame.gnTurn = parseInt(gmyLoadVars.nTurn);
_level0.myScrambleGame.gnRound = parseInt(gmyLoadVars.rnd) ;
_level0.myScrambleGame.gsPassword = rTrim(gmyLoadVars.pwd);
_level0.myScrambleGame.player1Hand.arPlayerTiles =
fnConvertStringToObjects(gmyLoadVars.p1hand);
_level0.myScrambleGame.player2Hand.arPlayerTiles =
fnConvertStringToObjects(gmyLoadVars.p2hand);
_level0.myScrambleGame.garBoard = fnConvertStringToObjects(gmyLoadVars.board);
_level0.myScrambleGame.garTileOrder = gmyLoadVars.order.split(",");
_level0.myScrambleGame.garTileOrder.pop(); // remove empty space at end
_level0.myScrambleGame.player1Hand.bToOpen =
fnConvertStringToBoolean(gmyLoadVars.p1toopen);
_level0.myScrambleGame.player2Hand.bToOpen =
fnConvertStringToBoolean(gmyLoadVars.p2toopen);
_level0.myScrambleGame.player1Hand.nScore = parseInt(gmyLoadVars.p1score);
_level0.myScrambleGame.player2Hand.nScore = parseInt(gmyLoadVars.p2score);
}
function fnConvertStringToObjects (pString:String):Array {
trace("fnConvertStringToObjects")
var i:Number;
var arTemp =new Array();
var arTempOut = new Array();
arTemp = pString.split(",");
for (i =0;i<arTemp.length;i++) {
if (arTemp[i] == "undefined" || arTemp[i] == "")
arTempOut.push("Empty");
else if (_level0[arTemp[i]])
arTempOut.push(_level0[arTemp[i]] );
}
return arTempOut;
}
function fnConvertStringToBoolean(pString:String):Boolean {
if (pString.substr(0,4) == "true")
return true;
else
return false;
}
function rTrim(s) {
var i:Number;
var sTemp = s;
i = sTemp.length;
while (i > 0) {
if (sTemp.charAt(i-1) == " " ||
sTemp.charAt(i-1) == "\n" ||
sTemp.charAt(i-1) == "\r") {
i--;
}
else {
break;
}
}
return sTemp.substr(0,i);
}
function fnMessageSuccess() {
trace ("fnMessageSuccess");
// overwritten by each message
}
function fnMessageFail() {
trace ("fnMessageFail");
// overwritten by each message
}
}

<%@ page import = "java.io.*" %>
<%
synchronized(page) {
int intVariableCount = 12;
String filename = request.getParameter("filename");
String action = request.getParameter("action");
int intErrorNumber;
int intTemp;
try {
intTemp = Integer.parseInt(filename);
}
catch (NumberFormatException nfe) {
intErrorNumber = 7;
out.println ("v=v&nErrorNumber=" + intErrorNumber);
return;
}
// Create a Blank File if it doesn't already exist
File fileObject = new File("/users/nicolasevans/" + filename + ".txt");
if (!fileObject.exists() ) {
fileObject.createNewFile();
}
// Read the file in
String[] arVariables;
arVariables = new String[intVariableCount];
FileReader fileRead = new FileReader(fileObject);
BufferedReader buffFileIn = new BufferedReader(fileRead);
String strLine = "";
int intCount = 0;
while ((strLine=buffFileIn.readLine()) != null)
if (intCount < intVariableCount) arVariables[intCount++] = strLine;
buffFileIn.close();
fileRead.close();
// Fill in any missing data with none/0
for (int i = intCount; i < intVariableCount ; i++) {
arVariables[i] = " ";
}
// Process the actions
// Insert a score/name
if (action.equals("INSERT")) {
intErrorNumber = 0;
// Abandon message if not later than the file
arVariables[0] = request.getParameter("pno");
if (Integer.parseInt(arVariables[0]) != 1
&& Integer.parseInt(arVariables[0]) != 2) {
intErrorNumber = 1;
}
if (!arVariables[1].equals(" ") && Integer.parseInt(arVariables[1])
>= Integer.parseInt(request.getParameter("nTurn") )) {
intErrorNumber = 2;
}
arVariables[1] = request.getParameter("nTurn");
try {
intTemp = Integer.parseInt(request.getParameter("rnd"));
}
catch (NumberFormatException nfe) {
intErrorNumber = 3;
}
arVariables[2] = request.getParameter("rnd");
try {
intTemp = Integer.parseInt(request.getParameter("p2score"));
}
catch (NumberFormatException nfe) {
intErrorNumber = 6;
}
arVariables[3]= request.getParameter("p2score");
arVariables[4] = request.getParameter("pwd");
arVariables[5] = request.getParameter("p1hand");
arVariables[6] = request.getParameter("p2hand");
arVariables[7] = request.getParameter("board");
arVariables[8] = request.getParameter("order");
arVariables[9] = request.getParameter("p1toopen");
arVariables[10]= request.getParameter("p2toopen");
try {
intTemp = Integer.parseInt(request.getParameter("p1score"));
}
catch (NumberFormatException nfe) {
intErrorNumber = 5;
}
arVariables[11]= request.getParameter("p1score");
try {
intTemp = Integer.parseInt(request.getParameter("messageID"));
}
catch (NumberFormatException nfe) {
intErrorNumber = 8;
}
if (intErrorNumber == 0) {
// create a new file with the variables passed in
fileObject.createNewFile();
FileOutputStream fileStream = new FileOutputStream(fileObject);
DataOutputStream dataStream = new DataOutputStream(fileStream);
for (int i=0;i < intVariableCount;i++) {
dataStream.writeBytes(arVariables[i] + "\n");
}
dataStream.close();
fileStream.close();
intTemp = Integer.parseInt(request.getParameter("messageID")) + 1;
out.println ("v=v&messageID=" + intTemp);
}
else {
out.println ("v=v&nErrorNumber=" + intErrorNumber);
return;
}
}
// Clear the list
else if (action.equals("CLEAR")) {
out.println("deleting");
fileObject.delete();
}
else if (action.equals("VIEW")) {
// return the variables from the file
out.println ("v=v&nErrorNumber=0");
out.println ("&pno=" + arVariables[0] );
out.println ("&nTurn=" + arVariables[1] );
out.println ("&rnd=" + arVariables[2] );
out.println ("&p2score=" + arVariables[3] );
out.println ("&pwd=" + arVariables[4] );
out.println ("&p1hand=" + arVariables[5] );
out.println ("&p2hand=" + arVariables[6] );
out.println ("&board=" + arVariables[7] );
out.println ("&order=" + arVariables[8] );
out.println ("&p1toopen=" + arVariables[9] );
out.println ("&p2toopen=" + arVariables[10] );
out.println ("&p1score=" + arVariables[11] );
}
}
%>
If you understand Java you can see its very simple. If not, I hope the comments help.
class GENERIC {
public var clip:MovieClip;
function GENERIC (ca:MovieClip) {
clip = ca;
}
}
import GENERIC;
class MyScrambleGame extends GENERIC {
function MyScrambleGame (ca:MovieClip,pTarget,pAsPlayer:Number) {
super(ca);
mcCa = ca;
}
function fnStartOfRound() {
}
function fnStartOfTurn() {
}
function fnEndOfTurn() {
}
function fnEndOfRound() {
}
function fnEndOfGame() {
}
function fnShuffleTiles() {
}
function fnDisplayBoard() {
}
function fnHideBoard() {
}
function fnEnableTableDrag() {
}
function fnDisableTableDrag() {
}
function fnStartDrag (mc:MovieClip) {
}
function fnStopDrag (mc:MovieClip) {
}
}
There are other methods specific to this game.
My next post should deal with a net version of Scramble.



Play
Fish Or Foul
Play
Mammoths