Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menu

Mensajes - TrOnTxU

#16
Yo simpre suelo tirar de pooling en mi input manager.

De todas formas utilizo un par de clases para abstraer los datos y implementaciones de clases que gestionan los "devices": pads, mouses, teclados, touch screens, etc.

Aparte, utilizo "C Opaque Pointers" para los datos especificos de plataforma, y tengo implementaciones distintas para cada plataforma: dxinput para windows, X11 para linux, cell library para PS3, etc.  En las plataformas que funcionan con callbacks "a la fuerza" (como en Android o Cocoa) relleno un estructura de datos (especifica por plataforma) conforme me llegan los callbacks, y luego lo gestiono en el update de la clase del device concreto.

Tambien tengo la opción de utilizar "channels" para "mappear" entradas (botones, teclas, ejes del raton, ejes de los joysticks, etc.).

Por encima de todo esto lo normal es crearte gestores de más alto nivel (aqui solo suele haber uno multiplataforma que utiliza las clases especifcas anteriores) para detectar combos, chords, gestures, etc.

Todo esto lo mejor es crearlo poco a poco y de manera incremental conforme vas necesitandolo.

En cuanto a referencias, no conozco un libro que trate el tema exahustivamente, pero el "Game Engine Architecure" de Jason Gregory tiene un capitulo dedicado a esto (aunque sin mucho ejemplo de código, más que nada conceptos).
Luego creo recordar que habia alguna implementación hecha en algún Game Programming Gems, pero no me hagas mucho caso tampoco.

La otra opción es ir mirando ejemplos en mototres Open Source. Te recomiendo empezar por Ogre3D que siempre es un buen punto de partida para comenzar a investigar.

Bueno, espero haberte ayudado.
Un saludo, y suerte :)
#17
Hay bastante motores que no necesitan de conocimientos de C. Luego por supuesto tienes juegos con ActionScript, HTML5, etc.

Pero de ahi a hacer un curso/carrera de programación de videojuegos y no saber C ...

C te vale para todo, desde la tecnologia del motor, pasando por partes importantes del gameplay, plug-ins de DDC (Maya, MODO, Max, etc.), herramientas de procesado offline, etc.

Yo soy de la opinión de que no te puedes "abstraer" completamente de la arquitectura de la plataforma para la que desarrollas, si vas a trabajar solamente en PC o juegos web, etc. no hay problema (en teoria).

Pero a poco que toques alguna consola, o quieras hacer algo que tenga buen rendimiento necesitas saber como trabajar a bajo-medio nivel.

Por ejemplo, mi experiencia con Unity en la Wii es que si lo programas todo en lenguaje de script, hay muchas estructuras de gameplay que pierden "performance" por un tubo, y uno de los peores enemigos de un "frame rate constante" son los metodos de recoleccion de basura de los lenguajes de script.

Asi que aunque vayas a trabajar el gameplay (o la mayor parte de él) con Lua, JS, C#, o cualquier otro lenguaje de más alto nivel, deberias tener claro como trabajar con C, como eliminar los problemas de reserva/manejo de memoria, como aprovechar la coherencia de la cache, etc.

Además, en una empresa mediana/grande el código de script de gameplay es cosa de los diseñadores de niveles, por norma general. El programador/ingeniero elabora sistemas de más bajo nivel que luego utilizan los diseñadores para "crear" la jugabilidad.

Un saludo.
#18
¿Presencial?
¿No os sirve un freelance a distancia para algun proyecto?  0:-)
#19
General Programadores / Re:Control de codigo fuente
02 de Noviembre de 2013, 08:27:10 PM
Cita de: bnl en 02 de Noviembre de 2013, 04:50:34 PM
Lo mismo lo estoy configurando mal pero en las pruebas que he hecho mas que copiar lo que hace es mover todo el codigo fuente desde el workspace de eclipse donde estabas trabajando a otra ruta dentro del repositorio de git y luego ya no trabajas con los ficheros que tenias dentro del workspace de eclipse (que dejan de existir) si no con los que estan dentro de la carpeta del repositorio
Es una tonteria pero se me hace raro.

