Sign in to follow this  
mobubby

Create multiplayer games rapidly using MoBubby

Recommended Posts

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

@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 !!

Share this post


Link to post
Share on other sites

@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" });

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.