Animacion

Solicite, consulte o publique recursos de referencia para desarrolladores.

Animacion

Notapor PLC » Mar Abr 29, 2008 7:48 am

Yo tengo en el juego que estoy haciendo, un personaje y una flor.

La flor esta en una determinada posicion y ademas puede estar abierta o cerrada, quiero que cuando mi personaje camine exactamente encima de la flor, esta cambie su estado, si esta cerrada que se abra y si esta abierta que se coma al personaje, por supuesto todos estos estados son imagenes. Ahora por ejemplo supongamos que mi flor esta cerrada, cuando mi personaje pasa por ecima de ella yo quiero que la flor cambie el estado pero lentamente, de hecho yo tengo una imagen que tiene a la flor semiabierta y otra abierta completamente, por lo que cuando mi personaje pasa por encima de la flor quiero dar la sensacion de que la flor abre sus petalos, como yo lo trate de hacer, paso por encima de ella pero es tan rapido que no se puede ver ese proceso en que la flor se abre poco a poco, para que me permita cuando pasa por encima de ella la primera vez si esta cerrada se abra y la sengunda vez se coma al personaje, y no que pasa una sola vez y cambien todos los estado a la vez
PLC
 
Mensajes: 21
Registrado: Lun Feb 11, 2008 12:02 am

Notapor Juan Carlos » Mar Abr 29, 2008 1:51 pm

Hola, tal vez la implementacion mas simple (y practica) sea utilizar un contador. Algo mas o menos asi:

Código: Seleccionar todo


game loop {

...
...

SI contador>=0 Y contador<10 ENTONCES
{
    imprimir flor cerrada
}
SI contador>=10 Y contador<20 ENTONCES
{
    imprimir flor semiabierta
}
SI contador>=20 Y contador<30 ENTONCES
{
    imprimir flor abierta
    SI jugador esta en contacto con la flor ENTONCES
    {
          jugador pierde
    }
}
SI contador>=30 Y contador<40 ENTONCES
{
     imprimir flor entreabierta
}
SI contador>=40 ENTONCES
{
     contador=0
}

contador=contador+1;

...
...
}



Si el problema radica en la velocidad del juego total, intenta implementar un controlador de frames (FPS frames per seconds)

Saludos[/code]
Juan Carlos
 
Mensajes: 97
Registrado: Sab Jul 07, 2007 1:05 pm

Notapor PLC » Mar Abr 29, 2008 6:50 pm

Eso me parece que no me va resolver el problema por se veria muy rapido de hecho es casi la misma idea de como yo lo tengo


Código: Seleccionar todo
self.flag = 0
def abrirse(self,n):
         if(self.flag == 1):
              self.image = self.normal
              self.flag = 0
              return 0
         elif self.flag == 0:
              self.image = self.abriendo
              self.delay = 1000000
              while self.delay >= 1:
               self.delay = self.delay - 1
              if self.delay < 1:
                    self.image = self.abierta
              self.flag = 3
              return 0


y para controlar si se come al personaje por ejemplo hago esto

Código: Seleccionar todo
if self.rect.x == 426  and self.rect.y == 107:
             if(comedoras[2].abrirse(1) == 1):
                 zeek.kill()


self.rect.x == 426 y self.rect.y == 107 seria una posicion determinada en donde el personaje esta encima de la flor.


tal vez el controlador de frames del que hablas pero bueno no se realmente como implementar eso.
PLC
 
Mensajes: 21
Registrado: Lun Feb 11, 2008 12:02 am

Notapor PLC » Mar Abr 29, 2008 6:58 pm

La funcion abrirse completa, me falto un pedazo de como la tengo hasta ahora


Me falto un pedazo de la funcion

Código: Seleccionar todo
def abrirse(self,n):
         if(self.flag == 1):
              self.image = self.normal
              self.flag = 0
              return 0
         elif self.flag == 0:
              self.image = self.abriendo
              self.delay = 1000000
              while self.delay >= 1:
               self.delay = self.delay - 1
              if self.delay < 1:
                    self.image = self.abierta
              self.flag = 3
              return 0
         elif self.flag == 3 and n == 1:
              self.image=self.comido
              self.flag = 1
              return 1
PLC
 
Mensajes: 21
Registrado: Lun Feb 11, 2008 12:02 am

Notapor lucesita » Mar Abr 29, 2008 7:58 pm

bueno, mucho de pyt no se, pero por lo que veo, vos lo que tenes es un CONTADOR, que decrementa, imagina tu le pusiste un numero en este caso fue

1000000 ten en cuenta que esos no son milisegundos.

y a las velocidades que corren las PC hoy en dia, ese Delay que le diste es casi NULO, es por eso que no debes ver la "animacion"

