Permalink
Browse files

Adds multiplayer base code.

  • Loading branch information...
1 parent 396ec71 commit b04e6a8cdf2769a4446bd775da29525c535a5933 @Overv committed Dec 28, 2011
Showing with 492 additions and 4 deletions.
  1. +6 −0 README.md
  2. +37 −0 js/blocks.js
  3. +6 −0 js/helpers.js
  4. +151 −0 js/network.js
  5. +44 −3 js/world.js
  6. BIN media/background.png
  7. +153 −0 multiplayer.html
  8. +33 −0 server.js
  9. +1 −1 singleplayer.html
  10. +57 −0 style/main.css
  11. BIN style/minecraftia.ttf
  12. +4 −0 style/minecraftia.txt
View
@@ -16,6 +16,8 @@ Structure
+ *media/* - Contains the graphics resources.
+ *style/* - Contains stylesheets for the HTML front-ends.
+ *singleplayer.html* - The front-end for the singleplayer client.
++ *multiplayer.html* - The front-end for the multiplayer client.
++ *server.js* - The Node.js server code.
Modules
---------------------
@@ -42,6 +44,10 @@ This is the module that takes care of visualizing the block structure in the wor
Finally there is also the module that handles everything related to the player of the game. Surprising, perhaps, is that it also deals with the physics and collision of the player. Less surprising is that it manages the material selector and input and responds to it in an update function, just like the physics module.
+**Network.js**
+
+This module makes it easy to synchronize a world between a server and connected clients. It comes with both a *Client* and *Server* class to facilitate all of your networking needs.
+
Typical game set-up
---------------------
View
@@ -17,19 +17,22 @@ BLOCK = {};
// Air
BLOCK.AIR = {
+ id: 0,
spawnable: false,
transparent: true
};
// Bedrock
BLOCK.BEDROCK = {
+ id: 1,
spawnable: false,
transparent: false,
texture: function( world, lightmap, lit, x, y, z, dir ) { return [ 1/16, 1/16, 2/16, 2/16 ]; }
};
// Dirt
BLOCK.DIRT = {
+ id: 2,
spawnable: true,
transparent: false,
selflit: false,
@@ -48,6 +51,7 @@ BLOCK.DIRT = {
// Wood
BLOCK.WOOD = {
+ id: 3,
spawnable: true,
transparent: false,
selflit: false,
@@ -64,6 +68,7 @@ BLOCK.WOOD = {
// TNT
BLOCK.TNT = {
+ id: 4,
spawnable: true,
transparent: false,
selflit: false,
@@ -80,6 +85,7 @@ BLOCK.TNT = {
// Bookcase
BLOCK.BOOKCASE = {
+ id: 5,
spawnable: true,
transparent: false,
selflit: false,
@@ -96,6 +102,7 @@ BLOCK.BOOKCASE = {
// Lava
BLOCK.LAVA = {
+ id: 6,
spawnable: false,
transparent: true,
selflit: true,
@@ -106,6 +113,7 @@ BLOCK.LAVA = {
// Plank
BLOCK.PLANK = {
+ id: 7,
spawnable: true,
transparent: false,
selflit: false,
@@ -116,6 +124,7 @@ BLOCK.PLANK = {
// Cobblestone
BLOCK.COBBLESTONE = {
+ id: 8,
spawnable: true,
transparent: false,
selflit: false,
@@ -126,6 +135,7 @@ BLOCK.COBBLESTONE = {
// Concrete
BLOCK.CONCRETE = {
+ id: 9,
spawnable: true,
transparent: false,
selflit: false,
@@ -136,6 +146,7 @@ BLOCK.CONCRETE = {
// Brick
BLOCK.BRICK = {
+ id: 10,
spawnable: true,
transparent: false,
selflit: false,
@@ -146,6 +157,7 @@ BLOCK.BRICK = {
// Sand
BLOCK.SAND = {
+ id: 11,
spawnable: true,
transparent: false,
selflit: false,
@@ -156,6 +168,7 @@ BLOCK.SAND = {
// Gravel
BLOCK.GRAVEL = {
+ id: 12,
spawnable: true,
transparent: false,
selflit: false,
@@ -166,6 +179,7 @@ BLOCK.GRAVEL = {
// Iron
BLOCK.IRON = {
+ id: 13,
spawnable: true,
transparent: false,
selflit: false,
@@ -176,6 +190,7 @@ BLOCK.IRON = {
// Gold
BLOCK.GOLD = {
+ id: 14,
spawnable: true,
transparent: false,
selflit: false,
@@ -186,6 +201,7 @@ BLOCK.GOLD = {
// Diamond
BLOCK.DIAMOND = {
+ id: 15,
spawnable: true,
transparent: false,
selflit: false,
@@ -196,6 +212,7 @@ BLOCK.DIAMOND = {
// Obsidian
BLOCK.OBSIDIAN = {
+ id: 16,
spawnable: true,
transparent: false,
selflit: false,
@@ -206,6 +223,7 @@ BLOCK.OBSIDIAN = {
// Glass
BLOCK.GLASS = {
+ id: 17,
spawnable: true,
transparent: true,
selflit: false,
@@ -216,6 +234,7 @@ BLOCK.GLASS = {
// Sponge
BLOCK.SPONGE = {
+ id: 18,
spawnable: true,
transparent: false,
selflit: false,
@@ -224,6 +243,18 @@ BLOCK.SPONGE = {
texture: function( world, lightmap, lit, x, y, z, dir ) { return [ 0/16, 3/16, 1/16, 4/16 ]; }
};
+// fromId( id )
+//
+// Returns a block structure for the given id.
+
+BLOCK.fromId = function( id )
+{
+ for ( var mat in BLOCK )
+ if ( typeof( BLOCK[mat] ) == "object" && BLOCK[mat].id == id )
+ return BLOCK[mat];
+ return false;
+}
+
// pushVertices( vertices, world, lightmap, x, y, z )
//
// Pushes the vertices necessary for rendering a
@@ -397,4 +428,10 @@ BLOCK.pushPickingVertices = function( vertices, x, y, z )
[ x + 1, y + 1, z + 1, 1, 1, color.r, color.g, color.b, 6/255 ],
[ x + 1, y, z + 1, 0, 0, color.r, color.g, color.b, 6/255 ]
);
+}
+
+// Export to node.js
+if ( typeof( exports ) != "undefined" )
+{
+ exports.BLOCK = BLOCK;
}
View
@@ -87,4 +87,10 @@ function rectRectCollide( r1, r2 )
if ( r2.x2 > r1.x1 && r2.x2 < r1.x2 && r2.y2 > r1.y1 && r2.y2 < r1.y2 ) return true;
if ( r2.x1 > r1.x1 && r2.x1 < r1.x2 && r2.y2 > r1.y1 && r2.y2 < r1.y2 ) return true;
return false;
+}
+
+// Export to node.js
+if ( typeof( exports ) != "undefined" )
+{
+ exports.Vector = Vector;
}
View
@@ -0,0 +1,151 @@
+// ==========================================
+// Network
+//
+// This class manages the connection between the client and the
+// server and everything involved.
+// ==========================================
+
+// ==========================================
+// Client
+// ==========================================
+
+// Constructor( socketio )
+//
+// Creates a new client using the specified socket interface.
+
+function Client( socketio )
+{
+ this.io = socketio;
+ this.eventHandlers = {};
+}
+
+// connect( uri, nickname )
+//
+// Connect to a server with the specified nickname.
+
+Client.prototype.connect = function( uri, nickname )
+{
+ var socket = this.socket = this.io.connect( uri );
+ this.nickname = nickname;
+
+ var s = this;
+ socket.on( "connect", function() { s.onConnection(); } );
+ socket.on( "world", function( data ) { s.onWorld( data ); } );
+ socket.on( "spawn", function( data ) { s.onSpawn( data ); } );
+}
+
+// on( event, callback )
+//
+// Hooks an event.
+
+Client.prototype.on = function( event, callback )
+{
+ this.eventHandlers[event] = callback;
+}
+
+// onConnection()
+//
+// Called when the client has connected.
+
+Client.prototype.onConnection = function()
+{
+ if ( this.eventHandlers["connect"] ) this.eventHandlers.connect();
+
+ this.socket.emit( "nickname", { nickname: this.nickname } );
+}
+
+// onWorld( data )
+//
+// Called when the server has sent the world.
+
+Client.prototype.onWorld = function( data )
+{
+ // Create world from string representation
+ var world = this.world = new World( data.sx, data.sy, data.sz );
+ world.createFromString( data.blocks );
+
+ if ( this.eventHandlers["world"] ) this.eventHandlers.world( world );
+}
+
+// onSpawn( data )
+//
+// Called when the local player is spawned.
+
+Client.prototype.onSpawn = function( data )
+{
+ // Set spawn point
+ this.world.spawnPoint = new Vector( data.x, data.y, data.z );
+
+ if ( this.eventHandlers["spawn"] ) this.eventHandlers.spawn();
+}
+
+// ==========================================
+// Server
+// ==========================================
+
+// Constructor( socketio )
+//
+// Creates a new server listening for clients using the specified
+// socket interface.
+
+function Server( socketio )
+{
+ var io = this.io = socketio.listen( 3000 );
+ var s = this;
+
+ io.set( "log level", 1 );
+ io.sockets.on( "connection", function( socket ) { s.onConnection( socket ); } );
+}
+
+// setWorld( world )
+//
+// Assign a world to be networked.
+
+Server.prototype.setWorld = function( world )
+{
+ this.world = world;
+}
+
+// onConnection( socket )
+//
+// Called when a new client has connected.
+
+Server.prototype.onConnection = function( socket )
+{
+ // Hook events
+ var s = this;
+ socket.on( "nickname", function( data ) { s.onNickname( socket, data ) } );
+}
+
+// onNickname( socket, nickname )
+//
+// Called when a client has sent their nickname.
+
+Server.prototype.onNickname = function( socket, data )
+{
+ // Associate nickname with socket
+ socket.set( "nickname", data.nickname );
+
+ // Send world to client
+ var world = this.world;
+
+ socket.emit( "world", {
+ sx: world.sx,
+ sy: world.sy,
+ sz: world.sz,
+ blocks: world.toNetworkString()
+ } );
+
+ // Spawn client
+ socket.emit( "spawn", {
+ x: world.spawnPoint.x,
+ y: world.spawnPoint.y,
+ z: world.spawnPoint.z
+ } );
+}
+
+// Export to node.js
+if ( typeof( exports ) != "undefined" )
+{
+ exports.Server = Server;
+}
Oops, something went wrong.

0 comments on commit b04e6a8

Please sign in to comment.