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

  • 800 views
Uploaded 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.

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.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
800
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
4
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    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

Transcript

  • 1. Como el Desarrollo deVideojuegos puede ayudarnosa volvernos mejoresDesarrolladores WebM. Andrés Pagella (@mapagella) - http://www.andrespagella.com
  • 2. < 2003
  • 3. < 2003
  • 4. < 2003
  • 5. < 2003
  • 6. ~2000
  • 7. 2004
  • 8. 2005
  • 9. Mac OSX 10.4 Tiger 2005
  • 10. 2007
  • 11. 2007
  • 12. APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?)
  • 13. APUNTAR AL ‘MINIMO COMUN DENOMINADOR’ (?) Si anda bien en este, anda bien en todos.
  • 14. PARA TENER EN CUENTA...
  • 15. PARA TENER EN CUENTA...Tiempo de Carga
  • 16. PARA TENER EN CUENTA... Tiempo de CargaVelocidad de Rendering
  • 17. PARA TENER EN CUENTA... Tiempo de CargaVelocidad de RenderingResponsividad de la UI
  • 18. Video Juegos
  • 19. Video Juegos
  • 20. OPTIMIZACIÓN DE TIEMPOS DE CARGA
  • 21. OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latencia
  • 22. OPTIMIZACIÓN DE TIEMPOS DE CARGABuen download bandwidth, pésima latenciaAcomodar la mayor cantidad de información en el menor espacio posible
  • 23. LAZY LOAD
  • 24. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  • 25. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  • 26. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites)
  • 27. Spritesheets / Atlas & Soundsheets (AKA Audio Sprites) +
  • 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. Heightmaps
  • 30. Heightmaps
  • 31. Heightmaps
  • 32. Heightmaps
  • 33. Heightmaps map.gif (150 bytes)
  • 34. Heightmaps map.gif (150 bytes)
  • 35. Heightmaps
  • 36. Heightmapsvar Tile = {! WALL: {! ! index: 0,! ! identifier: ffffff! },! RED: {! ! index: 1,! ! identifier: 00ff! },! BLUE: {! ! index: 2,! ! identifier: ff00! }}
  • 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. Otras consideraciones...
  • 39. Otras consideraciones... Background LoadingOptimizaciones del lado del Servidor Optimizaciones de Imágenes Templates etc.
  • 40. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA
  • 41. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA Extremadamente “caras” en dispositivos móviles
  • 42. OPTIMIZACIÓN DE OPERACIONES DE PINTADO EN PANTALLA Extremadamente “caras” en dispositivos móviles Consejo: Pensar “masivamente”
  • 43. VIEWPORT
  • 44. VIEWPORT
  • 45. for (var i = 0; i < 3; ++i) { for (var j = 0; j < 3; ++j) {VIEWPORT pintarCelda(); } }
  • 46. VIEWPORT
  • 47. for (var i = 0; i < 3; ++i) { for (var j = 0; j < 3; ++j) { if (dentro_de_viewport()) {VIEWPORT pintarCelda(); } } }
  • 48. VIEWPORT
  • 49. 1.000.000 FilasVIEWPORT x 1.000.000 Columnas
  • 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. Dirty Rectangles / ATR (Adaptive Tile Refresh)
  • 52. Dirty Rectangles / ATR (Adaptive Tile Refresh)
  • 53. Layering, Compositing, etc...
  • 54. Layering, Compositing, etc...Static Layer
  • 55. Layering, Compositing, etc...Static Layer Animated Layer
  • 56. Layering, Compositing, etc...
  • 57. Layering, Compositing, etc...
  • 58. Layering, Compositing, etc...
  • 59. Layering, Compositing, etc...
  • 60. Layering, Compositing, etc...
  • 61. Layering, Compositing, etc...
  • 62. Layering, Compositing, etc...
  • 63. Layering, Compositing, etc...
  • 64. Responsividad de la UI
  • 65. Usar HTML/CSS para dibujar la GUI
  • 66. Usar HTML/CSS para dibujar la GUIRovio/Google (Angry Birds GWT port), I’m looking at you...
  • 67. Usar HTML/CSS para dibujar la GUI
  • 68. Usar HTML/CSS para dibujar la GUIZeptoLabs/Microsoft (Cut the Rope), yay!
  • 69. Usar HTML/CSS para dibujar la GUI
  • 70. Usar HTML/CSS para dibujar la GUIAutodesk Scaleform GFX (UDK) - Adobe Flash/AS2
  • 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. 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. 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. 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. 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. Tablas de Valores Math.sqrt(<número>)Math.pow(<número>, <potencia>)
  • 77. Tablas de Valores
  • 78. Tablas de Valores
  • 79. Tablas de Valoresvar raizCuadrada = arrayRaices[<numero>];
  • 80. Ser conciente de la memoria utilizada por un objetogrilla[114422, 1233] = new ObjetoEjemplo();
  • 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. "Es divertido hacer lo imposible." Walt Disney
  • 83. ¡Gracias!@mapagella - https://github.com/andrespagella/ - http://www.andrespagella.com