My wonderful friend volunteered to test-play my game! I happily report that everything worked as it should, and we were able to play the game as fully as possible given the state of the code. (Some things are missing, including: losing a turn when you're out of bounds, detection of a player winning the game, detection of a player going off the edge of the grid entirely -- this last issue did not come up in our game, but it's rather important to make sure I can handle that somehow.)
First I'll post a screenshot of our finished game. I'm the blue player and my friend is the red.
Following the screenshot, I'm including a transcript of our chat conversation during the game (with my friend's permission, and mildly edited for relevance). It's very helpful to know his thoughts during gameplay, particularly in the areas of: the rules of play, interaction with the interface, and information to be displayed during gameplay.
Our game:
Chat transcript:
me: alright let me instruct you what to do
friend: ok
me: you're still on the page?
friend: absolutely
me: ok refresh it
me: and you should see "game #20" on available games to start
friend: yeah click it?
me: i mean to join
me: yes
me: ok i can see tha tyou joined lol
friend: i'm in baby
me: now does the track show up?
friend: yes
me: alright it's my turn lol
me: i'm blue and your'e red
friend: how do i move it?
me: you have to wait for me to go first
me: i'm player 0
friend: ok
me: you're player 1
me: cuz i started this particular game
friend: ok
me: do you see my move?
friend: you moved up one space
friend: yeah
me: yes
me: now you can click any of the red circles to move there
me: we're trying to go around the track. lol
friend: i gotcha
me: so that's all... lol
friend: can we occupy the same space?
me: not at the same time
friend: ooh
friend: intersting
me: but you can only select from the circles to move to
friend: can i go right on top of the inner black line?
me: they show you where you can move based on the rules
me: yeah that should work
friend: ok
friend: your move
me: yes i know
me: i'm trying to explain lol
friend: hehe
me: cu zi realized you don't know the rules
me: but yeah it's pretty simple
friend: i gotcha
friend: oh now we can move two spaces up
me: the rule is
me: on each turn, you can change your x speed by -1, 0, or 1
me: and same for y speed
me: make sense?
me: so try not to go out of bounds
friend: so how do i change the speed?
me: you are changing it by selecting one of the option circles
friend: ahhh i see
me: middle circle = no change
friend: i getcha
friend: like a turn-based game
me: all the others are a change of some kind, in one or both directions
me: it is turn based yes lol
friend: i dont see why it's letting you take the inside route
friend: and why the spaces closest to the edge wasnt available to me
me: you always have an x/y speed.
me: like i said
me: in each turn you can change one or both of those by: -1, 0, 2 for each
me: but the game is doing the work of tracking your speed and available changes by showing you the options for your move
me: that's all haha
friend: ok fine
me: do you understand it?
friend: for now
me: you manage your acceleration
me: so you should start slowing down in the x-direction
friend: so what's the advantage of a slowing down
me: lol....
me: if you keep going so fast in x-direction
me: you won't be able to stay inside
friend: i getcha
me: b/c you can only slow down by 1 each turn
friend: ahhh ook ok
friend: play on
me: oh shit
me: lol i'm out of bounds hahha
me: right now i don't actually have any implementation for handling that case.
friend: so what does that mean, game over for you/i win?
me: no
me: i haven't coded this part yet
friend: oh ok
friend: so it's stuck
me: but when yor'e out of bounds you lose every other turn
me: so you get slowed down a lot in comparison to the other players
me: no it's not stuck i can just move normally haha
me: see the upper right, the game knows i'm out of bounds
friend: oh ok
me: but it's not going to do anything about it
me: sorry haha i'm technically cheating right now
friend: ahh i see
friend: ok i'm trying to go more down and less righgt
me: mhm
friend: so was that the right move to make
me: yeah that's the right strategy for the moment
me: but don't go flying downwards too fast
me: cuz you will have to slow down again
friend: cause i gotta make the turn
me: it's acutally harder than it looks lol
friend: i go tit,
me: yay
friend: lets see if i can do it
friend: haha
me: dude, you have no idea, i'm so excited right now
friend: ok so one thing
friend: i gotta start goign left
friend: how do i tell it to do that
me: you can't "tell" it to do anything
friend: right
me: you can just choose from the options
me: you'll see
friend: well how do i change my velocity
friend: to go -x
me: it'll just do it for you
friend: based on what
me: as long as you are selecting one of the left-hand-column circles to move to, you're changing your horizontal speed by -1 each time
friend: ah haa
me: just keep clicking lol
friend: ok
me: now your'e out
me: of bounds
me: but you can keep playing like i did lol
friend: yeah
friend: didnt have much of an option
me: see you are going -x now
friend: yeah i see
me: but now watch the inside bound
friend: it's just
friend: reactive
me: haha
me: it's like driving
friend: how do i know what my current "x" is
me: right now you have to count it, sorry
me: i'll make a display for that
friend: haha ok
friend: that's the only thing
friend: keeping track
me: yeahh sorry!
friend: shoulda slowed my Y a bit sooner
me: lol, yeah
me: oh and please try not to go off the board
me: i don't have anything to deal with that right now in the code lol
friend: i'm working on it
friend: but i kidna dont remember how much -Y i put in
me: you can count from your previous dot to your X now
friend: oh forget that
me: okay...
me: crap i might go out
friend: hee
me: i didn't slow x early enough
friend: you nooob
me: right sure.
me: yeah shit
me: haha i'm flyyying off the track there.
friend: hahah
me: you should aslo slow x now
me: by the way it's not goign to detect the winner..
friend: yeah i finally see the x slowing
me: ok i'm gonna stop there ok?
friend: ok so you won then
me: well i was out of bounds so
me: who knows haha
me: hey
me: can i ask you a huge favor
friend:
so it's supposed to skip yoru turn
friend: but it seem like it didnt
me: i know, i told you i didn't code the turn-losing yet
friend: oh ok
me: yeah..
friend: sorry osrry
me: lol it's ok
friend: just trying to get it striaght
friend: ok huge favor
friend: go ahead
me: yeah def.
me: so would you mind if i posted (most of) this conversation with you on my project blog?
friend: sure
me: this is the first time i've played wiht someone else on another computer.
me: i won't put your name
friend: just, know that i'm not educated
friend: haha
me: lol,
me: i like our conversation b/c you pointed out stuff that would be confusing to someone who's never played before
me: which are things i should consider when i write the instructions, etc
friend: ah i see
me: thank you soo much!
Showing posts with label awesome. Show all posts
Showing posts with label awesome. Show all posts
Thursday, April 29, 2010
Monday, April 5, 2010
Multiplayer WORKS! (separate instances updating through the database)
Joe gave me permission to make the blog posts short and sweet. I'm going to try to keep this one more at an overview level.
The goal I set out to accomplish was to separately run multiple instances (i.e. one per player) of the swf with each one keeping itself updated on the actions made (turns taken) by the others.
How it works:
The goal I set out to accomplish was to separately run multiple instances (i.e. one per player) of the swf with each one keeping itself updated on the actions made (turns taken) by the others.
How it works:
- In the HTML for the embed/object elements, the FlashVars parameter provides (a) the total number of players in the game, and (b) with which player number that particular swf instance is to be associated.
- As the "whole document" class (TraceRace) is a DisplayObject, its Actionscript constructor uses its LoaderInfo instance to grab the values of the FlashVars.
- When it's a player's turn, that swf will both show and allow clicking on the options for the next turn. Upon the click of an option, the URLVariables/URLLoader/etc. classes send off this data to a PHP handler script, which sends a MySQL query to input a row in the database table.
- When it's not a player's turn, that swf will show the other player's turn options, but they are not clickable (so that you can't go taking someone else's turn). The swf uses the same URL[whatever] classes to poll for other players' turns showing up in the database: every two seconds, a POST is made which is handled by a PHP script. If the script returns the other player's turn data (since it has been entered in the database), it stops polling, and this swf updates the other player's move visually and in its own state (variables). If the other player's turn has not been entered into the database yet, the script just returns a boolean indicating such, and it initiates the next polling request.
- After I thought I'd figured them out last time, turned out I still was having issues with booleans. I'm now sending booleans through PHP echoes as 1 (true) or 0 (false), because the AS can easily convert them to actual booleans, whereas the word strings "true" and "false" are not so easily converted.
- During debugging I ended up trying to be pretty precise with types, even though I'm not always sure if that was causing a bug or not. For example, I cast variables parsed from PHP-echoed name/value strings to, say, a Number or a uint. I also cast a piece to a piece when I pull it out of an array, since I don't think arrays are designated to hold a certain single type.
- It looks like AS isn't happy with my passing an argument as 'null' (since I was going to retrieve the necessary object a different way, once inside the function). Then I tried using two parameters with default values, but since you can only leave out arguments at the end of the list, I can't input the 2nd and drop the 3rd in one call while doing the reverse in another call. Eventually I just wrote a getter function so I could access the object before the problematic call.
- One of the weirdest problems I've had yet, I actually managed to create myself. By initializing an Array with a specific length, and subsequently pushing more elements into it, I ended up with empty spaces prior to the pushed elements. This actually makes pretty decent sense. But since previously I hadn't initialized the array with a length, the pushed elements just added/filled spots from the beginning. I finally realized what was going on and now add the elements by accessing the array slots via indices.
Wednesday, March 31, 2010
Successful push of variables in AS =[PHP]=> database, plus AS callback
So the other night I set out to implement the plan I outlined before to figure out how to push data (i.e. each turn's information) from Actionscript variables to the database. Here are the components I wrote/set up:
- Database: set up a test table called TestTurns with 3 fields - p_id (piece's ID number), xpos, and ypos.
- Actionscript: added a storeTurn() method to the 'piece' class, which makes use of the URLVariables, URLRequest, and URLLoader classes to structure and send an HTTP POST request, containing a piece's ID number, x-position, and y-position, to the PHP file. Also wrote a callback function - which gets attached to the Loader's COMPLETE event - that spits the echoed data from the PHP script (provided in name/value query-string format) into a URLVariables object and "logs" some information into a dynamic text box currently sitting in the middle of the race track. (This is a temporary debugging mechanism, obviously.)
- PHP: wrote a small script in a file which grabs the 3 POSTed variables, runs an insert query on the database, and echoes back the information it received and whether the query was successful.
- First, I was trying to test the POST to the PHP script by running the Actionscript locally. It was able to pull the file, but in the AS callback function I was getting these strange strings as supposed value counterparts of the names that the URLVariables constructor was able to parse out. I rearranged and tested things for some time until the "well duh" moment: I was expecting PHP to run while sitting on my machine. Oh, wait. :) (To test locally, I wrote a simple text file containing a name/value string, directed the HTTP request to that file, and the URLVariables constructor parsed it just fine.) After this, I uploaded the files so I could test it for real (i.e. with the PHP running).
- I knew that for an insert query, the mysql_query function would return a true or false based on whether the query was successful or an error occurred. However, I didn't know the details on the representation of that boolean, and how it would get converted when echoed by the PHP and then parsed by the URLVariables constructor in the Actionscript. From the output I was getting dumped into the "log" it was appearing as a 1 or 0 instead of the string "true" or "false", so in order that the URLVariables variable for 'success' would actually have a value of true or false (that could then be used in a conditional), I just used the ternary conditional operator (?:) to convert the 1/0 value ahead of time in the PHP echo string.
- Also from the output log I realized that since I was calling (in the handler PHP file) require_once for the db_connect file, whatever was echoed in that file was showing up amidst what the handler file was echoing. Naturally this was screwing up the name/value query string I was trying to create so that the URLVariables constructor (in AS) could read it. I was looking through the PHP documentation for the include/require functions to see if there was a way to suppress the output of the included file, but didn't find anything along those lines. As an alternative for echoing messages of success or error in db_connect.php, I created a variable to store a boolean for connection success. Then, when I require db_connect.php in the handler file, I can store that boolean (i.e. $connect_success = require_once "db_connect.php";) to discover and deal with connection errors.
Friday, March 19, 2010
Found my game on BoardGameGeek!!
Joe suggested I try to find and scan an old piece of paper on which my dad and I had played the game. I'll probably try to do that, but in the meantime, I found a listing for the game under the name "Racetrack" on boardgamegeek.com. There are also some user-submitted photos. My favorites...
(click the images to see them in full size)
Love the comments... The caption on the page says this one is from the 1960s!
(click the images to see them in full size)
Love the comments... The caption on the page says this one is from the 1960s!
Subscribe to:
Posts (Atom)




