JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos  a volvernos mejores Desarrolladores Web por Andres Pagella
Upcoming SlideShare
Loading in...5
×
 

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

on

  • 954 views

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.

Statistics

Views

Total Views
954
Views on SlideShare
944
Embed Views
10

Actions

Likes
0
Downloads
3
Comments
0

5 Embeds 10

http://www.linkedin.com 3
https://si0.twimg.com 2
https://twitter.com 2
https://www.linkedin.com 2
http://us-w1.rockmelt.com 1

Accessibility

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \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 JSConf Argentina 2012 - Como el Desarrollo de Videojuegos puede ayudarnos a volvernos mejores Desarrolladores Web por Andres Pagella Presentation Transcript

  • Como el Desarrollo deVideojuegos puede ayudarnosa volvernos mejoresDesarrolladores WebM. Andrés Pagella (@mapagella) - http://www.andrespagella.com
  • < 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 el menor espacio posible
  • 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.schillmania.com/projects/soundmanager2/ Zynga Jukebox (Optimizado para Mobile) https://github.com/zynga/jukebox
  • 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: {! ! index: 2,! ! identifier: ff00! }}
  • 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; };
  • Otras consideraciones...
  • Otras consideraciones... Background LoadingOptimizaciones del lado del Servidor Optimizaciones de Imágenes Templates etc.
  • 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: Pensar “masivamente”
  • 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()) {VIEWPORT pintarCelda(); } } }
  • 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, 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();! ! ! }! ! }! }}
  • 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 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);! }}
  • 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;! ! }! }}
  • 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
  • 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();}
  • 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();}
  • 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/andrespagella/Making-Isometric-Real-time-Games/ blob/master/examples/astar.js
  • "Es divertido hacer lo imposible." Walt Disney
  • ¡Gracias!@mapagella - https://github.com/andrespagella/ - http://www.andrespagella.com