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.