Igual no me explicado yo bien: el repositorio local y el workspace ESTAN DENTRO de la misma carpeta en Git (entre otros DVCS).
Los archivos del workspace estan colocados a partir de la raiz del directorio, y toda la informacion y copias de la versiones estan en un subdirectorio especial (".git") que hay en el raiz.

En la carpeta sobre que la que trabajes tendras todo, copia local y repositorio local.
Por lo tanto en eclipse lo que has de configurar es la ruta sobre la que quieras tener la copia de trabajo como repositorio.

Para "sincronizar" con otro repositorio (ya sea en otro disco duro o en remoto) debes hacer un PUSH. No basta con hacer un commit, ya que los commit en DVCS solo afectan al "repositorio local".

Como te digo es irte adaptando a la forma de trabajar de los sistemas de control de versiones distribuidos, intenta no partir de premisas demasiado rigidas de como deberia funcionar. Intenta aprender el nuevo workflow y poco a poco verás como es más útil.
Personalmente no conozco a nadie que después de trabajar en un proyecto entero con un DVCS quiera volver a los VCS. Las ventajas una vez "controlas" son muchas.
#20
General Programadores / Re:Control de codigo fuente
26 de Octubre de 2013, 11:09:09 PM
Con un branch te vale.

Pero comenzar a trastear con pruebas de branches y merges te puede venir bien (más que nada como pruebas, luego ya le puedes dar el uso que creas conveniente).

De todas formas en los DVCS (como Git o Hg) cada revision es como un snapshot/branch-tag de svn, o sea que puedes recuperar el estado total de todos los archivos recuperando esa revision (a diferencia de svn o cvs, que al llevar revisiones por archivo era un infierno recuperar el estado de la copia de trabajo de un dia concreto, por ejemplo), sin la necesidad de haber creado un "branch/tag" al viejo estilo VCS.

EDIT PS:
En cuanto a lo de la carpeta en el repositorio, es porque en los DVCS siempre tienes una copia del repo entero dentro de una carpeta de trabajo local (".git", ".hg", etc. dependiendo del sistema que uses).

Al principio, si vienes de trabajo con repositorios centralizados ralla un poco (a mi me pasaba al principio). Y tiene el incoveniente de ocupar más espacio (como es lógico).
Pero, la verdad es que te acostumbras, y creeme, al final vale la pena y mucho tener esa copia, y las diferentes maneras de ir juntando los branches o trabajando con otro repo centralizado en un servidor, o con el repo de otro usuario, aplicar parches, etc.
#21
General / Re:Diferencias entre engines.
24 de Octubre de 2013, 11:51:23 AM
Esos dos enlaces que has puesto, son muy buenos :)
De hecho, yo me basé en "Cutting the Pipe" cuando decidí "actualizar" el "tool-set" de mi engine. Y la verdad es que funciona de maravilla, con un super botón de "Compile And Reload" :D

En cuanto a los tipos de modelos de GameObjects, mirate este link del Uncharted 2 de Naughty Dog: http://www.slideshare.net/naughty_dog/statebased-scripting-in-uncharted-2-among-thieves
Si encuentras el Power Point (creo que esta en la pagina de Naughty) tambien tiene anotaciones y comentarios (yo lo tengo bajado).
Basicamente define como funciona el state scripting que se han montado en Scheme. Pero en las paginas 13, 14 y 15 tienes breves descripciones de varios modelos de game objects (Unreal, Property-Centric, y Uncharted2). En la pag. 12 hay links interesantes, y en concreto el libro del mismo Jason Gregory "Game Engine Architecture" tiene un par de capitulos en los que define los diferentes modelos con mucho más detalle.

A parte, otro ejemplo que te puedo poner es un "Endless Runner/Flyer" donde utilizar estructuras simples que definan los "objetos dinámicos" dentro de un "Buffer Circular" ofrece muchas ventajas.
Ya que sabes que vas a ir creando y destruyendo los Game Objects continua y ordenadamente (siempre hacia adelante, o de lado, se entiende).
Y sabiendo el indice de "start" y de "end" te permite no tener que recorrer toda la "lista" de objetos o crear estructuras de "particion espacial" para las colisiones (por ejemplo).
Además puedes dibujar ordenadamente por Z en el caso de que sea un "endless" en el que "avanzas hacia el fondo". Evitandote asi tener que reordenar la lista de meshes por profundidad, y lo puedes utilizar en los opacos, por ejemplo, para descartar pixeles con el zbuffer (moderando el pixel fill overdraw), o cualquier otra tecnica de este tipo.

