mobubby Posted January 9, 2018 Share Posted January 9, 2018 Hello, I am the creator of MoBubby. MoBubby is a new, free, multiplayer service. I created MoBubby so that indie developers and hobbyists can create online, multiplayer games. All for free, and without needing their own server. Adding multiplayer to a game using MoBubby takes mere minutes. Here's a simple tutorial on how to create a multiplayer, plane game using Phaser.io and MoBubby. To begin this tutorial, let's link to the Phaser.io and MoBubby files <link rel="stylesheet" href="https://mobubby.com/resource/connect.css"> <script src="https://mobubby.com/resource/connect.js"></script> <script src="https://mobubby.com/demo/js/phaser.min.js"></script> Next, we'll create a simple button. When clicked, the user will be prompted to loggin to MoBubby <button id = "buttonLogin">Login</button> Naturally, we'll need a holder for the Phaser.io canvas <div id = 'phaser-div'></div> Now we can get into some Javascript. Let's create some global variables. var game = undefined; var player = undefined; var others = {}; var loaded = false; The game variable holds our Phaser.io engine. The player variable will hold the current player's plane. The others variable will hold the planes for all other players. Lastly, the loaded variable will hold true once the game is loaded. Next, we'll create our preload procedure. function preload() { game.load.image('background', 'images/background.png'); game.load.image('plane-blue', 'images/plane-blue.png'); game.load.image('plane-red', 'images/plane-red.png'); this.scale.scaleMode = Phaser.ScaleManager.RESIZE; this.scale.pageAlignVertically = true; } This is a standard Phaser.io procedure. It simply loads our graphical assets and sets-up some scaling options. Now we can code our create procedure. function create() { game.physics.startSystem(Phaser.Physics.ARCADE); tileSprite = game.add.tileSprite(0, 0, 1600, 1200, 'background'); player = game.add.sprite(128, 128, 'plane-red'); player.anchor.setTo(0.5, 0.5); // Enable Arcade Physics for the sprite game.physics.enable(player, Phaser.Physics.ARCADE); // Tell it we don't want physics to manage the rotation player.body.allowRotation = false; window.setInterval(function(){ moBubbySend({ "name": moBubbyUserName(), "action": "move", "x": player.x, "y": player.y, "angle": player.angle }); }, 100); loaded = true; } This procedure creates our background, player, and a timer that relays the current player's coordinates to all other players. This data is sent via JSON. Note the action field. Its value is set to "move". As you'll see in a bit, if the user is ever disconnected, we'll send a value of "exit". Now we'll create our update procedure. function update() { player.rotation = game.physics.arcade.moveToPointer(player, 60, game.input.activePointer, 500); } This procedure simply moves the plane toward the mouse (or finger on mobile devices). Simply because Phaser.io requires one, we'll create an empty render procedure. function render() { } The final segment of our code will handle the multiplayer. This includes calling moBubbyConnect and passing it 4 arguments: the maximum number of players the procedure to be executed once the current player is connected the procedure to be executed whenever the current player is disconnected the procedure to be executed whenever the current player receives data window.onload = function(){ document.getElementById("buttonLogin").onclick = function(){ moBubbyConnect( 5 ,function(event){ document.getElementById("buttonLogin").style.display = "none"; game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-div', { preload: preload, create: create, update: update, render: render }); } ,function(event){ moBubbySend({ "name": moBubbyUserName(), "action": "exit" }); } ,function(event){ var data = JSON.parse(event.data); if(loaded == false) return; if(data.action == "move"){ if (!others.hasOwnProperty(data.name)) others[data.name] = game.add.sprite(128, 128, 'plane-blue'); others[data.name].x = data.x; others[data.name].y = data.y; others[data.name].angle = data.angle; }else if(data.action == "exit"){ if (others.hasOwnProperty(data.name)){ others[data.name].destroy(); delete others[data.name]; } } } ); }; }; As the first argument sent indicates, this demo allows up to 5 players. The next argument is the procedure that is executed once the current player connects. During which procedure we create our Phaser.io game using the previously coded preload, create, update, and render procedures. The third argument is the procedure that is executed once the current player is disconnected. In our case, a simple "exited", JSON message is sent to the other players. The fourth and final argument is the procedure executed whenever the current player receives data. In this procedure we do one of two things: in the instance the action value is "move", we update the specified player's plane in the instance the action value is "exit", we remove the specified player's plane Just like that, we have a simple, multiplayer demo. You can download a copy of this demo here. Please let me know (via this thread) if you have any questions, or encounter any issues. Quote Link to comment Share on other sites More sharing options...
PsichiX Posted January 9, 2018 Share Posted January 9, 2018 websockets can use binary messages, which are smaller and faster to transfer. mobubby 1 Quote Link to comment Share on other sites More sharing options...
mobubby Posted January 9, 2018 Author Share Posted January 9, 2018 Agreed. They are quite a bit more complicated, though. The data has to be packed into an array buffer and then unpacked. JSON and XML usually have a more reasonable learning curve. Quote Link to comment Share on other sites More sharing options...
Gio Posted January 9, 2018 Share Posted January 9, 2018 Just a small suggestion if I may. From an API point of view, this alone moBubbySend("{\"name\": \"" + moBubbyUserName() + "\", \"action\": \"exit\"}"); would put me off using it. Can you consider, instead: moBubbySend({name: moBubbyUserName(), action: 'exit'}) and then, internally, JSON.stringify that. PsichiX and mobubby 2 Quote Link to comment Share on other sites More sharing options...
PsichiX Posted January 9, 2018 Share Posted January 9, 2018 exactly what @Gio said, this is even better learning curve ;p about websockets: you can provide binary communication as option for more experienced developers, who focus on best performance mobubby 1 Quote Link to comment Share on other sites More sharing options...
mobubby Posted January 9, 2018 Author Share Posted January 9, 2018 @Gio Implementing the sending of JSON objects seems simple enough. I'll implement this procedure as soon as possible. @PsichiX I agree that binary communication is also another great feature. I need to get started on that. Thank you both for your input !! Quote Link to comment Share on other sites More sharing options...
mobubby Posted January 10, 2018 Author Share Posted January 10, 2018 @Gio I've updated moBubbySend to support objects. If moBubbySend is passed a string, the string will simply be sent. However, if moBubbySend is passed an object, the object is stringified and then sent. The above tutorial has been updated. The following 2 examples are now valid. moBubbySend({ "name": moBubbyUserName(), "action": "move", "x": player.x, "y": player.y, "angle": player.angle }); moBubbySend({ "name": moBubbyUserName(), "action": "exit" }); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.