PyGame hacer salto con un sprite

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

PyGame hacer salto con un sprite

Notapor Nexusblake » Jue Nov 10, 2011 10:21 pm

Hola, soy nuevo por aqui y como vi tantos ejemplos en la web y ayuda en los foros, quize formar parte de la comunidad. Tenia una consulta con respecto a pygame y saltos de mi sprite en un juego de plataforma que estoy realizando. lo que pasa esk tengo lo principal mi personaje se mueve de izquierda a derecha perfectamente, lo que ocurre esque, necesito que salte tengo los sprites del salto y todo y tengo conocimiento de como ir guardando las cordenadas del personaje en un array y asi realizar el movimiento del mismo, busque en el foro y encontre un ejemplo de salto que lo isieron con un cubo, lo comprendi, pero al momento de querer aplicarlo en mi juego no pude, aparte de que los ejemplos que estan en la web son muy complejos para mi. si es posible que me pudieran explicar el codigo o mostrarme algun ejemplo con un sprites porfavor, al momento de presionar por ejemplo el espacio y salte
Nexusblake
 
Mensajes: 3
Registrado: Mar Nov 08, 2011 12:10 am

Re: PyGame hacer salto con un sprite

Notapor Barajas » Vie Nov 11, 2011 12:32 am

Podrías mostrar el código que llevas, eso ayuda mucho más de lo que crees :)

Bueno, aquí esta el código de un muy sencillo plataformas. Nota en la clase personaje, el estado salto :)
Código: Seleccionar todo
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pygame.locals import *
import pygame, os, sys

#función para cargar imagenes
def load_image(name, colorkey=False):
    fullname = os.path.join(name)
    try:
        image = pygame.image.load(fullname)
    except pygame.error, message:
        print 'No se puede cargar la imagen: ', fullname
        raise SystemExit, message
    image = image.convert()
    if colorkey:
        colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, RLEACCEL)
    return (image)

#Creamos un "nivel"
class Nivel():
    def __init__(self, Ancho, Alto):
        self.bloques = []
        imagen = load_image("brock.png")
        filas = 3
        columnas = 9
        #corto la imagen de los tiles
        tile_w = imagen.get_width () / columnas
        tile_h = imagen.get_height () / filas
        for f in xrange (filas):
            for c in xrange (columnas):
                rect = c * tile_w , f * tile_h , tile_w, tile_h
                #y guardo los pedasos en una lista
                self.bloques.append(imagen.subsurface(rect).copy ())
        #genero un mapa muy simple
        self.mapa = [
               [-1,-1,-1,-1,-1],
               [-1,-1,-1,-1,-1],
               [-1,-1,-1,-1,-1],
               [-1,-1,-1,-1,-1],
               [ 1, 1, 1, 1, 1]
               ]
        #un par de variables para controlar las coliciones
        espaciox = 500/len(self.mapa)
        espacioy = 500/len(self.mapa[0])
        self.dimenciones = (espaciox, espacioy)
    def imprimir(self,superficie):
        # Dibuja sobre una superficie todos los bloques del nivel.
        numero_de_filas = len( self.mapa )
        numero_de_columnas = len( self.mapa[0] )
        espaciox = superficie.get_width()/numero_de_filas
        espacioy = superficie.get_height()/numero_de_columnas
        self.dimenciones = (espaciox, espacioy)
        for fila in range(numero_de_filas):
            for columna in range(numero_de_columnas):
                pos_x = columna * espaciox
                pos_y = fila * espacioy
                #en caso de que sea distinto de -1
                if self.mapa[fila][columna] != -1:
                    #imprimo la imagen indicada en el mapa
                    index = self.mapa[fila][columna]
                    bloque = self.bloques[index] #aqui la tomo
                    #la escalo
                    bloque = pygame.transform.scale(bloque,(espaciox,espacioy))
                    superficie.blit(bloque, (pos_x, pos_y))
   
    def puede_pasar(self, posx, posy):
        #función que resive una posición y regresa un valor boleano
        columna = int( posx / self.dimenciones[0] )
        fila = int( posy / self.dimenciones[1] )
        try:
            celda = int(self.mapa[fila][columna])
        except:
            # si no puede obtener la celda prohíbe pisar ahí
            return False
        #si la celda distinta de nuestro "valor nulo"
        if celda != -1:
            #es obvio que no puede pasar
            return False
        #si no sucede eso, en ese caso, puede pasar
        return True
    def distancia_al_suelo(self, pos, rango):
        # función que mide la distancia al suelo en un rango
        posx, posy = pos
        contador = 0
        while contador < rango:
            contador += 1
            if not(self.puede_pasar(posx, posy + contador)):
                #nos regresa la distancia al suelo
                return contador
        #si regresa el rango, indica que no encuentra el suelo.
        return rango
       