Como ya se ha dicho antes, un buen conocimiento del contexto te ofrece grandes ventajas, que una implementación genérica, aunque también funcional, no puede aprovechar.

Espero que te ayude.
Salu2
#22
General / Re:Diferencias entre engines.
23 de Octubre de 2013, 08:45:27 PM
En mi opinión todo el "low-level" cuando más DoD (Data Oriented Design) mejor:
1 - Mayor sencillez y claridad en el diseño (por norma general)
2 - Menor tiempo de compilación
3 - Más fácil hacer decoupling de sub-sistemas
4 - Mayor coherencia de cache (por tanto mayor velocidad de ejecución)
5 - Mayor facilidad para mover sub-sistemas a multithreading, CPU-Helpers(como SPU) y/o GPGPU.

Las "capas superiores" que "atan" todos los sub-sistemas ... depende del tipo de juego.
Para algunos juegos son mejores basados en propiedades, otros orientado a objetos, etc.

Uno de los sistemas de gameplay más "versatiles" (en mi opinión) es el "Game Object Dynamic Components", como puede ser el del Unity3D o el de Insomniac https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2011/06/6-1-2010.pdf.

Aunque yo personalmente en mi motor utilizo modelos de game objects diferentes por tipo de juego (el que creo que puede encajar mejor).


En cuanto a las "tools", va por gustos. En mi opinión (y tal como lo estoy implementando yo en el Typhoeus) mejor tener tools separadas, y no dependientes del "runtime". Y mantener dos tipos de datos:
1) Los intermedios o de trabajo (preferiblemete en formato texto tipo JSON o XML)
2) Los binarios finales compilados. Que pueden ser compartidos o diferentes entre varias plataformas (cada plataforma puede tener sus tipos de compresión, su endianess, etc.)