lo que te propuso Juan Carlos es que uses un Timer, que cuente 1 ms

de manera que, suponiendo que este el personaje sobre la flor, cuente 10 mS para empezar a abrirse.
cuente 20 mS que va a mostar la animacion de la flor abierta
y que una vez trancurridos esos 30 mS que mostres la animacion del char comido.

con gusto te ayudaria a implementar FPS, pero de pyton voy muerto.

ojo, no confundas FPS con timers. si no sabes lo que son los FPS pregunta y te lo respondere.

Saludos Lucesita.
lucesita
 
Mensajes: 57
Registrado: Mié Mar 12, 2008 2:49 pm

PLC

Notapor PLC » Mié Abr 30, 2008 3:12 am

En lo que me propone juan carlos no veo nada de timer, sino una variable que se decrementa y se comprueba su valor, casi lo mismo que tengo hecho, ya se que FPS es frames por segundos, ahora si mi problema se puede resolver con eso me haria falta algun ejemplo en python, o en c++ con sdl y tal vez pudiera migra el codigo.
PLC
 
Mensajes: 21
Registrado: Lun Feb 11, 2008 12:02 am

Notapor lucesita » Mié Abr 30, 2008 4:03 pm

No creo que te sirva migrar el codgio, o si eso queda a tu criterio.

en c++/sdl

Código: Seleccionar todo
#include "SDL/SDL.h"

int ticks_ini;
int ticks_fin;

void ResetTime()
{
    ticks_ini = SDL_GetTicks();
}

int GetCurrentTime()
{
    ticks_fin = SDL_GetTicks();
    return ticks_fin - ticks_ini;
}

// Aqui ya tienes las funciones que te manejaran el timer con resolucion de milisegundos
//ahora imagina que tiene ya tu loop implementado

int main()
{
//cosas que desees hacer
     MOSTRA_ANIM_CERRADA();

     if (esta_encima == true)
     {
         MOSTRA_ANIM_ABIERTA();
         ResetTime(); //reseteamos el contador
         while (GetCurrentTime() < 20){}   // Esto quiere decir que mientras el contador retorne numeros menor a 20 que no haga nada, cada unidad representa 1 ms.
         
     }

}


fijate creo que podes hacerlo tranquilamente con pyton, pero la verdad que si te digo te miento, de todos modos los timers son cosa de cada dia, asi que pyton es seguro que tendra una libreria para manejo de timers.[/code]
lucesita
 
Mensajes: 57
Registrado: Mié Mar 12, 2008 2:49 pm

Notapor hugoruscitti » Jue May 01, 2008 12:19 am

Saludos, tu consulta se puede resolver utilizando dos técnicas: por un lado
tienes la necesidad de mostrar animaciones a poca velocidad y por otro la
administración de varios estados.

Las animaciones se pueden gestionar mediante contadores, no es muy complejo. Una
buena forma de implementarlo es con un contador.

El tema de los estados es un poco mas difícil, hay un artículo en la web que
trata sobre el tema (autómatas) aunque esa no es la única forma de manejarlos.

En este mensaje me he tomado el tiempo de escribir un programa de ejemplo que
hace algo similar a lo que necesitas:

Imagen



El programa de ejemplo muestra una caja, cuando pulsas la tecla espacio la
caja se abre (si estaba cerrada) o se cierra (si estaba abierta).

Sería bueno que lo analices con miras a adaptarlo a tu programa. Pero claro, ten
en cuenta que al principio puede parecer mas complicado de lo que en realidad
es.

A grandes rasgos, puedes pensar que la Flor (o planta carnívora) es un objeto
que puede "estar" en uno de los siguientes estados:

- Abierta
- Cerrada
- Abriéndose
- Cerrándose

cada uno de estos estados se puede diseñar mediante objetos diferentes, y a su vez, la
Flor puede ser un objeto que tiene una referencia al objeto de estado actual. Un lio...

Saludos.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor PLC » Lun May 05, 2008 5:40 am

Eso era lo que me hacia falta realmente, pero me surge un nuevo problema, que pasa, supongamos que en vez de un cofre, tenemos tres cofres y queremos que el primero se abra o cierre si apretamos space, y que los otros dos hagan los mismo si apretamos otras teclas respectivamente. Digo esto porque en mi juego tengo tres flores y la animacion no se pude ver en todas al mismo tiempo, sino en la flor donde el personeje le pase por encima, intente lograr esto pasandole a la funcion update del cofre el objeto de mi personaje, y el numero de la flor, para despues preguntar por la posicion de mi personaje y el numero de la flor valga la redundancia, pero no me pincha ningun invento.


import pygame
from pygame.sprite import Sprite