#creo una clase para gestionar las animaciones
#un uso alternativo, es "partir" la imagen
class AnimacionDeArchivo():
    def __init__(self, columnas, filas, image):
        #inicializamos las características para la animación
        self.lista_frames = []
        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 ())
        #variabloes que nesesito para la animación
        self._frame = 0
        self.inicio = pygame.time.get_ticks()
        self._delay = 1000/15
        self.ultima_act = 0 #ultima
    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] ]

#primero, creamos una clase para nuestro personaje
class Personaje(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        imagen = load_image("eva.png", True)
        self.animacion = AnimacionDeArchivo( 4, 4, imagen)
        self.image = self.animacion.Frame_es( [1] )
        self.rect = self.image.get_rect()
        self.gravedad = 0.1
        self.dx = 5
        #algunas personas usaran dy
        #yo uso fuerza salto....
        self.fuerza_salto = 0
        #si, es menos practico que dy...
       
        #definimos la posición inicial
        self.posx = 250
        self.posy = 250
        #creamos una variable para guardar el estado
        self.estado = "Parado"
        # y una pequeña verción del nivel
        self.esenario = Nivel(500,500)
    def estado_parado(self):
        #lo que hace en el estado parado
        #self.mover, es una función para gestionar movimiento-animación
        self.mover()
        key=pygame.key.get_pressed()
        if key[K_UP]:
            self.estado = "Salta"
            self.fuerza_salto = 5 #inicializamos la fuerza del salto...
        #en caso de que este en una plataforma...
        distancia = self.esenario.distancia_al_suelo(self.rect.midbottom, 10)
        #y la distancia que lo separa del suelo sea mayor a 10
        if distancia >= 10:
            #significa que esta cayendo al suelo...
            self.estado = "Salta"
            self.fuerza_salto = 0 #por eso ponemos la fuerza salto en 0
    def estado_saltar(self):
        #la serie de acciones a realizar en el estado salta
        self.posy -= self.fuerza_salto # a la posición x añadimos la fuerza_salto
        self.fuerza_salto -= self.gravedad # a la fuerza salto, añadimos la de la gravedad
        self.mover() #llamamos a la función mover...
        #deja de subir y comienza a caer...
        if self.fuerza_salto < 0:
            #verifico la distancia que me separa del suelo
            distancia = self.esenario.distancia_al_suelo(self.rect.midbottom, 10)
            if distancia <= 5:
                #si es menor a cierto rango...
                #cambio a el estado parado
                self.estado = "Parado"
    def mover(self):
        #aqui definimos la función mover...
        key=pygame.key.get_pressed()
        if key[K_RIGHT]:
            #sección de animación....
            if self.estado != "Salta":
                #si no esta saltando...
                image = self.animacion.Frame_es( [4,4,5,5,6,6,7,7] )
                #volteamos la imagen
                self.image = pygame.transform.flip(image, True, False)
            else:
                #si salta, la imagen es...
                image = self.animacion.Frame_es( [5,5], True )
                self.image = pygame.transform.flip(image, True, False)   
            #sección de movimiento
            if self.posx < 500:
                self.posx += self.dx
            else:
                self.posx = 500
        #lo mismo, pero para el otro lado...
        elif key[K_LEFT]:
            if self.estado != "Salta":
                self.image = self.animacion.Frame_es( [4,4,5,5,6,6,7,7] )
            else:
                self.image = self.animacion.Frame_es( [5,5], True )
            if self.posx > 0:
                self.posx -= self.dx
            else:
                self.posx = 0
        #en caso de que no se mueva en el eje x
        else:
            if self.estado != "Salta":
                self.image = self.animacion.Frame_es( [1],  Reset = True)
            else:
                self.image = self.animacion.Frame_es( [10,10], True )
    def update(self):
        #colocamos el centro de la imagen en la posición...
        self.rect.center = (self.posx,self.posy)
        #si el estado es tal...
            #llamo a su metodo
        if self.estado == "Salta":
            self.estado_saltar()
        if self.estado == "Parado":
            self.estado_parado()
def main():
    pygame.init()
    pantalla = pygame.display.set_mode((500,500))
    personaje = Personaje() #creo mi personaje...
    sprite = pygame.sprite.RenderClear()
    sprite.add(personaje)
    continuar = True
    nivel = Nivel(500,500) #creo mi nivel
    reloj = pygame.time.Clock()
    while continuar:
        #relleno la pantalla
        pantalla.fill((150,150,200))
        for evento in pygame.event.get():
            if evento.type==pygame.QUIT:
                continuar=False
                pygame.quit()# salir del juego
                sys.exit()
        sprite.draw(pantalla) # dibujo mi personaje...
        nivel.imprimir(pantalla) # dibujo mi nivel...
        personaje.update() # actualizo a mi personaje...
        reloj.tick(60)
        pygame.display.update()

main()




Espero que te ayude :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: PyGame hacer salto con un sprite

Notapor Nexusblake » Vie Nov 11, 2011 1:55 am

Muchas gracias!! genial era exactamente lo que queria :D, vere si al terminar el proyecto logro subirlo para que lo vean, una consulta que usas para programar? algun ide o solo terminal, yo uso netbeans, pregunto por si hay algun otro mejor para usar D:, eso seria gracias nuevamente :o

------
edit: una consulta, me podrias explicar la parte donde obtienes los distintos estados de la imagen? es que en mi codigo tengo definido los distintos sprites en un arreglo y los voy agregando de uno en uno segun los pixeles de la imagen, dejandome un gran trozo de codigo..
Nexusblake
 
Mensajes: 3
Registrado: Mar Nov 08, 2011 12:10 am

Re: PyGame hacer salto con un sprite

Notapor MrBB4 » Sab Nov 12, 2011 1:49 am

Buenas. Yo hace poco empecé a usar Spyder. Es bastante comodo en comparación a los otros pocos ides que he utilizado, aunque hay otros más profecionales, pero este se enfoca en python asi que te va a ayudar mucho. lo puedes encontrár en este Link.

Saludos y suerte en tu proyecto ;)
Avatar de Usuario
MrBB4
 
