Posts Tagged videojuegos
El diario Escondido
Luego de muchos meses de mucho trabajo, remasterización, ajustes, pruebas y demás, finalmente pudimos terminar y poner online una de las campañas más ambiciosas que hemos hecho hasta ahora : El diario Escondido.
Hasta el día del lanzamiento solo podrán ver el trailer, si lo juegan me gustaría que después se pasen y dejen opiniones sobre qué les pareció
.
PD: No, no estoy autorizado a decirles como pasar, sumarles puntos extra o hacerlos subir de ranking
.
State Machine
Posted by Gazer in Programación on 08/12/2008
Varios días atrás tuve que hacer un juego simple, un memotest para ser exacto, para correr en unos “kioskos” para un cliente. Ya que tenía pendiente aprender a usar RubyGame, lo hicimos con este framework para ver que onda, ya que hasta ahora veníamos usando pyGame.
El juego salió super rápido, sin mayores problemas, pero la lógica de juego no me gustaba porque teníamos que andar trackeando el estado actual a mano, muchos ifs y comprobaciones que hacían del loop de juego un choclo de código.
Es por eso que me puse a ver un poco como aprovechar el tener bloques de código para encapsular la lógica del juego un poco más prolijo. Antes de comenzar encontré la gema Statemachine pero a primera vista no la entendí mirando los ejemplos
y luego de jugar un rato no me terminó de convencer ya que parece mucho más de lo que yo necesitaba.
El resultado de un par de horas de tirar “magia” fue poder definir la lógica de la siguiente manera (el ejemplo está simplificado, omitiendo los efectos y parte de la lógica) :
class Logic include StateMachine # Esperando interacción del usuario state :user_input do @events.each { |event| case event when MouseDownEvent selected event.pos when QuitEvent end_game end } end # Oculta las piezas seleccionadas cuando no hubo match state :clear do @selected.each {|f| f.hide } @selected = [] end # Cambio de estado transition :user_input, :clear do @selected.size == 2 end # Cambio de estado transition :clear, :user_input do true end end
Cada declaración de state tiene el código que se debe ejecutar cuando estamos en dicho estado, mientras que las transition son usadas automáticamente para saber a qué estado nos debemos mover. La primer transition que retorne true, se toma el estado destino y se asigna como el actual.
Por el lado del game loop, lo único que se debe hacer es llamar a un método que se encarga de ejecutar el estado actual y luego verificar si alguna transición retorna “true” y se cambia al nuevo estado.
class Game include Rubygame include Logic def event_loop loop do current_state return if game_ended? draw @clock.tick @screen.update end end end
En Game hay otros métodos auxiliares como game_ended, draw y selected, que no vienen mucho al caso en este momento.
El próximo paso ahora es limpiar un poco esto, ver si no hay una forma mejor de hacerla y publicar el esqueleto completo (la idea a futuro es tener un generator) para poder tener un mini framework para hacer juegos simples.
Si buscan un framework interesante les recomiendo Shattered Ruby (git repo), aunque al momento de escribir este post el sitio principal no responde.
MovieClip Factory en Flash
Posted by Gazer in Programación on 04/12/2008
Para un videojuego que nos pidió un cliente tuve que solucionar un problema que me costó bastante y es por eso que lo comparto. Si bien no me gusta mucho escribir por acá sobre software privativo, en este caso encontré tan poca información que me pareció bueno compartirlo.
El juego en cuestión es un scroller horizontal, en donde van entrando chimeneas (mas bien techos con sus chimeneas) y Papá Noel tiene que hacer el delivery de regalos
. El problema apareció cuando empecé a agregar más y más techos al escenario.
La forma en que inicialmente lo manejaba era con un gran MovieClip que tenía adentro los techos en sus respectivas posiciones y luego moviendo el gran MovieClip movía todo. Simple, pero inefectivo. Según parece (aunque no hay nadie que lo confirme) Flash se lleva mal con las técnicas de clipping básicas y por eso el mover un MovieClip enorme (estamos hablando de 4000 o 5000px de ancho) le es costoso (algo así como consumir el 95% del CPU). Otra cosa que incrementaba el problema es que el juego tiene 3 layers para hacer un efecto de Parallax scrolling.
Esto hizo que empezara a investigar opciones, y la solución que mejor se adapta es crear los objetos antes de que entren en pantalla (unos pixels antes) y destruirlos al salir. Ahora bien, crear y destruir objetos on-the-fly es aún peor en muchos casos que el problema inicial
. La solución real al problema es reutilizar las instancias en lugar de eliminarlas. ¿Cómo?. Seguí leyendo.
La idea básica es que cuando un MovieClip sale de pantalla, en lugar de eliminarlo lo ocultamos. De esta forma Flash lo ignora al hacer el render. Si en algún momento necesitamos crear un objeto del mismo tipo, en lugar de crear uno nuevo, reutilizamos el que teníamos oculto y lo hacemos visible (previo acomodarlo donde corresponde). Ahora multipliquen esta idea por 10 tipos de objetos diferentes, y que además son generados al azar antes de empezar cada nivel (no puedo predecir cuantos de cada tipo necesito).
Esto hace que en lugar de tener una lista de MovieClips tengamos una lista de puntos, y solo movemos los puntos. En cada frame nos fijamos que puntos están por entrar a la pantalla y creamos el nuevo objeto y lo ponemos en la posición del punto. Mi código luce más o menos así :
// Crea los objetos que deben estar visibles // en un momento dado. while (i < chimeneas.length) { var o:Object = chimeneas[i]; if (o.x > (Stage.width+10)) { // Este punto está muy afuera y como // están ordenados, el resto también. break; } // Si estoy a 10 pixels de entrar lo creo var t:Techo = factory.create(o.techo, "techo"+last_id, 9000+last_id); // Acomodo el nuevo objeto, ya sea nuevo nuevo u obtenido del cache t._x = o.x; t._y = Stage.height - 125; // Esta lista tiene los Techos reales que estan visibles en pantalla techos.push(t); last_id++; ++i; } // Elimino los puntos que ya use chimeneas = chimeneas.splice(i);
La solución que implementé fue esto que llamo “MovieClip Factory” que adjunto al final del post para quien quiera descargarla. La idea es que en lugar de crear un nuevo MovieClip con attachMovie, lo hago con la factory. Esta clase se encarga de manejar al lógica de caching de manera transparente.
Cuando no necesitamos más un objeto simplemente lo devolvemos a la fábrica y así esta lo deja a la espera de ser reusado. Un ejemplo de uso sería algo como sigue :
/* mc sería el MovieClip que queremos usar como padre */ factory = new Factory(mc); factory.registerCode(1, "Techo01"); var t:MovieClip = factory.create(1, "un_id", 1); // Devuelvo el objeto al factory. factory.push(t); /* A este punto t y u son el mismo objeto */ var u:MovieClip = factory.create(1, "un_id", 1);
Haciendo las cuentas, si en promedio mis techos miden 250px cada uno, de hacerlo de la manera inicial tendría que crear unos 16 techos para un escenario de 4000px de ancho. Usando el factory, suponiendo que más de 4 techos a la vez no puedo ver (por el ancho del área visible) en el peor de los casos tengo 4 de cada tipo de techo (2 completos y 2 mitades, una que entra y una que sale), es decir 20 objetos en memoria siendo el consumo mayor.
Sin embargo al generar el escenario en forma aleatoria yo valido que no toquen 2 iguales seguidos porque quedaban feos, por lo que la cuenta en realidad da 2 objetos simultáneos máximo de cada tipo, siendo 10 en total en memoria.
La otra ventaja es que puedo hacer el escenario infinitamente largo a costo constante de uso de memoria
Hitman: Agent 47
Posted by Gazer in Cine, Yo Estuve Ahí on 23/01/2008
Ayer fui al preestreno (a.k.a Avant Premiere) de la película basada en los juegos Hitman, invitado por Speedy. El overall siendo generoso, es un 5/10.
El actor no está mal, un poco duro para mi gusto, aunque bueno, tiene que imitar a un mesh 3D
, fuera de chiste, yo prefería a Jason Statham para el panel, ya que la primera vez que vi The Transporter, pense en “uh, este es como Hitman!”.
La película me resulto muy corta. Si no hice mal mis matemáticas fue una hora y media. Ahora, o estaba cortada o no daba para más
.
En general esta bien cuidado el personaje, salvo en un par de lugares donde sonríe frente a algún chiste de su co-star Olga Kurylenko (si, si, lo tuve que buscar). Desde cuando un super asesino sonríe ?!!
Las escenas de accion estan bien, no se me ocurre ahora criticarles mucho más de que duran como 30 segundos cada una. Como buen asesino que es, lo hace todo rápido y no deja nadie de pié
. Podrían haberlas hecho en slowmotion para que duren más !!.
El personaje da para hacer buenas películas y espero que estén pensando en hacer una segunda un poco mejor. Seguramente habrá que esperar un rato
Más PacMan!!
Posted by Gazer in Programación on 03/06/2005
Si amigos!, mientras trato de hacer el código algo presentable, tengo nuevas novedades. Hoy Alan me hizo notar que mi juego estaba adaptado para celulares demasiados groso (pantallas de 240×240 pixels). Claro que no es la realidad de la mayoría.
Por lo tanto, me tuve que poner a implementar window-scrolling, y para que quede como a mi me gustaba, lo hice desde 0, logrando algo que realmente me gusta, tanto en código como visualmente.
Antes de liberarlo, les dejo un lindo swf mostrando como se ve en los distintos modelos, les voy a visando, son 4Mb.
UPDATE: Ya puse el código fuente disponible en mi repositorio de darcs. Para bajarlo (si tenés darcs instalado) : darcs get http://www.gazer.com.ar/repos/PacMan , Si no tenes darcs, no existís
