-
-
Save netgfx/52f9142aa7194394e498c096db51b0e4 to your computer and use it in GitHub Desktop.
Firebase: Assigning players in a multiplayer game. This snippet assigns you a spot in a game if the game isn't full yet.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function go() { | |
var userId = prompt('Username?', 'Guest'); | |
// Consider adding '/<unique id>' if you have multiple games. | |
var gameRef = new Firebase(GAME_LOCATION); | |
assignPlayerNumberAndPlayGame(userId, gameRef); | |
}; | |
// The maximum number of players. If there are already | |
// NUM_PLAYERS assigned, users won't be able to join the game. | |
var NUM_PLAYERS = 4; | |
// The root of your game data. | |
var GAME_LOCATION = 'https://SampleGame.firebaseIO-demo.com/'; | |
// A location under GAME_LOCATION that will store the list of | |
// players who have joined the game (up to MAX_PLAYERS). | |
var PLAYERS_LOCATION = 'player_list'; | |
// A location under GAME_LOCATION that you will use to store data | |
// for each player (their game state, etc.) | |
var PLAYER_DATA_LOCATION = 'player_data'; | |
// Called after player assignment completes. | |
function playGame(myPlayerNumber, userId, justJoinedGame, gameRef) { | |
var playerDataRef = gameRef.child(PLAYER_DATA_LOCATION).child(myPlayerNumber); | |
alert('You are player number ' + myPlayerNumber + | |
'. Your data will be located at ' + playerDataRef.toString()); | |
if (justJoinedGame) { | |
alert('Doing first-time initialization of data.'); | |
playerDataRef.set({userId: userId, state: 'game state'}); | |
} | |
} | |
// Use transaction() to assign a player number, then call playGame(). | |
function assignPlayerNumberAndPlayGame(userId, gameRef) { | |
var playerListRef = gameRef.child(PLAYERS_LOCATION); | |
var myPlayerNumber, alreadyInGame = false; | |
playerListRef.transaction(function(playerList) { | |
// Attempt to (re)join the given game. Notes: | |
// | |
// 1. Upon very first call, playerList will likely appear null (even if the | |
// list isn't empty), since Firebase runs the update function optimistically | |
// before it receives any data. | |
// 2. The list is assumed not to have any gaps (once a player joins, they | |
// don't leave). | |
// 3. Our update function sets some external variables but doesn't act on | |
// them until the completion callback, since the update function may be | |
// called multiple times with different data. | |
if (playerList === null) { | |
playerList = []; | |
} | |
for (var i = 0; i < playerList.length; i++) { | |
if (playerList[i] === userId) { | |
// Already seated so abort transaction to not unnecessarily update playerList. | |
alreadyInGame = true; | |
myPlayerNumber = i; // Tell completion callback which seat we have. | |
return; | |
} | |
} | |
if (i < NUM_PLAYERS) { | |
// Empty seat is available so grab it and attempt to commit modified playerList. | |
playerList[i] = userId; // Reserve our seat. | |
myPlayerNumber = i; // Tell completion callback which seat we reserved. | |
return playerList; | |
} | |
// Abort transaction and tell completion callback we failed to join. | |
myPlayerNumber = null; | |
}, function (error, committed) { | |
// Transaction has completed. Check if it succeeded or we were already in | |
// the game and so it was aborted. | |
if (committed || alreadyInGame) { | |
playGame(myPlayerNumber, userId, !alreadyInGame, gameRef); | |
} else { | |
alert('Game is full. Can\'t join. :-('); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment