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

848

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.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
848
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 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
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×