Mensajes: 49
Registrado: Mar Dic 14, 2010 11:39 pm
Ubicación: Purto Madryn, Chubut, Argentina.

Re: PyGame hacer salto con un sprite

Notapor Barajas » Mar Nov 15, 2011 3:00 am

Hola, ha pasado un tiempo jeje...
Nexusblake escribió:edit: una consulta, me podrias explicar la parte donde obtienes los distintos estados de la imagen? es que en mi codigo tengo definido los distintos sprites en un arreglo y los voy agregando de uno en uno segun los pixeles de la imagen, dejandome un gran trozo de codigo..

Bueno, la magia esta en la clase "Animación", que lo que realiza es cortar la imagen como si fuera una matriz, (por eso cuando se "incializa", pide como argumento columnas y filas).
Código: Seleccionar todo
class AnimacionDeArchivo():
    def __init__(self, columnas, filas, image):
        #inicializamos las características para la animación
        self.lista_frames = []
        tile_w = image.get_width () / columnas
        tile_h = image.get_height () / filas
        #esto corta mi imagen como si recorriera una matriz
        for f in xrange (filas):
            for c in xrange (columnas):
                rect = c * tile_w , f * tile_h , tile_w, tile_h
                #y esta parte añade lo que "corta" a un arreglo que las contiene
                self.lista_frames.append(image.subsurface(rect).copy ())
        #variables que necesito para la animación
        self._frame = 0
        self.inicio = pygame.time.get_ticks()
        self._delay = 1000/15
        self.ultima_act = 0 #ultima
    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] ]

Ahora, en el método "Frame_es" le doy como argumento que pedazos de la imagen quiero para formar la animación, por ejemplo:
Código: Seleccionar todo
#mi imagen:
    |aaaa|
    |aaaa|
    |aaaa|
#mi imagen dividida en columnas y filas:
    |0|1|2|
    |3|4|5|
    |6|7|9|


Y no me preocupo de nada más...
no sé si eso responda la duda... :)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am

Re: PyGame hacer salto con un sprite

Notapor Barajas » Mar Nov 15, 2011 3:06 am

...Y sobre la duda del IDE, yo en lo personal utilizo principalmente el Gedit y la terminal (en ocasiones el Dr. Python) cuando es en Linux. En Windows, me doy por bien servido con el incluido por Python... (muy a pesar de que es algo "feo"... :P)
Vi veri universum vivus vici
Avatar de Usuario
Barajas
 
Mensajes: 209
Registrado: Mar Nov 16, 2010 12:06 am


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

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