Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Como el Desarrollo deVideojuegos puede ayudarnosa volvernos mejoresDesarrolladores WebM. Andrés Pagella (@mapagella) - htt...
< 2003
< 2003
< 2003
< 2003
~2000
2004
2005
Mac OSX 10.4 Tiger       2005
2007
2007
APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?)
APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?)   Si anda bien en este, anda bien en todos.
PARA TENER EN CUENTA...
PARA TENER EN CUENTA...Tiempo de Carga
PARA TENER EN CUENTA...   Tiempo de CargaVelocidad de Rendering
PARA TENER EN CUENTA...   Tiempo de CargaVelocidad de RenderingResponsividad de la UI
Video Juegos
Video Juegos
OPTIMIZACIÓN DE TIEMPOS DE CARGA
OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latencia
OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latenciaAcomodar la mayor cantidad de información      en ...
LAZY LOAD
Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)                                        +
Spritesheets / Soundsheets (AKA Audio Sprites)       Sound Manager 2 (Legacy support con fallbacks)       http://www.schil...
Heightmaps
Heightmaps
Heightmaps
Heightmaps
Heightmaps       map.gif (150 bytes)
Heightmaps       map.gif (150 bytes)
Heightmaps
Heightmapsvar Tile = {! WALL: {! ! index: 0,! ! identifier: ffffff! },! RED: {! ! index: 1,! ! identifier: 00ff! },! BLUE:...
Heightmaps                           Level.prototype.loadMap = function (map) {                                // Create a...
Otras consideraciones...
Otras consideraciones...        Background LoadingOptimizaciones del lado del Servidor    Optimizaciones de Imágenes      ...
OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA
OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA    Extremadamente “caras” en dispositivos móviles
OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA    Extremadamente “caras” en dispositivos móviles           Consejo: Pe...
VIEWPORT
VIEWPORT
for (var i = 0; i < 3; ++i) {               for (var j = 0; j < 3; ++j) {VIEWPORT           pintarCelda();               }...
VIEWPORT
for (var i = 0; i < 3; ++i) {               for (var j = 0; j < 3; ++j) {                   if (dentro_de_viewport()) {VIE...
VIEWPORT
1.000.000 FilasVIEWPORT             x           1.000.000 Columnas
var scroll = { x: 0, y: 0 },!   tile = { width: 32, height: 32 },!   tileMap = inicializarTileMap();function pintar(c, can...
Dirty Rectangles / ATR (Adaptive Tile Refresh)
Dirty Rectangles / ATR (Adaptive Tile Refresh)
Layering, Compositing, etc...
Layering, Compositing, etc...Static Layer
Layering, Compositing, etc...Static Layer                   Animated Layer
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Layering, Compositing, etc...
Responsividad de la UI
Usar HTML/CSS para dibujar la GUI
Usar HTML/CSS para dibujar la GUIRovio/Google (Angry Birds GWT port), I’m looking at you...
Usar HTML/CSS para dibujar la GUI
Usar HTML/CSS para dibujar la GUIZeptoLabs/Microsoft (Cut the Rope), yay!
Usar HTML/CSS para dibujar la GUI
Usar HTML/CSS para dibujar la GUIAutodesk Scaleform GFX (UDK) - Adobe Flash/AS2
Object Pooling// Maximum number of sound objects allowed in the poolvar MAX_PLAYBACKS = 3;var globalVolume = 0.3;function ...
Object PoolingSoundUtil.prototype.getAudioObject = function(){!      if (this.audioObjects.length === 0) {!      !      va...
Evitar instanciaciones en loops// Pseudocódigowhile (activo()) {! var obj = new Ejemplo(); // Ouch! obj.configurar();! obj...
Mantener la lógica separada de la rutina de pintado// Pseudocodigofunction actualizarVista(){! if (pasaAlgo()) {! ! for (v...
Mantener la lógica separada de la rutina de pintado// Pseudocodigofunction ejecutarLogica(){! if (pasaAlgo()) {! ! for (va...
Tablas de Valores     Math.sqrt(<número>)Math.pow(<número>, <potencia>)
Tablas de Valores
Tablas de Valores
Tablas de Valoresvar raizCuadrada = arrayRaices[<numero>];
Ser conciente de la memoria utilizada por un objetogrilla[114422, 1233] = new ObjetoEjemplo();
Ser conciente de la memoria utilizada por un objeto  grilla[114422, 1233] = new ObjetoEjemplo();https://github.com/andresp...
"Es divertido hacer lo imposible."           Walt Disney
¡Gracias!@mapagella - https://github.com/andrespagella/ - http://www.andrespagella.com
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por And...
Upcoming SlideShare
Loading in …5
×

JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos a volvernos mejores Desarrolladores Web por Andres Pagella

1,268 views

Published on

Una charla explicativa de como podemos transladar ténicas y patrones de diseño utilizado en el desarrollo de videojuegos en el ámbito del desarrollo web apuntado a dispositivos móviles.

  • Be the first to comment

  • Be the first to like this

JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos a volvernos mejores Desarrolladores Web por Andres Pagella

  1. 1. Como el Desarrollo deVideojuegos puede ayudarnosa volvernos mejoresDesarrolladores WebM. Andrés Pagella (@mapagella) - http://www.andrespagella.com
  2. 2. < 2003
  3. 3. < 2003
  4. 4. < 2003
  5. 5. < 2003
  6. 6. ~2000
  7. 7. 2004
  8. 8. 2005
  9. 9. Mac OSX 10.4 Tiger 2005
  10. 10. 2007
  11. 11. 2007
  12. 12. APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?)
  13. 13. APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?) Si anda bien en este, anda bien en todos.
  14. 14. PARA TENER EN CUENTA...
  15. 15. PARA TENER EN CUENTA...Tiempo de Carga
  16. 16. PARA TENER EN CUENTA... Tiempo de CargaVelocidad de Rendering
  17. 17. PARA TENER EN CUENTA... Tiempo de CargaVelocidad de RenderingResponsividad de la UI
  18. 18. Video Juegos
  19. 19. Video Juegos
  20. 20. OPTIMIZACIÓN DE TIEMPOS DE CARGA
  21. 21. OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latencia
  22. 22. OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latenciaAcomodar la mayor cantidad de información en el menor espacio posible
  23. 23. LAZY LOAD
  24. 24. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  25. 25. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  26. 26. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  27. 27. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites) +
  28. 28. Spritesheets / Soundsheets (AKA Audio Sprites) Sound Manager 2 (Legacy support con fallbacks) http://www.schillmania.com/projects/soundmanager2/ Zynga Jukebox (Optimizado para Mobile) https://github.com/zynga/jukebox
  29. 29. Heightmaps
  30. 30. Heightmaps
  31. 31. Heightmaps
  32. 32. Heightmaps
  33. 33. Heightmaps map.gif (150 bytes)
  34. 34. Heightmaps map.gif (150 bytes)
  35. 35. Heightmaps
  36. 36. Heightmapsvar Tile = {! WALL: {! ! index: 0,! ! identifier: ffffff! },! RED: {! ! index: 1,! ! identifier: 00ff! },! BLUE: {! ! index: 2,! ! identifier: ff00! }}
  37. 37. Heightmaps Level.prototype.loadMap = function (map) { // Create an HTML5 Canvas object, define the 2D Context and create an empty array to store the tileData var c = this.c, cnv = document.createElement("canvas"), ctx = cnv.getContext("2d"), idata = null, tileData = []; // Set the size of the map this.mapData.size = { x: map.width, y: map.height }var Tile = { // Adjust the size of the canvas to match the size of the image! WALL: { cnv.width = map.width; cnv.height = map.height;! ! index: 0, // Paint the map on the new canvas! ! identifier: ffffff ctx.drawImage(map, 0, 0);! }, // Read the pixel data array idata = ctx.getImageData(0, 0, cnv.width, cnv.height);! RED: { // Start cycling through all the pixels of the image! ! index: 1, for (var i = 0, my = map.height; i < my; ++i) { for (var j = 0, mx = map.width; j < mx; ++j) {! ! identifier: 00ff // Convert the RGB values to hex var r = (idata.data[((mx * i) + j) * 4]).toString(16),! }, g = (idata.data[((mx * i) + j) * 4 + 1]).toString(16), b = (idata.data[((mx * i) + j) * 4 + 2]).toString(16),! BLUE: { hex = r + g + b;! ! index: 2, tileData[j] = tileData[j] || [];! ! identifier: ff00 switch(hex) { case Tile.WALL.identifier:! } tileData[j][i] = Tile.WALL.index; break;} case Tile.BLUE.identifier: tileData[j][i] = Tile.BLUE.index; this.mapData.base.blue = {x: j, y: i}; break; case Tile.RED.identifier: tileData[j][i] = Tile.RED.index; this.mapData.base.red = {x: j, y: i}; break; } } } // Replace the level data with the values of the tileData matrix. this.mapData.data = tileData; };
  38. 38. Otras consideraciones...
  39. 39. Otras consideraciones... Background LoadingOptimizaciones del lado del Servidor Optimizaciones de Imágenes Templates etc.
  40. 40. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA
  41. 41. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA Extremadamente “caras” en dispositivos móviles
  42. 42. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA Extremadamente “caras” en dispositivos móviles Consejo: Pensar “masivamente”
  43. 43. VIEWPORT
  44. 44. VIEWPORT
  45. 45. for (var i = 0; i < 3; ++i) { for (var j = 0; j < 3; ++j) {VIEWPORT pintarCelda(); } }
  46. 46. VIEWPORT
  47. 47. for (var i = 0; i < 3; ++i) { for (var j = 0; j < 3; ++j) { if (dentro_de_viewport()) {VIEWPORT pintarCelda(); } } }
  48. 48. VIEWPORT
  49. 49. 1.000.000 FilasVIEWPORT x 1.000.000 Columnas
  50. 50. var scroll = { x: 0, y: 0 },! tile = { width: 32, height: 32 },! tileMap = inicializarTileMap();function pintar(c, canvas) {! c.fillStyle = #FFFFFF;! c.fillRect (0, 0, canvas.width, canvas.height);! c.fillStyle = #000000;! var startRow = Math.floor(scroll.x / tile.width),! ! startCol = Math.floor(scroll.y / tile.height),! ! rowCount = startRow + Math.floor(canvas.width / tile.width) + 1,! ! colCount = startCol + Math.floor(canvas.height / tile.height) + 1;! for (var row = startRow; row < rowCount; ++row) {! ! for (var col = startCol; col < colCount; ++col) {! ! ! var tilePositionX = tile.width * row, tilePositionY = tile.height * col;! ! ! tilePositionX -= scroll.x;! ! ! tilePositionY -= scroll.y;! ! ! if (dentro_de_viewport()) {! ! ! ! pintarCelda();! ! ! }! ! }! }}
  51. 51. Dirty Rectangles / ATR (Adaptive Tile Refresh)
  52. 52. Dirty Rectangles / ATR (Adaptive Tile Refresh)
  53. 53. Layering, Compositing, etc...
  54. 54. Layering, Compositing, etc...Static Layer
  55. 55. Layering, Compositing, etc...Static Layer Animated Layer
  56. 56. Layering, Compositing, etc...
  57. 57. Layering, Compositing, etc...
  58. 58. Layering, Compositing, etc...
  59. 59. Layering, Compositing, etc...
  60. 60. Layering, Compositing, etc...
  61. 61. Layering, Compositing, etc...
  62. 62. Layering, Compositing, etc...
  63. 63. Layering, Compositing, etc...
  64. 64. Responsividad de la UI
  65. 65. Usar HTML/CSS para dibujar la GUI
  66. 66. Usar HTML/CSS para dibujar la GUIRovio/Google (Angry Birds GWT port), I’m looking at you...
  67. 67. Usar HTML/CSS para dibujar la GUI
  68. 68. Usar HTML/CSS para dibujar la GUIZeptoLabs/Microsoft (Cut the Rope), yay!
  69. 69. Usar HTML/CSS para dibujar la GUI
  70. 70. Usar HTML/CSS para dibujar la GUIAutodesk Scaleform GFX (UDK) - Adobe Flash/AS2
  71. 71. Object Pooling// Maximum number of sound objects allowed in the poolvar MAX_PLAYBACKS = 3;var globalVolume = 0.3;function SoundUtil(){! this.maxPlaybacks = MAX_PLAYBACKS;! this.audioObjects = []; // Pool of audio objects available for reutilization}SoundUtil.prototype.play = function(file, startTime, duration, volume, loop){! // Get an audio object from pool! var audioObject = this.getAudioObject(),! ! suObj = this;! /**! * No audio objects are available on the pool. Dont play anything.! * NOTE: This is the approach taken by toy organs, alternatively you! * could also add objects into a queue to be played later on! */! if (audioObject !== null) {! ! audioObject.obj.loop = loop;! ! audioObject.obj.volume = volume;! ! for (var i = 0, l = file.length; i < l; ++i) {! ! ! if (audioObject.obj.canPlayType(file[i][1]) === "probably" ||! ! ! ! audioObject.obj.canPlayType(file[i][1]) === "maybe") {! ! ! ! audioObject.obj.src = file[i][0];! ! ! ! audioObject.obj.type = file[i][1];! ! ! ! break;! ! ! }! ! }! ! var playBack = function()! ! {! ! ! // Remove the event listener, otherwise it will keep getting called over and over agian! ! ! audioObject.obj.removeEventListener(canplaythrough, playBack, false);! ! ! audioObject.obj.currentTime = startTime;! ! ! audioObject.obj.play();! ! ! // Theres no need to listen if the object has finished playing if its playing in loop mode! ! ! if (!loop) {! ! ! ! setTimeout(function() {! ! ! ! ! audioObject.obj.pause();! ! ! ! ! suObj.freeAudioObject(audioObject);! ! ! ! }, duration);! ! ! }! ! }! ! audioObject.obj.addEventListener(canplaythrough, playBack, false);! }}
  72. 72. Object PoolingSoundUtil.prototype.getAudioObject = function(){! if (this.audioObjects.length === 0) {! ! var a = new Audio();! ! var audioObject = {! ! ! id: 0,! ! ! obj: a,! ! ! busy: true! ! }! ! this.audioObjects.push (audioObject);! ! return audioObject;! } else {! ! for (var i = 0, l = this.audioObjects.length; i < l; ++i) {! ! ! if (!this.audioObjects[i].busy) {! ! ! ! this.audioObjects[i].busy = true;! ! ! ! return this.audioObjects[i];! ! ! }! ! }! ! // No audio objects are free. Can we create a new one?! ! if (this.audioObjects.length <= this.maxPlaybacks) {! ! ! var a = new Audio();! ! ! var audioObject = {! ! ! ! id: this.audioObjects.length,! ! ! ! obj: a,! ! ! ! busy: true! ! ! }! ! ! this.audioObjects.push (audioObject);! ! ! return audioObject;! ! } else {! ! ! return null;! ! }! }}SoundUtil.prototype.freeAudioObject = function(audioObject) {! for (var i = 0, l = this.audioObjects.length; i < l; ++i) {! ! if (this.audioObjects[i].id === audioObject.id) {! ! ! this.audioObjects[i].currentTime = 0;! ! ! this.audioObjects[i].busy = false;! ! }! }}
  73. 73. Evitar instanciaciones en loops// Pseudocódigowhile (activo()) {! var obj = new Ejemplo(); // Ouch! obj.configurar();! obj.hacerAlgo();} Casos de uso: Emisión de Partículas, Update loops
  74. 74. Mantener la lógica separada de la rutina de pintado// Pseudocodigofunction actualizarVista(){! if (pasaAlgo()) {! ! for (var i = 0, l = objetosEnLista.length; i < l; ++i) {! ! ! hacerAlgo();! ! }! } else {! ! for (var i = 0, l = elementos.length; i < l; ++i) {! ! ! hacerOtraCosa();! ! }! }!! pintarEnPantalla();}
  75. 75. Mantener la lógica separada de la rutina de pintado// Pseudocodigofunction ejecutarLogica(){! if (pasaAlgo()) {! ! for (var i = 0, l = objetosEnLista.length; i < l; ++i) {! ! ! hacerAlgo();! ! }! } else {! ! for (var i = 0, l = objetosEnLista.length; i < l; ++i) {! ! ! hacerOtraCosa();! ! }! }}function actualizarVista(){! pintarEnPantalla();}
  76. 76. Tablas de Valores Math.sqrt(<número>)Math.pow(<número>, <potencia>)
  77. 77. Tablas de Valores
  78. 78. Tablas de Valores
  79. 79. Tablas de Valoresvar raizCuadrada = arrayRaices[<numero>];
  80. 80. Ser conciente de la memoria utilizada por un objetogrilla[114422, 1233] = new ObjetoEjemplo();
  81. 81. Ser conciente de la memoria utilizada por un objeto grilla[114422, 1233] = new ObjetoEjemplo();https://github.com/andrespagella/Making-Isometric-Real-time-Games/ blob/master/examples/astar.js
  82. 82. "Es divertido hacer lo imposible." Walt Disney
  83. 83. ¡Gracias!@mapagella - https://github.com/andrespagella/ - http://www.andrespagella.com

×