node meetup feb_20_12

19
Hello I’m Jafar http://jaf.ar.com Multiplayer Worlds with Node.js + HTML

Upload: jafar104

Post on 01-Jul-2015

208 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Node meetup feb_20_12

Hello I’m Jafar

http://jaf.ar.com

Multiplayer Worldswith

Node.js + HTML

Page 2: Node meetup feb_20_12

RED INTERACTIVE

2009 - I Love Flash

2010 - Steve Jobs Hates Flash

2011 - Flash dies slow death... :(

http://FF0000

Inspired By

Page 3: Node meetup feb_20_12

My Website is....

Not perfect....

Probably really hackable...

Still using globals....

Chat room needs filters...

Server not authoritave

Page 4: Node meetup feb_20_12

Works well in Chrome 19 ! Download Chrome Canary

Worked well in Chrome 16

Chrome updates to 17......bugs come back

(image flicker)

http://www.eclipse.org/forums/index.php/mv/tree/262108/#page_top

Might be a cache issue....Might be a Mac thing...Maybe Wifi on Mac thing

OH NO BUGS IN CHROME!

Page 5: Node meetup feb_20_12

So Screw IE9 or Lower

Although Socket.io does work on browsers without

web sockets

IE10 pretty good....

MICROSOFT SAYS NO WEBSOCKETS

and Opera and Safari

(too choppy)

Microsoft Changes Their Mind

Page 6: Node meetup feb_20_12

STACK

Node.js - server

Socket.IO - cross browser sockets

Now.js - namespace, easy chat rooms

jQuery - front end stuff

Express - static files, pages

Page 7: Node meetup feb_20_12

//ANIMATION LOOPwindow.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame })();

World.js

//MAIN LOOP(function animloop(){

moveCamera(); gravity(); floor(); myPlayer(); movePlayers(); controlPlayer(); moveLasers(); otherLasers();

requestAnimFrame(animloop);

})();

Page 8: Node meetup feb_20_12

Canvas too slow for a large mapJUST USE HTML DIV’s

Because when you draw on canvas you must also clear each move and each pixel

3000 x 3000 = 9 Million px/sec

http://craftyjs.com/demos/tutorial/tutorial.html

“Tip: DOM is usually always faster than canvas....”

3000px 1920 x 1024

3000

px

Page 9: Node meetup feb_20_12

#myPlayer

.player

in relation to the DOM WindowWhere is My Player?

.player .player

.player .player

var PosX = $('#myPlayer').offset().left - $(window).scrollLeft();

if( PosX < 50 || PosX > (winW - 50) )

window.scrollBy(x,y);

//within 50px of window

//scroll the window to keep player in view

Page 10: Node meetup feb_20_12

//PULL PLAYERSeveryone.now.pullPlayers = function(id,x,y,dir,mov,flo,skin){

actors[id] = {x:x, y:y, dir:dir, mov:mov,flo:flo,skin:skin};

var playerUpdate = {}; playerUpdate = {id:id,x:x,y:y,dir:dir,mov:mov,flo:flo,skin:skin}; everyone.now.showPlayers(playerUpdate); };

var players = {};

CLIENT

SERVER

CLIENT

id, x, y, direction, moving, floor, skin

>>>> LOOP THE PLAYERS OBJECT

//SHOW PLAYERS now.showPlayers = function(plyr) { players[plyr.id] = {x:plyr.x, y:plyr.y, dir:plyr.dir, mov:plyr.mov,flo:plyr.flo,skin:plyr.skin}; }

//KEY DOWN function kdRight(){ now.pullPlayers(now.core.clientId,player.x, player.y, 0,1,floor_y,skin_num); }

Animation Loop

Page 11: Node meetup feb_20_12

//SHOW PLAYERS now.showPlayers = function(plyr) { players[plyr.id] = {x:plyr.x, y:plyr.y, dir:plyr.dir, mov:plyr.mov,flo:plyr.flo,skin:plyr.skin}; }

//MOVE PLAYERSfunction movePlayers(){ //FOR LOOP for(var i in players) { //REMOVE $(".player[rel='" + i + "']").remove(); //ADD $('#Players').append('<div class="player" rel="' + i + '"></div>'); >>>>IF MOVING (next page) >>>>ELSE STANDING STILL (next page) } }

Animation Loop

Page 12: Node meetup feb_20_12

//MOVING if(players[i].mov == 1) { //LEFT if(players[i].dir == 1) { players[i].x--; $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); $(".player[rel='"+ i +"']").css('background-image',img_walk_l); //RIGHT } else if(players[i].dir == 0){ players[i].x ++; $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); $(".player[rel='"+ i +"']").css('background-image',img_walk_r); } else { $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); $(".player[rel='"+ i +"']").css('background-image',img_front); } //STANDING STILL } else { //LEFT if(players[i].dir == 1) { $(".player[rel='"+ i +"']").css('background-image',img_l); $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); //RIGHT } else if (players[i].dir == 0){ $(".player[rel='"+ i +"']").css('background-image',img_r); $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); //BACK } else if (players[i].dir == 'b'){ $(".player[rel='"+ i +"']").css('background-image',img_back); $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); //FRONT } else { $(".player[rel='"+ i +"']").css('background-image',img_front); $(".player[rel='"+ i +"']").css('left', players[i].x ); $(".player[rel='"+ i +"']").css('top', players[i].y ); } //END MOV }

Wait What About My Player

Page 13: Node meetup feb_20_12

Wait What About My Player

//MY PLAYERfunction myPlayer() { if ( movement && leftKey ) { player.x --; $('#player').css('left',player.x ); } else if ( movement && rightKey ) { player.x ++; $('#player').css('left',player.x ); } else { $('#player').css('left',player.x ); } //END FUNC }

//GLOBALS--movement --leftKey--rightKey

Page 14: Node meetup feb_20_12

GRAVITY LOOPWe use the global object “players{}”

//GRAVITYfunction gravity() { //MY PLAYER if ( player.y !== floor_y ) {

player.y ++; player.y ++; $('#player').css('top',player.y ); } //FOR LOOP for (var i in players) { //IN THE AIR if( i === now.core.clientId && players[i].y !== floor_y ) {

players[i].y++; players[i].y++; $(".player[rel='"+ i +"']").css('top', players[i].y );

} else if ( i !== now.core.clientId && players[i].y !== players[i].flo) {

players[i].y++; players[i].y++; $(".player[rel='"+ i +"']").css('top', players[i].y );

} else { //do nothing }

}

}

now.pullPlayers(now.core.clientId,player.x, player.y, direction, movement, floor_y,skin_num)

Page 15: Node meetup feb_20_12

//FLOORfunction floor(){

//FLOOR 1 if(player.y == floor1 && player.x <= 810 && player.x >= 100){ floor_y = floor1; player.y = floor1; } //FALLING if ( player.y == floor1 - 2 && player.x <= 810 && player.x >= 100) { floor_y = floor1; now.pullPlayers(); } //JUMPING if ( player.y == floor1 + 2) { now.pullPlayers(); }

//END FUNC}

FLOOR LOOPchanging players floor position

**PULL PLAYERS**

now.pullPlayers(now.core.clientId,player.x, player.y, direction, movement, floor_y,skin_num)

Page 16: Node meetup feb_20_12

LASERS LOOP

//FIRE LASERSeveryone.now.fireLasers = function(id,x,y,dir){

var laserUpdate = {}; laserUpdate = {id:id,x:x,y:y,dir:dir}; everyone.now.showLasers(laserUpdate);

};

//SHOW LASERSnow.showLasers = function(laz) { if(laz.id != now.core.clientId) { other_lasers.push( [laz.x, laz.y, laz.dir] ); } }

var lasers = []; var other_lasers = [];var laser_v = 27;

$(window).keyup(function(e) {

case 191: if(!$(‘.placeHolder’).is(“:focus”)) { now.fireLasers(now.core.clientId,player.x + 12, player.y + 12, direction); lasers.push([player.x + 12, player.y + 12, direction]); e.preventDefault(); } break;}

VARIABLES

CLIENT

SERVER

CLIENT

>>>> MOVE AND DRAW LASERS

Page 17: Node meetup feb_20_12

Function to Draw Our Lasers

//LASERS function drawLasers (x, y, dir) { if( dir == 0 || dir == 1) { game.clearRect(x,y,-65,2); game.clearRect(x, y,65,2); game.fillStyle = '#f00'; game.fillRect(x, y,10,1); } else { game.clearRect(x,y,-2,65); game.clearRect(x, y,2,65); game.fillStyle = '#f00'; game.fillRect(x, y,1,10); } }

Page 18: Node meetup feb_20_12

function moveLasers() { for(var i = 0; i < lasers.length; i++) { //IF WITHIN BOUNDS if(lasers[i][0] < player.x + w && lasers[i][0] > player.x - w && lasers[i][1] > 1500 ) { if(lasers[i][2] == 1) { lasers[i][0] -= laser_v; } else if(lasers[i][2] == 0){ lasers[i][0] += laser_v; } else { lasers[i][1] -= laser_v; } drawLasers(lasers[i][0], lasers[i][1],lasers[i][2]); } else if(lasers[i][0] > player.x + w + 1 || lasers[i][0] < player.x - w +1){ lasers.splice(i,1); } else if(lasers[i][1] < 0 ){ lasers.splice(i,1); } else { //do nothing } } }

MOVE LASERS

Page 19: Node meetup feb_20_12

function otherLasers() { for(var i = 0; i < other_lasers.length; i++) { if(other_lasers[i][0] < player.x + w && other_lasers[i][0] > player.x - w ) { if(other_lasers[i][2] == 1) { other_lasers[i][0] -= laser_v; } else if(other_lasers[i][2] == 0){ other_lasers[i][0] += laser_v; } else { other_lasers[i][1] -= laser_v; } drawLasers(other_lasers[i][0], other_lasers[i][1],other_lasers[i][2]); } else { other_lasers.splice(i,1); } } }

OTHER PLAYERS LASERS