Para mi las ventajas sobre el modelo ÜberEditor (Unity3D, UnrealEd, etc.) son:
1 - Si "peta" el motor, no "peta" el editor.
2 - Si "peta" el editor de particulas, no "peta" el editor de materiales, etc.
3 - Las "herramientas pequeñas" son más faciles de mantener y se "cargan" más rapidamente.
4 - Mayor facilidad de trabajo concurrente y "data merge".
5 - Menor problema para crear las herramientas en un lenguaje de más alto nivel (C#, Python, ...) aunque el run-time siga siendo completamente C++.
6 - Más fácil de mantener un runtime "independiente de la edición" y de "bajo peso".

Para solventar el problema de comunicación (entre herramientas y con el runtime) lo mejor es usar sockets TCP/IP. Lo cual tambien permite actualizar el estado del juego directamente en la consola o en el smart-phone con un solo 'click' en una herramienta del PC de desarrollo.


Esto es solo mi opinión, pero también existe algun motor por ahi con una filosofia parecida y bastante eficiente (veasé: http://www.bitsquid.se/ ).

Espero haber aportado algo.
Un saludo.
#23
Jajaja. que sinte más chulo!!!!
Es brutal  :D :D :D

Luego puedes pasar el ".WAV" por el Audacity, le metes algun effecto y ya tienes un rollete más moderno ... o no  :D

Estoy pensando hasta en soportar la creación de los datos del buffer sonido a partir del archivo que tiene ... y adios a los WAVs!! volvemos a los buenos tiempos ...   ^_^ ^_^
#24
No estoy muy puesto en lo de Xamarin, pero yo para Android yo lo que hago es pasar del evento de rotación, y obtener el tamaño del surface cada frame. Puede que haya un pequeño "overhead" pero a mi me funciona (al menos con una Native Activity).

Puedes guardar la ultima resolución y compararla con la actual (obtenida el mismo frame), para saber si se ha rotado o no el Device (te basta con el width, por ejemplo).

Tambien comprueba que en el XML permites varias orientaciones y no solo una (si especificas Landscape o Portrait no se detectará la rotación del dispositivo).


Espero haberte ayudado, un saludo.
#25
General Programadores / Re:Optimizar recursos
17 de Mayo de 2013, 12:59:47 AM
Cita de: bnl en 16 de Mayo de 2013, 11:31:02 PM
Gracias.
Muy interesante lo del swap last, no se me habia ocurrido.

Se me ocurre que podrias prescindir de la lista de particulas y tener solo un array con todas las particulas, tanto las vivas como las muertas. Las muertas estarian todas al final y las vivas al principio y se mantendria una variable con la posicion de la ultima particula viva. Al actualizar las particulas si una pasa a estado muerto se haria el swap con la ultima particula viva y ser decrementaria la variable de la posicion de la ultima particula viva

Exacto, esa es la idea.

Yo utilizo la lista de erase para acumular todas las particulas que "deben ir al final" (o sea las que se mueren) durante el ciclo de update. Pero la idea es esa, un array con el maximo de particulas, y un indice que separa las "vivas" de las "muertas" :)
#26
General Programadores / Re:Optimizar recursos
15 de Mayo de 2013, 04:27:57 PM
Swap-Last es cambiar el elemento a borrar por el el ultimo del array y decrementar el numero de elementos.

Este trozo de la implementacion (del código del post que puse) ...

...
  const unsigned int kEraseArraySize = 10;
  unsigned int eraseArray[kEraseArraySize];
  unsigned int eraseArrayCount = 0;

  for(unsigned int i = 0; i < pEmitter->particleCount; i++)
  {
    // Apply gravity
    add_vec3(&velocityArray[i], &velocityArray[i], &dtGravity);
    // Apply movement
    Vec3 deltaVel;
    scalar_mult_vec3( &deltaVel, &velocityArray[i], dt );
    add_vec3(&positionArray[i], &positionArray[i], &deltaVel);
    // Decrease life
    lifeArray[i] -= dt;

    if (lifeArray[i] <= 0.0f && eraseArrayCount < kEraseArraySize)
    {
      eraseArray[eraseArrayCount] = i;
      eraseArrayCount++;
     }
  }

  while (eraseArrayCount > 0) // && pEmitter->particleCount > 0)
  {
    eraseArrayCount--;
    pEmitter->particleCount--;
    // Erase and swap-last
    int eraseElement = eraseArray[eraseArrayCount];
    positionArray[eraseElement] = positionArray[pEmitter->particleCount];
    velocityArray[eraseElement] = velocityArray[pEmitter->particleCount];
    lifeArray[eraseElement] = lifeArray[pEmitter->particleCount];
  }
...

... corresponde al metodo de actualización.

1) En el array auxiliar "eraseArray" pongo hasta un máximo de diez particulas a eliminar durante ese frame (particulas que han (muerto").
2) Después del loop principal por todas las particulas, hay otro loop por las particulas "muertas", y se van intercambiando las posiciones del array (yo tengo las propiedades como "SoA") por las ultimas y decrementando el numero de particulas.

Es solo una forma de implementarlo, si utilizas algun tipo de indexacion (para luego ordenarlas) puedes tener que evitarte copiar todas la estructura o la propiedades por separado, y solo mover el indice.

De todas formas esta implementación la hice como ejemplo. El "verdadero" subsistema de particulas y efectos del typhoeus es un poco más complicado. Y el algoritmo de actualización es un poco diferente, a ver si puedo hacer otro post con imagenes del sistema y algun trozo de código de ejemplo.

Un saludo, espero que te sirva :)
#27
General Programadores / Re:Optimizar recursos
14 de Mayo de 2013, 10:55:06 PM
Yo lo que hago como puse en el post de particulas del typhoeus es crear un array con un numero maximo de particulas definido en el sistema: http://typhoeus-sdk.blogspot.com.es/2012/06/problemas-de-memoria-no-lo-se-no-me.html

La versión más optimizada es la version en "C puro" con arrays estáticos.

Añado nuevas particulas al final del array, y elimino particulas con "swap-last". El máximo tamaño del Array determina el maximo numero de particulas a crear.

