Sunday, January 24, 2016

Multiplayer Card Game using WebSockets,Java Netty Server ,Cocos2d-x-HTML5 - Part 5

Game Server Source code overview



Now we are close to the point which we return with WebSocket response the new game states to the clients , but what are those "Game states" ?
it can be represented in many ways but in our case which is super simple the states will be kepet
in 2 levels .

First level is global game state and all things that are relevant to the general game like:
How many players are in the game
What is the scoring status
Who is the winner
How many cards left in the middle card deck

Second level of states are the ones that relevant to the players
Each player has several states , the states are updated during the game .


Player.java

This is the class that represent the player and the player states
Only the important code is explained all the rest of the code are getters and setter to the members
of The Player Class.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Player {
 private final static Logger LOG = LoggerManager.GetLogger(GameServerMain.class.getName());
 private LinkedList<String> PlayerCards;
 private String userName;
 private int Event;
 //Session channel
 private Channel channel;
 //Player Json massage
 private String playerJson;
 //the player which is active and has the turn
 private int activeplayerid;
 private int id;
 private String activecardid;
 private int registertionNum;
 private int winner;
 private String winnercards;
 private String deckcard;
 //mark the end game the value will be the winner id
 private int endgame;
  public Player()
 {
  this.channel = null;
  Init();
 } 
 public Player(Channel _channel)
 {
  this.channel = _channel;
  Init(); 
 }



  1. Line 3 : the cards that were dealt to the player , which are the half of the total cards in the page
  2. Line 4 : player user name.
  3. Line 5 : player event , the current event that the player is in.
  4. Line 7 : each player will hold the Netty channel in which it used to communicate from the client . this channel will be used to inform back to the client the state of the palyers and the state of the game.
  5. Line 9 : the json string that is constructed during the process of playing the game in the server , this json will be the one that used to send back to the player client .
  6. Line 11 : the id of the player that is currently active , that means the one that is playing its turn
  7. Line 12 : player unique id.
  8. Line 13 : the card that is played now 
  9. Line 14 : the order of which the player registered , this way it will be determined the player turn. 
  10. Line 15 : mark as winner of this game
  11. Line 16 : save the winner cards in this global game turn the format is:
    currentPlayerCardId+"_"+ prevCardId
  12. Line 17 : the card which is now on the middle card deck.
  13. Line 19 : Id of the player that win the game
  14. Lines 25 - 29 : Player Constructure that gets the player channel instance
    This channel instance will be used to communicate with the client .
GameResponseDispatcher.java
This class is responsible to build the JSON object that will be send back to the clients that are associated with this game .
The class have 2 main response functions as you remember we have 2 main events in the game
LOGIN and PLAY.
so the class will handle the response to the LOGIN event  :ResponseDispatcheLoginDone
and to the PLAY event : 
ResponseDispatchePlayDone


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
public class GameResponseDispatcher {
 private final static Logger LOG = LoggerManager.GetLogger(GameEventHandler.class.getName());
 private GameManager gameManager; 
 
 public GameResponseDispatcher(GameManager _gameManager)
 {
  this.gameManager = _gameManager;
   
 }
 public boolean ResponseDispatcheLoginDone(int  _playerId)
 {
  int currentPlayerId = _playerId;
  Player currentPlayer = this.gameManager.getPlayers().get(currentPlayerId);
  
  JSONObject currentPlayerJsonObj = setPlayerToJson(currentPlayer,
               currentPlayer.getEvent(),
               currentPlayer.getId());
  
  JSONObject currentPlayerJsonObj2 = setPlayerToJson(currentPlayer,
              currentPlayer.getEvent(),
              currentPlayer.getId());
   
  //build the other players json
     JSONArray currentPlayerArrayNewPlayers = new JSONArray();
     JSONArray ArrayCurrentPlayers = new JSONArray();
     ArrayCurrentPlayers.put(currentPlayerJsonObj2);
     Iterator<Entry<Integer, Player>> it = this.gameManager.getPlayers().entrySet().iterator();
     while (it.hasNext()) {
      @SuppressWarnings("rawtypes")
   Map.Entry pair = (Map.Entry)it.next();
         Player playerIt = ((Player)pair.getValue());
          
         if(currentPlayerId != playerIt.getId())
         {
          this.gameManager.getPlayers().get(playerIt.getId()).setEvent(Config.NEW_USER_LOGIN_DONE); 
          JSONObject playerJsonObjIt = setPlayerToJson(playerIt,
                     Config.NEW_USER_LOGIN_DONE,
                     playerIt.getId());
          JSONObject newPlayerForCurrent  = setPlayerToJson(playerIt,
                      Config.NEW_USER_LOGIN_DONE,
                      playerIt.getId());
          //to current    
          currentPlayerArrayNewPlayers.put(newPlayerForCurrent);
          //to others 
          playerJsonObjIt.put("players",ArrayCurrentPlayers);
          String jsonStr = playerJsonObjIt.toString();
          this.gameManager.getPlayers().get(playerIt.getId()).setPlayerJson(jsonStr);
         }
     }
     //current user array
     currentPlayerJsonObj.put("players",currentPlayerArrayNewPlayers);
     String jsonStr = currentPlayerJsonObj.toString();
     this.gameManager.getPlayers().get(currentPlayerId).setPlayerJson(jsonStr);
    return true;
 }
 
 public boolean ResponseDispatchePlayDone(int _playerId)
 {
  int currentPlayerId = _playerId;
  this.gameManager.getPlayers().get(currentPlayerId).setEvent(Config.PLAY_DONE);
  int newActivePlayer = this.gameManager.getNextActivePlayer(currentPlayerId);
  this.gameManager.getPlayers().get(currentPlayerId).setActiveplayerid(newActivePlayer);
  
  Player currentPlayer = this.gameManager.getPlayers().get(currentPlayerId);
  
  JSONObject currentPlayerJsonObj = setPlayerToJson(currentPlayer,
               currentPlayer.getEvent(),
               currentPlayer.getId());
  
  JSONObject currentPlayerJsonObj2 = setPlayerToJson(currentPlayer,
              currentPlayer.getEvent(),
              currentPlayer.getId());
  
  //build the other players json
     JSONArray currentPlayerArrayNewPlayers = new JSONArray();
     JSONArray ArrayCurrentPlayers = new JSONArray();
     ArrayCurrentPlayers.put(currentPlayerJsonObj2);
     Iterator<Entry<Integer, Player>> it = this.gameManager.getPlayers().entrySet().iterator();
     while (it.hasNext()) {
      @SuppressWarnings("rawtypes")
   Map.Entry pair = (Map.Entry)it.next();
         Player playerIt = ((Player)pair.getValue());
          if(currentPlayerId != playerIt.getId())
         {
          //update each user 
          this.gameManager.getPlayers().get(playerIt.getId()).setDeckcard(currentPlayer.getDeckcard());
          this.gameManager.getPlayers().get(playerIt.getId()).setEvent(Config.PLAY_DONE); 
          this.gameManager.getPlayers().get(playerIt.getId()).setActiveplayerid(newActivePlayer);
          JSONObject playerJsonObjIt = setPlayerToJson(playerIt,
                     Config.PLAY_DONE,
                     playerIt.getId());
          JSONObject newPlayerForCurrent  = setPlayerToJson(playerIt,
                      Config.PLAY_DONE,
                      playerIt.getId());
          currentPlayerArrayNewPlayers.put(newPlayerForCurrent);           
          //to others 
          playerJsonObjIt.put("players",ArrayCurrentPlayers);
          String jsonStr = playerJsonObjIt.toString();
          this.gameManager.getPlayers().get(playerIt.getId()).setPlayerJson(jsonStr);
          
         }        
     }
     //current user array
     currentPlayerJsonObj.put("players",currentPlayerArrayNewPlayers);    
     String jsonStr = currentPlayerJsonObj.toString();
     this.gameManager.getPlayers().get(currentPlayerId).setPlayerJson(jsonStr);
  return true;
 }
 @SuppressWarnings("unused")
 private JSONObject setPlayerToJson(final Player _player,final int event,
          final int _playerId)
 { 
  JSONObject _jsonPlayer = new JSONObject();
  _jsonPlayer.put("id",_playerId);
  _jsonPlayer.put("event",event);
  _jsonPlayer.put("username",_player.getUserName());
  _jsonPlayer.put("activecardid",_player.getActivecardid());
  _jsonPlayer.put("activeplayerid",_player.getActiveplayerid()); 
  _jsonPlayer.put("registertionnum",_player.getRegistertionNum()); 
  _jsonPlayer.put("winner",_player.getWinner()); 
  _jsonPlayer.put("deck",_player.getDeckcard()); 
  _jsonPlayer.put("endgame",_player.getEndgame()); 
  _jsonPlayer.put("winnercards",_player.getWinnercards()); 
  _jsonPlayer.put("numcardsleft",_player.getPlayerCards().size()); 
  return _jsonPlayer;
 }
}


  1. Lines 24 - 49 : Build the response back to the other players about the result of the LOGIN event, the other players will be notified
    about the new player login and also will be receiving the new player data .
    the response event in our super simple game will be with LOGIN_DONE.
  2. Lines 51 -53 : Build the response for the current player . in this case the current player will be
    notified about the other players state if any .
  3. Lines 74 -102 : Build the response back to the other players about the result of the Play event.
    new Event will be send back depending on the Game Play in our Super simple game
    it will return PLAY_DONE event.
  4. Lines 104 - 106 : Build the response for the current player . in this case the current player will be notified about the other players state if any with PLAY_DONE event .
  5. Lines 110 - 125 : Helper function to convert Player data to JSON object.

Now its time to do the Cocos2d-x client code review in the next port:
Multiplayer Card Game using WebSockets,Java Netty Server ,Cocos2d-x-HTML5 - Part 6


No comments:

Post a Comment