0

So I'm developing simple game with the following scenario:

  • 2 users need to start a game (so I'm creating new room for 3rd user and so on)
  • 2 users is maximum per room
  • When game is started, event is sent to client, after 60 seconds server needs to end the game.

Code which I wrote will work only for 1 room, but for multiple rooms, cancelling is not correct because my lastRoom variable is incorrect.

I'm new to node.js so I'm not really sure how to deal with this.

Some code:

var lastRoom = 'default'; //this is the first created room

function tryToStartGame(socket){

  var clients = io.sockets.adapter.rooms[lastRoom];

  console.log("Size of room "+lastRoom+" is: "+getObjectSize(clients));

  //we are checking size of last room
  if (getObjectSize(clients) == 2){

    //players in the room should be different
    games['default']= {
      'leftPlayer': getFromObject(clients, 0),
      'rightPlayer': getFromObject(clients, 1),
      'stuff': "some data here"
      'roomName': lastRoom
    };

    console.log("We can start the game");

    //let all the people in that room
    io.to(lastRoom).emit('game', games['default']);

    //game to cancel
    gameToCancel = lastRoom;

    //client needs to be aware when game is ended
    //but if we have simultaneous games this will not work
    setTimeout(function(){
      console.log("Cancelling game in: "+gameToCancel);
      io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");

    }, 8000); //after 8 seconds for test

    //reset the room name, so next time when this function is called in second room
    //we will have something different
    lastRoom = 'game'+new Date().getTime();
  }

  //we have less then 2 players, wait for another player
  if (getObjectSize(clients)<2){
    console.log("Less then 2 players");
    socket.emit('waiting', 'Waiting for another user to join the game');
  }

}

And tryToStartGame(socket) function is called always at connection like this:

io.on('connection', function(socket){

  //when client says he wants to play
  socket.on('joinGame', function(username){

    //add user
    addUser(socket, username);

    //send list of players
    io.emit('playersList', getFormatedPlayers());

    //figure out in which room this player bellongs
    socket.join(lastRoom);

    //try to start the game
    tryToStartGame(socket);

  });

Problematic part is that lastRoom variable is overwritten and then setTimeout picks the wrong room, so what happens that basically last game is canceled, and the previous ones are not.

How should I correctly track and cancel the game in correct rooms ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Splendid
  • 1,317
  • 4
  • 20
  • 41

1 Answers1

3

As you noted, lastRoom is a global variable and might/will change between the time you set it and the timeout

You can create a closure on the timeout function to keep the room as a locale variable:

var lastRoom = 'default'; //this has to be set in the same function than the call to setTimeout

//client needs to be aware when game is ended
//but if we have simultaneous games this will not work
setTimeout(function(){
  var gameToCancel = lastRoom;

  console.log("Cancelling game in: "+gameToCancel);
  io.to(gameToCancel).emit('gameEnded', "Winner logic is todo ;) ");

}, 8000); //after 8 seconds for test
Xavier
  • 1,157
  • 9
  • 29
  • Well, thanks for the answer, but this is not a solution still the gameToCancel will have the wrong value, maybe because lastRoom is also global ? – Splendid Dec 24 '14 at 15:26
  • so gameToCancel is incorrect even before the timeout function? not sure what's your game logic, is this you trying to create the rooms automatically? can you have more than two people waiting before they start playing? – Xavier Dec 24 '14 at 15:41
  • Nope... but If I put it just before setTimeout it seems to work, just reading about JavaScript closures because I don't get this ;( – Splendid Dec 24 '14 at 16:12