Friday, August 12, 2016

Part 4: Multiplayer WebSocket Game server written in C using libuv & libwebsockets & Cocos2d-x-HTML5

In this set of tutorials i will show you how to create the client side AKA the game .
Please dont expect to see "real" game . its just demo which demonstrate
I will use Cocos2d-x the HTML5 version which means you can take the code and compile it
To iOS and desktop and android see previous tutorial 
  1. Players registration
  2. Players movements
  3. All clients get updates from the server about other players 
  4. gem and bombs and collisions detection not implemented yet , but there is initial code there
    please ignore it for now.
After done creating the project copy the game files and overwrite the default files.
To run the game client in the browser we need to download some HTTP server.
it can be : Apache / tomcat / nginx what ever , i use this personal web server called Mongoose 
which is used in embed devices like cars .....
(yeah ... look in the "about" in the multimedia console in your car ).

I will not explain the very simple files which are just class's which hold data to be used in game .
Player.js: Player class representation.
Protocol.js : misc data structures and simple functions that are used in the game.
other files you can ignore

Lets dive in with the main files :
LayerController.js



 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
var websocketMng = null;
var LayerController = cc.Layer.extend({
 winsize:null,
    ctor:function () {
    this._super();
       this.winsize = cc.winSize;     
       return true;
    },
 onEnter:function () {
  this._super();
  websocketMng = new WebSocketNode(); 
   websocketMng.init();
  var logInlayer = new LogInlayer(websocketMng);
        var gameLayer = new GameLayer(websocketMng);
        var layer = new cc.LayerMultiplex(logInlayer,gameLayer);
        this.addChild(layer, 0);
 }
});

var LayerControllerScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layerController = new LayerController();
        this.addChild(layerController);
    }
});

Lines 2- 17 :  load the game first layer initialize the game objects
the websockets/LogInLayer/GameLayer class's
The base layer will be of type  "LayerMultiplex" in cocos2d-x it means it will load 2 scenes and switch between them .
The first Layer that will be load is The LogInlayer.

Lines 20 - 25: load the main Scene and add the layer controller as child.


Login.js
This class is the login module , the first screen which the player see when loging to the game
The player set its name , press "LogIn" button ,
Few things are happening behind the stage.

  1. The Connection to the WebSockets server is established 
  2. The Server creates the player session 
  3. The Player instance is created in the client 
  4. The next Layer is switched , this is the main game layer.



 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
 
 var loginSprite = null;
 var m_websocketMng = null;
 var winsize = null;

 var LogInlayer = cc.Layer.extend({
    
    ctor:function (_websocketMng) {
       this._super();
       m_websocketMng = _websocketMng;
       winsize = cc.winSize;       
       return true;
    },
    onEnter:function () {
        this._super();
        loginSprite = Login.initSprite();
        loginSprite.x = winsize.width / 2;
        loginSprite.y = winsize.height / 2;
        this.addChild(loginSprite, 0);
    }
});

var Login = cc.Sprite.extend({
    Editbox:null,
    EditBoxText:null,
    serverofflineLabel:0,
 ctor: function(){
        this._super();

        
    },
 onEnter:function () {
  this._super();
  this.initWithTexture(cc.textureCache.addImage(res.blank_png));
        this.setTextureRect(cc.rect(0,0,500,400));
        this.setAnchorPoint(0.5, 0.5);
        this.setColor(cc.color(0, 50,111,50)); 
        this.setXY(cc.winSize.width/2,cc.winSize.height/2);
          // Create the textfield
       this.Editbox = new cc.EditBox(cc.size(180,50), new cc.Scale9Sprite(res.yellow_edit_png));
       this.Editbox.setFont("Ariel",25);
        this.Editbox.setPlaceholderFontColor(cc.color(255, 0, 0));
        this.Editbox.setPlaceHolder("Enter Name:");
        this.Editbox.x = this.getContentSize().width/2;
        this.Editbox.y = this.getContentSize().height/2;
        this.Editbox.setDelegate(this);
        this.Editbox.setFontColor(cc.color(5, 4, 10));
        this.Editbox.setMaxLength(20);

        var LogIn_item = new cc.MenuItemFont("LogIn", this.onMenuLogInCallback,this);
        var menu = new cc.Menu(LogIn_item);
        menu.x = this.getContentSize().width/2;
        menu.y = (this.getContentSize().height/2) - this.Editbox.getContentSize().height;



        this.addChild(menu,1);
        this.addChild(this.Editbox,1);


        this.serverofflineLabel = new cc.LabelTTF("Server is down\ntry again in few seconds", "Arial",60);
        this.serverofflineLabel.x = cc.winSize.width/2;
        this.serverofflineLabel.y = (cc.winSize.height/2) - 200;
         
       
        this.parent.addChild(this.serverofflineLabel,3);
        this.serverofflineLabel.opacity = 0; 

 },
    editBoxTextChanged: function (editBox, text) {
        this.EditBoxText = text;
    },
    onMenuLogInCallback:function(sender){

        //send player name the server 
      this.serverofflineLabel.opacity = 0; 
      var msgProtocolObj = new MsgProtocol();
      msgProtocolObj.player_name = this.EditBoxText; 
      msgProtocolObj.end_player_pos_x=(winsize.width / 2).toString();
      msgProtocolObj.end_player_pos_y=(winsize.height / 2).toString();
      msgProtocolObj.status = 0;
      m_websocketMng.sendMassage(msgProtocolObj,this);
        
    },
    switchToGame:function()
    {
       this.parent.parent.switchTo(1);    
    },
 setXY:function (x,y) {
     this.x = x;
     this.y = y;
    }
});

Login.initSprite = function () {
    var login = new Login();
    return login;
};



Lines 33 - 38:initialize the background texture .
Lines 40 - 48:initialize the textbox
Lines 50 - 58:initialize the "LogIn" Button.
Lines 73 -83:In this callback function is triggered when pressing the "LogIn" button.
The MsgProtocol container is initialized and the player name and position and status is set.
Line:82:prepering the massage to be send to the server .
the game not switching right away to the GameLayer" it will first do validetion process of the new user in the WebSockets class ( the m_websocketMng object )
Lines 85 - 87: Switching to the "GameLayer scene" , this done after the player successfully validated in the server triggered from the WebSockets class  ( the m_websocketMng object) .


Continue to PART 5 client code where we examine Websockts.js


2 comments:

  1. Informative post you have shared here. The tutorial you have shared is very helpful in creating Multiplayer WebSocket Game server. You can buy the best Minecraft Host from Bisecthosting.com at affordable prices.

    ReplyDelete
  2. It is a nice information about the websocket game and its playing criteria for multi players. If you are also looking for Minecraft Hosting service, visit on meloncube.

    ReplyDelete

Note: Only a member of this blog may post a comment.