class Comedora(Sprite):
def __init__(self,x,y):
Sprite.__init__(self)

self.cargar_imagenes()
self.change_state(Cerrada(self))
self.rect = self.cerrada.get_rect()
self.rect.move_ip(x, y)


def cargar_imagenes(self):
self.cerrada = pygame.image.load('img/comedora_0.bmp')
self.cerrada.set_colorkey((255, 255, 255))
self.cerrada.convert_alpha()

self.abriendo = pygame.image.load('img/comedora_1.bmp')
self.abriendo.set_colorkey((255, 255, 255))
self.abriendo.convert_alpha()

self.abierta = pygame.image.load('img/comedora_2.bmp')
self.abierta.set_colorkey((255, 255, 255))
self.abierta.convert_alpha()
self.frames=[self.cerrada,self.abriendo,self.abierta]

def change_state(self, state):
self.state = state

def set_frame(self, index):
self.image = self.frames[index]



def update(self,zeek,n):
if(zeek.rect.x==213 and zeek.rect.y==2 and n==1):
self.state.update(zeek,n)
elif(zeek.rect.x==35 and zeek.rect.y==37 and n==2):
self.state.update(zeek,n)
if(zeek.rect.x==426 and zeek.rect.y==108 and n==3):
self.state.update(zeek,n)


class Cerrada:

def __init__(self, comedora):
self.comedora = comedora
self.comedora.set_frame(0)

def update(self,zeek,n):
if(zeek.rect.x==213 and zeek.rect.y==2 and n==1):
self.comedora.change_state(Abriendo(self.comedora))
elif(zeek.rect.x==35 and zeek.rect.y==37 and n==2):
self.comedora.change_state(Abriendo(self.comedora))
elif(zeek.rect.x==426,zeek.rect.y==108,n==3):
self.comedora.change_state(Abriendo(self.comedora))

Código: Seleccionar todo
class Abierta:

    def __init__(self, comedora):
       self.comedora = comedora

    def update(self,zeek,n):
      if(zeek.rect.x==213 and zeek.rect.y==2 and n==1):
        self.comedora.change_state(Cerrando(self.comedora))
      elif(zeek.rect.x==35 and zeek.rect.y==37 and n==2):
        self.comedora.change_state(Cerrando(self.comedora))
      elif(zeek.rect.x==426,zeek.rect.y==108,n==3):
        self.comedora.change_state(Cerrando(self.comedora))

class Abriendo:

    def __init__(self, comedora):
        self.comedora = comedora
        self.frames = [2,3]
        self.delay = 0

    def update(self,zeek,n):
        self._update_animation()

    def _update_animation(self):
        self.delay -= 1
        if self.delay <= 0:
            self.delay = 20
            try:
                next_frame = self.frames.pop(0)
                print next_frame
                self.comedora.set_frame(next_frame -1)
            except:
                print "El cofre a terminado de abrirse."
                self.comedora.change_state(Abierta(self.comedora))

class Cerrando:

    def __init__(self, comedora):
        print "Entrando en el estado:", self
        self.comedora = comedora
        #self.frames = [2, 3][::-1]
        self.frames = [3, 2]
        self.delay = 0

    def update(self,zeek,n):
        self._update_animation()

    def _update_animation(self):
        self.delay -= 1

        if self.delay <= 0:
            self.delay = 20
            try:
                next_frame = self.frames.pop(0)
                self.comedora.set_frame(next_frame -1)
            except:
                print "El cofre ya se ha cerrado."
                self.comedora.change_state(Cerrada(self.comedora))


En progama principal crearia mis flores comedoras
comedora1=Comedora(214,37)
comedora2=Comedora(34,72)
comedora3=Comedora(427,143)

En ciclo principal de juego tendria entonces que llamar a
comedora1.update(zeek,1)
comedora2.update(zeek,2)
comedora3.update(zeek,3)

pero este invento no me pincha
PLC
 
Mensajes: 21
Registrado: Lun Feb 11, 2008 12:02 am

Notapor hugoruscitti » Lun May 05, 2008 6:27 pm

PLC escribió:Eso era lo que me hacia falta realmente, pero me surge un nuevo problema, que pasa, supongamos que en vez de un cofre, tenemos tres cofres y queremos que el primero se abra o cierre si apretamos space, y que los otros dos hagan los mismo si apretamos otras teclas respectivamente.


Tendrías que ver como hacer esto en el ejemplo que te envié,
es muy sencillo de lograr. Ten en cuenta que debes llamar
todo el tiempo a la función update por cada caja (o flor).

PD: y usa la etiqueta "code" si quieres colocar código en el foro.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina


Volver a Artículos, traducciones y documentación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados