Solicitud de tutorial o breve explicación

Solicite, consulte o publique recursos de referencia para desarrolladores.

Solicitud de tutorial o breve explicación

Notapor gabofer82 » Lun Feb 28, 2011 9:49 pm

Hola:

Antes que nada quiero agradecer a los organizadores de este sitio por tan buen aporte que hacen a los colegas y a quienes empezamos con esto de la programación en Python. Felicitaciones!!!

Ahora si dire mi solicitud:

Me gustaría que pudieran hacer un tutorial o alguna explicación sobre como se realizan animaciones con spritesheets utilizando pygame, si ese tutorial existe por favor posteen la url, porque solo he encontrado sobre el tema en tutoriales sobre XNA.

Así que muchas gracias a todos quienes me puedan ayudar o accedan a este pedido por cristiana caridad.

Saludos a todos!!! :D :D :D
gabofer82
 
Mensajes: 2
Registrado: Lun Feb 28, 2011 9:05 pm
Ubicación: Salto

Re: Solicitud de tutorial o breve explicación

Notapor shackra » Sab Mar 05, 2011 12:50 am

actualmente yo trabajo en un ejemplo de animación, pero con PySFML, aun no esta terminado y le falta mucho para estar listo... lo único que puedes hacer es esperar a que yo termine mi ejemplo :-|.
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica

Re: Solicitud de tutorial o breve explicación

Notapor shackra » Vie Mar 11, 2011 11:03 pm

bueno, como te prometí, te traje un código donde muestro como hacer una animación de sprites usando un spritesheet. Debo subir este ejemplo a Bitbucket.org, aun así, no puedo, así que mejor dejo el código aquí. tomad en cuenta que este código esta hecho con PySFML, aun así, podrías estudiarlo para adaptarlo a Pygame o en dado caso, mejor usas PySFML ~_~:

spritesheet: Imagen

Código: Seleccionar todo
#! /usr/bin/env python
#-*- coding: utf-8 -*-

from PySFML import sf

class MySprite(sf.Sprite):
    """ extendemos la clase sf.Sprite para dotarla de nuevos atributos y funciones
    que necesitamos para trabajar mas comodamente para con nuestros personajes
    del juego. """
   
    # quizás este sea el ejemplo con animación mas complejo que desarrollo
    # hasta el momento. De seguro existen mejores formas de animar un Sprite
    # con tantos frames y tan complejo, así que de seguro existirán maneras
    # mejores y mas elegantes de manejar animaciones que la que expondré acá
    # Usaremos a Havoc, del mitico juego Metal Warrior para Snes.
   
    def __init__(self, rejilla):
        # usamos la clase sf.Image para cargar una imagen dada por **rejilla**
        self.imagen = sf.Image()
        self.imagen.LoadFromFile(rejilla)
        # Hacemos el fondo transparente
        colorfondo  = self.imagen.GetPixel(0, 0)
        self.imagen.CreateMaskFromColor(colorfondo)
        # asignamos la imagen a nuestra clase MySprite
        sf.Sprite.__init__(self, self.imagen)
        # colocamos el Sprite a la mitad de la pantalla
        self.SetX(400)
        self.SetY(150)
        # creamos un par de atributos para recordar el orden de los frames de
        # animacion.
        # aunque tambien se podria diseñar un sistema de "frame unico" que seria
        # una identificacion para dado frame dentro del "Sprite Sheet".
        # Se implentara esa tecnica en el proximo ejemplo.
        # (mejor ignoren esos comentarios, ni siquiera sé que estoy haciendo).
        self.frame_pos   = 0
        # para este ejemplo el Sprite no se movera a ningun lado
        # se quedara quieto en el centro de la pantalla.
        # cambiamos el nombre de un atributo, en lugar de self.cambia
        # usaremos self.tiempo que es mas adecuado.
        self.tiempo      = 0.0
        # con este atributo podemos asignar un numero a cierta coordenadas para
        # recortar la imagen del Sprite del Sprite Sheet
        self.coord_frm   = {}

    def animar(self, ventana, orientacion, frames):
        """ anima el Sprite, no lo mueve (por el momento). """
        self.FlipX(orientacion)
       
        # revisamos si la cantidad de tiempo transcurrido es mayor o igual a 30
        # cuadros de animacion o 1/30. si es asi, pasamos al siguiente frame,
        # obtenemos de vuelta las coordenas del rectangulo correspondiente a ese
        # cuadro de la animacion para que luego sea dibujado en pantalla...
        # asi sucesivamente.
        # Basicamente asi es una animacion de sprites, claro esta, existen muchas
        # variantes dependiendo de las necesidades del desarrollador.
        #
        # Mi necesidad en este codigo era la de desarrollar una animación parecida
        # a la del juego original, Metal Warrior para SNES.
        if self.tiempo >= 1/30:
            self.frame_pos = self.frame_pos + 1
            try:
                coord = self.getframe(frames[self.frame_pos])
                # sf.IntRect no acepta tuplas, por eso este raro hack...
                self.SetSubRect(sf.IntRect(coord[0], coord[1],\
                                           coord[2], coord[3]))
            except IndexError:
                if self.tiempo >= 1/30:
                    self.frame_pos = 0
        else:
            self.tiempo = self.tiempo + ventana.GetFrameTime()

    def addframe(self, numero, left, top, right, bottom):
        """ añade un frame para la animacion.
       
        las coordenadas left, top, right, bottom, pertenecen al cuadro a recor
        tar del sprite sheet de nuestro sprite, asignarle un numero a esta coor
        denadas nos permite identificar y usar dicho frame para la animacion de
        nuestro Sprite. """
        self.coord_frm[numero] = left, top, right, bottom
   
    def setframe(self, numero):
        """ inicia el primer frame de la animacion que vamos a hacer. """
        self.frame = numero
        coord = self.getframe(self.frame)
        # sf.IntRect no acepta tuplas, por eso este raro hack...
        self.SetSubRect(sf.IntRect(coord[0], coord[1],\
                                   coord[2], coord[3]))
           
    def getframe(self, numero):
        """ retorna las coordenadas del frame en el sprite sheet. """
        try:
            return self.coord_frm[numero]
        except KeyError:
            print "no existe coordenas para el frame {0}".format(numero)
            return 0, 0, 1, 1
       
if __name__ == "__main__":
    # la sentencia de arriba previene que este codigo se ejecute cuando es
    # importado desde otro fichero de python por import
   
    # Como que me da mucha pereza usare los objetos de color de sf.Color,
    # Vamos a usar variables para esos objetos de color.
    Black   = sf.Color.Black

    # Creamos la ventana del juego
    ventana = sf.RenderWindow(sf.VideoMode(800, 300), "Prueba 7 de PySFML por Shackra")
    ventana.SetFramerateLimit(30)

    # creamos una instancia de sf.Event para el manejo de los eventos del juego
    evento = sf.Event()

    # obtenemos el input de los eventos de la ventana creada, mira sf.Input para mas informacion
    # parece ser que no es necesario declarar este objeto dentro del loop para actualizar su estado...
    entrada = ventana.GetInput()

    # cargamos el SpriteSheet
    havocr = MySprite("havocr2.png")

    # TODO: esto podria ir en el __init__ y no acá !!
    # cargamos los frames de havoc para la animacion de caminar
    #               frame, left, top, right, bottom
    havocr.addframe(1,      339,   0,   373,     45)
    havocr.addframe(2,      306,   0,   338,     45)
    havocr.addframe(3,      272,   0,   304,     45)
    havocr.addframe(4,      238,   0,   269,     45)
    havocr.addframe(5,      204,   0,   236,     45)
    havocr.addframe(6,      170,   0,   202,     45)
    havocr.addframe(7,      136,   0,   168,     45)
    havocr.addframe(8,      102,   0,   136,     45)

    # seteamos el primer cuadro de la animacion para el Sprite
    havocr.setframe(1)

    # variables para terminar el bucle del juego
    salir = False
    # bucle principal del juego
    while not salir:
        while ventana.GetEvent(evento):
            if evento.Type == sf.Event.Closed:
                salir = True
           
            if evento.Type == sf.Event.KeyPressed:
                if evento.Key.Code == sf.Key.Escape:
                    salir = True
                if evento.Key.Code == sf.Key.Right:
                    # movemos a havocr a la derecha
                    havocr.animar(ventana, False, [1,2,3,4,5,6,7,8])
                if evento.Key.Code == sf.Key.Left:
                    # movemos a havocr a la izquierda
                    havocr.animar(ventana, True, [1,2,3,4,5,6,7,8])
       
            # Limpiamos la ventana del juego
            ventana.Clear(Black)
            # dibujamos a Havocr
            ventana.Draw(havocr)
            # Cambiamos los buffers de video
            ventana.Display()
           
    # no olvides limpiar y cerrar con llave el local cuando termines de jugar :)
    ventana.Close()
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica

Re: Solicitud de tutorial o breve explicación

Notapor gabofer82 » Lun May 23, 2011 12:34 am

Hola shackra!!

Muchas gracias por tu tutorial!!

Como estuve alejado de python y pilas por cuestiones laborales (lease mucho php, javascript y el resto de la pandilla) no te contesté antes.

Voy a aprovechar tu material, despues te cuento.

Saludos!!!
gabofer82
 
Mensajes: 2
Registrado: Lun Feb 28, 2011 9:05 pm
Ubicación: Salto

Re: Solicitud de tutorial o breve explicación

Notapor shackra » Mié May 25, 2011 5:47 pm

de nada!

en el repositorio que hice varias semanas ya hay mas ejemplos, tambien Hugo ayudo confeccionando algunos ejemplos mas :)
pondria el enlace al repositorio pero hoy parece que el servidor de Bitbucket.org esta caido :S
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica

Re: Solicitud de tutorial o breve explicación

Notapor Barajas » Mié Sep 07, 2011 12:12 am

Bueno, utilizando la misma imagen...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
Alto=400
Ancho=600
from coat import *
from pygame import *
#una función que carga las imagenes :)
def carga_imagen(name, alfa=False, rect=False, colorkey=None):
#crea una ruta a la carpeta de datos
#al escribirlo de esa forma, nos aseguramos
#de que pueda abrir en todos los S.O.
#donde este instalado python
fullname = os.path.join(name)
#comprobamos si existe la imagen
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'No se puede cargar la imagen: ', fullname
raise SystemExit, message
#combierte la imagen para que pygame la pueda usar
image = image.convert()
#En este punto asignamos el colorkey
#es decir, un color de base al que se
#borrara dejando solo el canal alfa (transparencia)
if alfa:
colorkey = image.get_at((0, 0))
image.set_colorkey(colorkey, RLEACCEL)
if not(alfa) and colorkey != None:
image.set_colorkey(colorkey, RLEACCEL)
#devuelve la imagen y la recta de la imagen
if rect:
return (image, image.get_rect())
else:
return (image)

#este es parte de unas clases que he
# desarrollado para manejar los sprites mejor
#aun esta "verde", hay que añadir cosas... y mejor ducumentación
class AnimacionDeArchivo():
def __init__(self, Archivo, Tabla=None, Diccionario=None, Colorkey=None):
#De lo UNICO que se encarga esta función es de regresar
#las imagenes de animación y nada mas, lo de preguntar
#rects le compete a la clase del sprite :).
self.lista_frames = []
#si no hay un color de trasparencia especifico, lo carga con el color
#del pixel (0,0)
if Colorkey == None:
image = carga_imagen(Archivo, alfa=True, rect=False, colorkey=None)
else:
image = carga_imagen(Archivo, alfa=False, rect=False, colorkey=Colorkey)
if Diccionario != None and Tabla != None:
print "No se pueden usar los parametros'Tabla' y 'Diccionario' al mismo tiempo"
return False
#partimos la imagen en filas y columnas
if Tabla != None:
columnas, filas = Tabla
tile_w = image.get_width () / columnas
tile_h = image.get_height () / filas
for f in xrange (filas):
for c in xrange (columnas):
rect = c * tile_w , f * tile_h , tile_w, tile_h
self.lista_frames.append(image.subsurface(rect).copy ())
#o en las cordenadas que marque un diccionario...
if Diccionario != None:
for llave in Diccionario:
rect = Diccionario[Llave]
ima = image.subsurface(rect).copy ()
self.lista_frames.append(ima)
self._frame = 0
self.inicio = pygame.time.get_ticks()
self._delay = 1000/15
self.ultima_act = 0 #ultima
#función para redimencionar todas las imagenes del sprite
def redimencion(self, dimencion):
for i in range(len(self.lista_frames)):
frame_i = self.lista_frames[i]
frame = pygame.transform.scale(frame_i, dimencion)
self.lista_frames[i] = frame
#función para hacer todas las imagenes con una trasparencia
def set_alpha(self, alpha):
for i in range(len(self.lista_frames)):
frame_i = self.lista_frames[i]
frame_i.set_alpha(alpha)
self.lista_frames[i] = frame_i
#la funcion que hace la magia :D
def Frame_es(self, Lista_anima = [0], Reset = False, Frame_return = False):
if Reset:
self._frame = 0
if pygame.time.get_ticks() - self.ultima_act > self._delay:
self._frame += 1
if self._frame >= len(Lista_anima):
self._frame = 0
self.ultima_act = pygame.time.get_ticks()
if Frame_return:
return self.lista_frames[ Lista_anima[self._frame] ], self._frame
else:
return self.lista_frames[ Lista_anima[self._frame] ]

def Main():
pygame.init() #incializamos pygame
#creamos abajo, una pantalla de dimenciones Ancho Alto
pantalla=pygame.display.set_mode((Ancho,Alto))
#le ponemos un titulo
pygame.display.set_caption("Animando un sprite")
#Inicializo la clase anima
anima = AnimacionDeArchivo(Archivo="havoc_basic_spritesheet_by_mrshackra-d3bezye.png",
Tabla = (11,1))
anima.redimencion((50,100)) #la hago mas grande
continuar = True
while continuar:
for evento in pygame.event.get():
if evento.type==pygame.QUIT:
pygame.quit()
continuar=False
sys.exit()#creo que esto es redundante
pantalla.fill((250,250,250))#rellenamos la pantalla de blanco
#coloco la imagen en la mitad de pantalla
pantalla.blit(anima.Frame_es([10,9,8,7,6,5,4,3]), (Ancho/2,Alto/2))
pygame.display.flip()

Main()


Si tienes alguna duda, solo pregunta :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am


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 1 invitado