Crear el array de un tamaño máximo, utilizando un contador de elementos te asegura que no va a haber malloc/free (o el equivalente en garbage collection) por más que se creen y destruyan particulas cada frame.

Lo de utilizar un pool no es mala idea tampoco.

Para utilizar "z-sorting" (por ejemplo) utilizo un array de indices, esto implica un indireccionamiento más (el z-sorting solo es necesario al hacer el render no al actualizar), pero evita tener que mover estructuras o varios datos( depende de si es "SoA" o "AoS" ) por particula al ordenar.

Un saludo
#28
Cita de: NullPointerException en 26 de Marzo de 2013, 01:58:52 PM
Cita de: YaW en 26 de Marzo de 2013, 11:07:26 AM
Probaste a poner el problema en el foro de LibGDX?

Leí por ahí en que no se daba soporte a los errores con el emulador, aunque creo que debería hacerlo

pufff pues yo trabajar pruebas con un emu de android me da el patatus!!

Cuando quiero probar diferentes resoluciones lo pruebo en win32 normal (o OSX si estoy con el mac) cargando desde un archivo de configuración. Tengo tambien una forma para hacer un build de las librerias bajo emulacion gles, supongo que el GDX tiene algo parecido.

Luego depuro la version en los android que tengo (que no son muchos) y cuando puedo hago una prueba en algun dispositivo de algun amigo.

Seguramente con el emu se puedan probar algunas cosas como entradas de llamadas, o eventos de estos. Pero si el libGDX tiene un buen framework soportará estas cosas y las podrás probar (más o menos) en la versión desktop.

Otra cosa es que tuviera problemas con algunos Android (dispositivos). Entonces puedes buscar alguna cosa más "ligera" que funcione en más dispositivos e incluso en los emuladores (en todo caso, si hay menos código, es más fácil de portar).
Tambien tienes frameworks para c++ si quieres pasarte al lado oscuro del coder. Igual la SDL o una cosa asi te da soporte de independencia de plataforma. Y el resto (manejo de sprites, etc) lo puedes implementar en OGL ...
#29
Yo no he tocado el libGDX, pero si lo vas a hacer en java seguro, parece que es muy buena opción (por lo que dicen).
Además si es OpenSource, igual te conviene intentar "depurar" los defectos que le veas y luego supongo que puedes mandarles el patch si quieres.

Hacerte un motor de cero, depende ... si es solo orientado a este juego y tampoco te planteas reaprovechar demasiado ...
Lo que te cueste menos tiempo depende de tu forma de hacer las cosas. Hay gente que se le da mejor bucear y modificar código, y otros escriben mejor desde cero.

Pero con lo que estoy de acuerdo, es que poder desarrollar en desktop te facilita la vida. (y los "emuladores" Android son muy lentos y engorrosos para depurar, al menos si trabajas en c++)
Yo el Typhoeus tambien lo tengo planteado rollito "cross-platform". Incluso, tengo un fileserver para los archivos en la versión "development" y no tengo que actualizar el APK cuando cambio el "Content", solo cuando hay cambios en el ".so".


Mi consejo es que o vas con un engine "cross-platform" como dice YaW( el libGDX o el que sea), o el que te programes deberia permitir que lo probaras en "desktop". Sino yo creo te vas a volver loco para "afinar" los parámetros y hacer pruebas.

Pero solo es mi opinión.

Un saludo y ánimo :)
#30
- Yo creo que el mayor problema de poner muchos sprites rollo arcade es el numero de draw calls.
- Yo en el sistema de GUI 2D del Typhoeus lo que tengo es un "batcher" por material y profundidad.
- Te sugiero que "empaquetes" los sprites en unas pocas texturas. Para compartir la mayor cantidad de batches.
- A los vertices les pongo posicion, uvs, y color.
- Es conveniente tener un "draw_fast" con posicion (y a lo mejor una escala) y "draw_transform" con escala y rotacion.
- Dibujarlos con listas de triangulos indexados es una buena opción.
- Otro tema es si el batch lo dibujas con drawArrays o actualizas un buffer ogl. Pero lo principal yo creo que es "batchear" :)

Un saludo





Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.