itty bittypresentation lrug

Download Itty bittypresentation lrug

If you can't read please download the document

Upload: tom-crinson

Post on 18-May-2015

830 views

Category:

Technology


0 download

DESCRIPTION

Presentation given to the London Ruby User Group (LRUG) and the Ipswich Ruby User Group (IPRUG) on a simple project I made called IttyBittyBoom.com which is an HTML5 based bomberman clone.

TRANSCRIPT

  • 1. IttyBittyBoom.com Cramp + Websockets = Awesome

2. What ? Attempt to play film here... 3. Why ? 4. How ? Drawing - canvas Network Requests - websockets Server - cramp 5. HTML5 Canvas Very Cool, Can do lots of cool things with it, Browser support is good (safari3.2, chrome3, firefox 3.0) 6. StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock WallBlockTall StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock StoneBlock 7. 8. Sprites canvas.getContext( '2d' ).drawImage( image, imgOffsetX, imgOffsetY,frameWidth,frameHeight, xPos, yPos,frameWidth,frameHeight) 9. Websockets Full Duplex communication channel over a single socket Javascript interface Cope with firewalls + proxies 10. //Create one: varsocket= new WebSocket ( 'ws://ittybittyboom.com/game' ); //Use it: socket . onopen = function ( evt ){alert ( "Connection open ..." ); }; socket . onmessage = function ( evt ) {alert ("Received Message:" + evt. data ); }; socket . onclose = function ( evt ) {alert ( "Connection closed." ); }; socket. send ("Any data you fancy"); 11. Where does Ittyuse them? Everywhere! 12. Run Away! 13. //Register Keypress switch ( event .which){ case 38 : MrJaba.Bomberman.me.setMovementDirection( 'up' );break ; case 40 : MrJaba.Bomberman.me.setMovementDirection( 'down' );break ; case 37 : MrJaba.Bomberman.me.setMovementDirection( 'left' );break ; case 39 : MrJaba.Bomberman.me.setMovementDirection( 'right' );break ; } //Run Every Clock Tick: update : function (){ if ( this .canMoveTo( newX, newY )){ MrJaba.Bomberman.GameClient.trigger( 'player_move' );} } //Send data to the server {"type":"player_move","uuid":"5a5c0a80-844f-012d-5d1f-001b63957646","data":{"x":"0","y":"105"}} socket. send (movement_data); 14. You can't givea bomb to a baby! 15. //Trigger the bombdrop on the game client MrJaba.Bomberman.GameClient.trigger( 'send_bomb_drop' ); //Send the Bomb drop messagesocket. send ( { "type" : "send_bomb_drop" , "uuid" : "5a5c0a80-844f-012d-5d1f-001b63957646" , "data" :{ "x" : "0" , "y" : "90" }} ); //The server will update it's map of players to bombs and issue an update every 5msec {type: "update_bombs" , positions:{"7fd93b20-8465-012d-5d20-001b63957646" :{ x:"0"y:"0"} }} //The socket receives all messages through this: socket . onmessage = function ( evt ){ vardata=JSON. parse (evt. data ) handleEvent ( data[ 'type' ], data ); }; 16. updateBombPositions :function ( positions ){ $ .each(positions,function (bombId, bomb){ if ( isNewBomb(bombId) ){MrJaba.Bomberman.bombs[bombId]= new Bomb (bombId, bomb)} }) }, //Event Handling Code calls this 17. Kill! Kill! Kill!Filthy bastards,Commies! Norman! Tea's Ready! Coming Dear! 18. //tick tick...boom MrJaba.Bomberman.detonate( this ,this .getTileX(),this .getTileY()); detonate : function ( bomb, tileX, tileY ){ deleteMrJaba.Bomberman.bombs[bomb.getId()]; MrJaba.Bomberman.GameClient.trigger( 'send_bomb_detonate' , bomb.getId()); bomb.toExplosion(); }, 19. Apparently Explosions Are...Unpleasant sendHotBurningDeath : function (){ varalreadyKilled= this .killed; this .tilesAround(this .getTileX(),this .getTileY(),function (tileX, tileY, direction, radius){ MrJaba.Bomberman.killPlayersAt( tileX, tileY, alreadyKilled ); });}, 20. Cramp! Asynchronous EventMachine based web framework 21. Asynchronous Event Driven Code Event Loop Request Handler Request Handler 22. Cramp::Controller::Action 23. class RootController< Cramp::Controller::Action on_start:send_socket def send_socket render File .open( "public/index.html" ,'r' ){ | f | f.readlines } finish end end 24. Anatomy of a cramp request Request: Blow the bloody doors off! initialize Initialize ResponseStart request Finish Request 25. Cramp::Controller::Websocket 26. class GameController< Cramp::Controller::Websocket on_data:receive_message def receive_message ( data ) message= JSON .parse(data) type=message[ 'type' ]uuid=message[ 'uuid' ] if Game .player_in_game?(uuid)||type== "register" update_last_message_time(uuid) self .send( "receive_ #{type} " , message, uuid) end end end 27. Example! { "type" : "send_bomb_drop" , "uuid" : "4bba07e0-846c-012d-5d29-001b63957646" , "data" :{ "x" : "0" , "y" : "0" }} Client: def receive_message ( data ) message= JSON .parse(data) type=message[ 'type' ]uuid=message[ 'uuid' ] if Game .player_in_game?(uuid)||type== "register" update_last_message_time(uuid) self .send( "receive_ #{type} " , message, uuid) end end Server: def receive_send_bomb_drop ( message, uuid ) position={ :x=> message[ 'data' ][ 'x' ],:y=> message[ 'data' ][ 'y' ]} Game .bomb_positions[uuid]=positionif ! uuid.nil? end 28. Again and Again and Again Recurring Actions are super easy in Cramp 29. periodic_timer:push_states ,:every=>0.05 def push_states data={ :type=>'update_positions' ,:positions=> game_states_for_connection}.to_json renderdata end def push_bombs if Game .bomb_positions.size> 0 data={ :type=>'update_bombs' ,:positions=>Game .bomb_positions}.to_json renderdata end end periodic_timer:push_bombs ,:every=>0.05 30. Alternatives? 31. Thank You's! 32. Game Over! Tom Crinson @MrJaba http://github.com/MrJaba/Websocket-Bomberman