Presentación y dudas

Consulte acerca de programas, técnicas, algoritmos etc.

Presentación y dudas

Notapor Facon » Mar Jun 23, 2009 4:32 pm

Buenas a todos, vine aquí con la intención de aprender a hacer un videojuego en 3D y medianamente complejo, con un aspecto similar al de la imagen, añadiendo algo de historia e interactivo.

Imagen

Pero como bien se, para llegar hasta algo similar a eso uno tiene que recorrer un largo camino, el mio de hecho es aún más largo pues empiezo de 0, solo sabiendo programación.

Para empezar lo mejor es crearte un prototipo en 2D de lo que vas a hacer en 3D, para ello sigo la recomendación que hacéis de Python + PyGame, que permite un desarrollo rápido.

Bueno he conseguido hacer algunas cosillas:

http://www.mediafire.com/?sharekey=443477709d349618af924764f9977b1de04e75f6e8ebb871

Código: Seleccionar todo
#!/usr/bin/env python

#Import Modules
import random
import string
import sys
import os, os.path
import pygame
from pygame import *
from pygame.sprite import Sprite

class Player(Sprite): # This class is YOU
        def __init__(self):
                Sprite.__init__(self)
                self.image11=pygame.image.load('player11.bmp').convert()
                self.image12=pygame.image.load('player12.bmp').convert()
                self.image31=pygame.image.load('player31.bmp').convert()
                self.image32=pygame.image.load('player32.bmp').convert()
                self.image51=pygame.image.load('player51.bmp').convert()
                self.image52=pygame.image.load('player52.bmp').convert()
                self.image71=pygame.image.load('player71.bmp').convert()
                self.image72=pygame.image.load('player72.bmp').convert()
                self.image=self.image11
                self.image.get_at((0,0))
                self.image.set_colorkey(-1, RLEACCEL)
                self.rect=self.image.get_rect()
                self.posx = 0
                self.posy = 0

        def move(self, dir): # Movement
                if dir == "left" and self.posx > 0:
                        self.posx -= 5
                        if self.image == self.image71:
                                self.image = self.image72
                        else:
                                self.image = self.image71
                elif dir == "right" and self.posx <60> 0:
                        self.posy -= 10
                        if self.image == self.image11:
                                self.image = self.image12
                        else:
                                self.image = self.image11
                elif dir == "down" and self.posy < 60:
                        self.posy += 10
                        if self.image == self.image51:
                                self.image = self.image52
                        else:
                                self.image = self.image51
                               
                self.image.get_at((0,0))
                self.image.set_colorkey(-1, RLEACCEL)
                       
def main():
        random.seed()
        pygame.init()

        # Prepare stage
        screen = pygame.display.set_mode((200, 200))
        pygame.display.set_caption('Ventana')
        screen = pygame.display.get_surface()
        background = pygame.image.load('mapa.JPG').convert()

        screen.blit(background,(0,0))

        player = Player() # Instance of Player

        screen.blit(player.image, (0,0))
       
        music = pygame.mixer.Sound('contradanza.mp3')
        music.play(-1, 0)
       
        running = True
       
        while running:
                pygame.time.delay(10)
                pygame.display.flip()
                screen.blit(background,(0,0))
                screen.blit(player.image, (player.posx, player.posy))
                teclas = pygame.key.get_pressed()
                for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                                running = False               
                        elif event.type == KEYDOWN:
                                if event.key == K_d:
                                        player.move('right')
                                elif event.key == K_a:
                                        player.move('left')
                                elif event.key == K_w:
                                        player.move('up')
                                elif event.key == K_s:
                                        player.move('down')
                                elif event.key == K_q:
                                        running == False

if __name__ == '__main__': main()


Ahora bien tengo varias dudas:

1º Como puedo a partir de la imagen "Chara05.png", que adjunto en el archivo obtener resultados similares a los de "player11.bmp", "player12.bmp", etc...

2º Porque la música que adjunto "contradanza.mp3", no funciona mientras que la "magic.wav" si.

3º Como hago trasparencia a los "playerXX.bmp" que tienen fondo blanco.

4º Como puedo hacer que al mantener pulsado un botón de movimiento el personaje vaya en la dirección que le indica dicho botón, hasta que lo suelte.

Gracias por leeros este post, he intentar hecharme una mano ;) .

Un Saludo.
Facon
 
Mensajes: 7
Registrado: Mar Jun 23, 2009 2:07 pm

Notapor Geo » Mar Jun 23, 2009 10:09 pm

Yo utilizo C/C++/SDL y no python/pygame, pero espero pueda ayudarte un poco ;).

1.
No entendí si quieres crear muchas imágenes pequeñas o de una sola cargar todas las animaciones. Para lo primero, en cualquier programa de edición gráfica separas cada imagen, en el caso que muestras son de 24x32 pixeles. En cuanto a lo segundo, cargas la imagen completa, y luego copias o dibujas el cuadro que desees. Por ejemplo, si quieres dibujar la segunda animación de la primera línea usarías algo como:
Código: Seleccionar todo
screen.blit( chars, (player.posx, player.posy ), ( 24, 0, 24, 32 ) )

En el código sería un poco engorroso estar usando números para cambiar los cuadros, en su lugar, puedes crear los cuadros de animación para tu personaje al inicio de manera similar.

3.
La imagen tiene un atributo llamado colorkey que indica el color transparente, puedes hacer que el color blanco sea el transparente indicando a cada imagen su colorkey o, ya que en tu método move tienes el código para la transparencia, cambia esto:
Código: Seleccionar todo
self.image.set_colorkey(-1, RLEACCEL)

por esto:
Código: Seleccionar todo
self.image.set_colorkey(pygame.Color(255,255,255), RLEACCEL)


4.
Estás moviendo el personaje cada que ocurre un evento de tipo KEYDOWN, el cual solo se lanza en el momento que se presionó la tecla, pero después ya no. En su lugar, utiliza el estado de las teclas que obtuviste con pygame.key.getpressed():

Código: Seleccionar todo
                teclas = pygame.key.get_pressed()
                # cambio para que se mueva siempre que esté presionada la tecla
                if teclas[ K_d ]:
                        player.move( 'right' )
                elif  teclas[ K_a ]:
                        player.move( 'left' )



Por último, una recomendación, date una vuelta por los ejemplos de la web, encontrarás varios muy útiles:
http://www.losersjuegos.com.ar/referencia/ejemplos
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor Juanxo » Mar Jun 23, 2009 10:20 pm

Buenas :

1- Para conseguir lo que tu quieres puedes hacer varias cosas:
La primera, seria ir recortando los muñequitos uno a uno: Para ello, te puedes crear una función como la siguiente:

Código: Seleccionar todo
def imagen_a_tiles(self, image, rect, fila, columna):

        ancho_t = rect.width / columna

        alto_t = rect.height / fila

        tiles = []
     

        for f in range(fila):

            for c in range(columna):

                rect = c*ancho_t, f*alto_t, ancho_t, alto_t

                tiles.append(image.subsurface(rect).copy())

        return tiles


Esta función lo que hace es crearte una lista en la cual va añadiendo una imagen del tamaño y en la posicion que le indica rect
No es demasiado eficiente quizás, pero te quita de calcular la imagen cada vez.

Otra manera sería utilizar el tercer parametro del blit(imagen, posicion, area a imprimir), con el cual le dices que parte de la imagen quieres imprimir.

2- Si no estoy equivocado, creo que pygame no reproduce archivos .mp3, es algo parecido a lo que ocurre con SDL y SDL_mixer en C/C++

3- Te recomiendo crearte una función para la carga de imagenes, e ir poniendo a cada uno el colorkey ahi, porque de la manera en la que tu lo tienes, el color transparente siempre va a ser el mismo, el que se establece en la imagen11.

Código: Seleccionar todo
    def cargar_imagen(self, nombre, colorkey = None):

        ruta = os.path.join('datos', nombre)

        try:

            image = pygame.image.load(ruta)

        except:

            print "Error al cargar la imagen:", ruta

            raise SystemExit, message


        if colorkey is not None:

            image = image.convert()


            if colorkey == -1:

                colorkey = image.get_at((0,0))

            image.set_colorkey(colorkey, RLEACCEL)

        else:

            if image.get_alpha() is None:

                image = image.convert()

            else:

                image = image.convert_alpha()

        return image, image.get_rect()


4- El problema, si te fijas radica en que tu solo ejecutas el movimiento cuando el evento es de tipo KEYDOWN, vamos, solo la primera vez que pulsas. En vez de usar eso te recomiendo lo siguiente:

teclado = pygame.key.get_pressed()

if teclado[K_UP]:
mover arriba
if teclado[K_DOWN]:
mover abajo
if teclado[K_i]:
mostrar inventario

cosas asi...

Bueno espero no liarte demasiado, y darte la bienvenida a este sitio.

Por cierto, recomendarte que si acabas de empezar, te olvides del 3D por un rato, que hay que dominar la programación de juegos para centrarse en los aspectos d diseño, lógica, mates y cosas de ese estilo
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Facon » Mié Jun 24, 2009 6:30 pm

Primero y antes de nada muchas gracias por echarme una mano en este mundillo, ya que me habéis solucionado la mayoría de las cosas.

1º Según lo puesto por Geo, prefiero poner manualmente las coordenadas y no meterlo en la función porque te lías un huevo, poniendo una a una cada frame a pesar de llevar tiempo es sin duda la forma más eficiente. Aunque como las animaciones esta todas juntas pues hago una suma o multiplicación respecto a la imagen base que ha tiempo de interpretación se convierte en constante.

2º Si sera seguramente por lo que dices porque no es una especificación abierta tendré que usar ogg. Ya le diré a mi amigo compositor que me pase a este formato.

3º Estoy usando la función de Juanxo, me es muy útil, ;) aunque no sabia que se podía devolver de esa forma dos parámetros.

4º Aquí me da problemas :( , lo he puesto usando la función que mencionáis pero no funciona... de hecho se me bloquea.

Código: Seleccionar todo
while running:
                pygame.time.delay(10)
                pygame.display.flip()
                screen.blit(background[0],(0,0))
                screen.blit(player.image, (player.posx, player.posy))
                screen.blit(m1.image, (m1.posx, m1.posy), (219, 169, 17, 22)) #Imagen 1 de varias
                teclas = pygame.key.get_pressed()             
                if teclas[K_RIGHT]:
                        player.move('right')
                if teclas[K_a]:
                        player.move('left')
                if teclas[K_w]:
                        player.move('up')
                if teclas[K_s]:
                        player.move('down')
                if teclas[K_q]:
                        running == False


Juanxo escribió:Por cierto, recomendarte que si acabas de empezar, te olvides del 3D por un rato, que hay que dominar la programación de juegos para centrarse en los aspectos d diseño, lógica, mates y cosas de ese estilo


Lo se por eso empiezo de la forma que veis, de todas formas este mes próximo de Julio, voy a aprender algo de Shaders sobre OpenGL en un cursillo, porque solo piden el requisito de saber C++ y algo de matemáticas.

Por todo lo demás, repito muchas gracias, me habéis ayudado bastante ;) .

Un Saludo.
Facon
 
Mensajes: 7
Registrado: Mar Jun 23, 2009 2:07 pm

Notapor lacabra25 » Mié Jun 24, 2009 11:14 pm

En cuanto a lo primero efectivamente es mas eficiente el calcular donde esta cada personaje en la imagen partiendo de el pixel (0, 0) y el ancho y alto de cada personaje, pero mas eficiente que calcularlas es que abras la calculadora un momento y cambies cualquier calculo que tengas por el resultado directamente si siempre vas a usar el mismo personaje o todos los personajes se van a ajustar a la misma rejilla, aunque sea interpretado es mas rapido, por ejemplo ".... 55 ...." que ".... 11*5 ....". En cuanto a lo de la musica, no hace falta que te compliques la vida enviando los archivos para que te los conviertan, esperar que te los vuelvan a enviar y todo eso, con programas como audacity puedes tu mismo convertirlos, o con ogg convert que te conbierte muchos formatos privativos a formatos libres como de MP3 pasar a OggVorbis. Sobre la transparencia, ya te han comentado lo del color key, aun con eso yo te recomendaria que en lugar de usar bmp uses png, en principio son mas ligeras, pero ademas de so, si no quieres solo que un color sea transparente y el resto opaco, sino que con png tambien podrias tener partes del personaje semitransparentes y cosas asi, pero depende de si las bibliotecas que estas usando en python soportan los png, de todos modos puedes probar a cargar una imagen png y si no da error y la carga bien, pues la soporta. Por ultimo, si no te funciona la solucion que ya te han dado lo que podrias hacer es convertir a tu personaje en una maquina de estados, cuando se pulse la tecla que pase de "parado" a "movimiento_derecha" o "movimiento_izquierda" esto puedes implementarlo con numeros o letras siendo cada uno un estado determinado, y actuar de una determinada forma en funcion de el estado en lugar de las teclas, solo tendrias que encargarte de recojer la pulsacion de la tecla o cuando esta deja de ser presionada para cambiar el estado.

Facon escribió:...voy a aprender algo de Shaders sobre OpenGL en un cursillo...


Si tomas apuntes y te animas a escanearlos o pasarlos a un PDF y subirlos a algun servidor de internet te saldrias. No se si sera mucho o poco lo que deis en el cursillo, pero siempre se puede aprender algo nuevo.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Jue Jun 25, 2009 10:54 am

Buenasss::

Haber, lo primero de todo, me alegro de que se hayan corregido errores.

Segundo, la función de la imagen que te pase es recomendable que la llames de la siguiente forma:
Código: Seleccionar todo
self.imagen, self.rect = load_image("imagenX",-1)

para tener un parámetro rect que si todas las imagenes son iguales no hace falta que cambies y un parámetro imagen, lo cual te permite trabajar mas comodamente.
Otra cosa curiosa de Python es que, si solo quieres cargar las imagenes puedes hacer lo siguiente:
Código: Seleccionar todo
self.image = load_image("imagenX", -1)[0]

lo cual te devolvería unicamente el primer parámetro de la función.

En cuanto a lo del error, podrías decir cual es exactamente ( que linea te dice, tipo de error, etc)

pero depende de si las bibliotecas que estas usando en python soportan los png


pygame soporta png, que tienen su propio canal_alpha, y además soportan el alpha_blending( creo que se dice así)

Nada más por ahora XD, y como ha dicho sabiamente lacabra, QUE RULEN ESOS APUNTESSSS!!!!!!!!!!!! jajajajaja
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Facon » Jue Jun 25, 2009 6:45 pm

Bueno ya he diseñado el prototipo de lo que va a ser AFD, de la máquina de estados que comentáis arriba.

Básicamente el personaje tiene 3 estados: QUIETO, MOVER, ATACAR.

- QUIETO: El personaje esta quieto mientras no se toque nada,
- MOVER: El personaje se mueve en función de los parametros que pasen a la función move, que determinara la dirección y sentido.
- ATACAR: El personaje blande una espada, aparece una secuencia de tres imágenes, que forman 1/4 de circulo, depende de la posición del personaje y es en sentido anti-horario.

Lo que no se es como implementarlo me podríais poner un pequeño boceto?

PD: En cuanto a los apuntes que pedís, en cuanto de el curso intentare subirlos ;) .
Facon
 
Mensajes: 7
Registrado: Mar Jun 23, 2009 2:07 pm

Notapor lacabra25 » Sab Jun 27, 2009 1:18 am

Supongo que con un pequeño boceto te refieres a algo de codigo de ejemplo de como usarlo, yo de python se poco, programo mas en C, y de pygame menos aun, por ello no puedo ponerte lineas y lineas de codigo con la deteccion de la tecla pulsada, el cambio de estado, etc, etc. Pero si quieres que el personaje se mueva a la izquierda y a la derecha no son suficientes esos tres estados; me explico, (voy a suponer que la maquina de estados es una nueva clase de la que defines un objeto, el personaje, por como python es orientado a objetos) tambien seran necesarias algunas variable mas para poder saber si al moverse debe moverse hacia la izquierda o hacia la derecha, si atacar hacia un lado o hacia el otro, etc, etc. Supongo que con una sola propiedad has echo lo de los estados, pues necesitarias otra propiedad para saber hacia que lado esta mirando, cuando una tecla sea pulsada deberas de tener las lineas de codigo necesarias para capturar el evento y poder saber que tecla ha sido pulsada, segun la tecla que sea pulsada cambias el valor de el estado o el lado hacia el que mira, con eso ya tendrias tratados los eventos, despues solo tendrias que actualizar la posicion del personaje en funcion de su estado y demas propiedades, si por ejemplo esta quieto, ya habrias acabado esta parte, si esta en movimiento y mira hacia la derecha lo mueves un poco a la derecha, despues de esto solo tendrias que dibujar todo en pantalla y volver a empezar el bucle del juego volviendo a comprobar los eventos, etc, etc.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Sab Jun 27, 2009 12:39 pm

En esto le doy la razon a la cabra, ya que de algun modo tienes que pasar la tecla pulsada a la función, o un parametro direccion o algo.

Para el tema de estados, movimiento y demás te recomiendo que te bajes el ejemplo de Hugo de la seccion de ejemplos( de donde ibas a bajar un ejemplo si no.....jajajaja) de un ejemplo de juego de plataformas.

Yo estoy haciendo un juego de plataformas en base a todo ese desarrollo y la verdad es que es un ejemplo cojo....... Si no entiendes algo de lo que hace ese código puedes preguntarlo aquí, que ya has visto que te ayudan hasta los que no programan en ese lenguaje

Suerte y a trabajar.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor endaramiz » Sab Jun 27, 2009 3:13 pm

Juanxo escribió:Para el tema de estados, movimiento y demás te recomiendo que te bajes el ejemplo de Hugo de la seccion de ejemplos( de donde ibas a bajar un ejemplo si no.....jajajaja) de un ejemplo de juego de plataformas.
También te puede interesar el ejemplo del cofre si quieres aprender sobre los estados. A mí me parece muy bueno porque está exclusivamente centrado en el tema (bueno, y su respectiva animación...). Y una vez entendido, puedes mirar el de las plataformas que ya es más amplio (movimientos, colisiones...).

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor Juanxo » Sab Jun 27, 2009 3:35 pm

Menos mal que hay gente que se nota que sabe en este foro. Acabo de mirar el código del cofre y está bastante bien como introduccion al de plataformas que comente antes.
Lo de plataformas lo dije porque la clase animacion que hizo hugo me parecía una forma muy efectiva de tratarlas.

Por cierto, si no entiendes algo del código te recomiendo que te lo reescribas, pensando lo que hace cada linea, pero no copiandolo directamente, sino entendiendo que hace la función e intentar reproducirlo con tus nombres de variables y tus comentarios de explicacion.

Cuando un código es bueno, se puede aprender mucho reescribiendolo o simplemente leyendotelo un par de veces
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Facon » Dom Jun 28, 2009 8:54 pm

Bueno al final lo que he hecho es mirar el prototipo en el que me baso y adaptarlo a mi proyecto, que para algo hay que reutilizar el software libre. Ya he solucionado todo lo de arriba y he entendido mejor la estructura de los Sprites, al crear objetos como el personaje y los enemigos que eran ciertos métodos como Update().

Bueno os dejo lo que llevo de código:

Código: Seleccionar todo
#!/usr/bin/env python

#Import Modules
import random
import string
import sys
import os
import pygame
from pygame import *
from pygame.sprite import Sprite

def load_image(name, colorkey = None):
        ruta = os.path.join('imgs', name)
        try:
            image = pygame.image.load(ruta)
        except:
            print "Error al cargar la imagen:", ruta
            raise SystemExit, message

        if colorkey is not None:
            image = image.convert()
            if colorkey == -1:
                colorkey = image.get_at((0,0))
            image.set_colorkey(colorkey, RLEACCEL)
        else:
            if image.get_alpha() is None:
                image = image.convert()
            else:
                image = image.convert_alpha()
        return image, image.get_rect()

class Player(Sprite): # This class is YOU
        def __init__(self):
                Sprite.__init__(self)
                # Player Animations
                self.image11, self.rect=load_image('player11.bmp', -1)
                self.image12, self.rect=load_image('player12.bmp', -1)
                self.image31, self.rect=load_image('player31.bmp', -1)
                self.image32, self.rect=load_image('player32.bmp', -1)
                self.image51, self.rect=load_image('player51.bmp', -1)
                self.image52, self.rect=load_image('player52.bmp', -1)
                self.image71, self.rect=load_image('player71.bmp', -1)
                self.image72, self.rect=load_image('player72.bmp', -1)
                self.image=self.image11
                self.rect.center = (30, 30)
                self.velocity = {'x':0, 'y':0}
                self.direction = 1
                self.flag = 1
                self.max_health = 3.0
                self.health = 3.0
                sword = Sword()
                self.inventory = [sword]
               
        def attack_sword(self):
                if self.inventory[0] == Sword:
                        pass
                print "Ataque simple!"
                               
        def update(self):
                # Movement + Collides
                self.rect.move_ip(self.velocity['x'], 0)
                self.rect.move_ip(0, self.velocity['y'])
               
                # Functions for switch map
               
                # Current Animation
                if self.velocity['x'] == 0  and self.velocity['y'] <0> 0 and self.velocity['y'] == 0:
                        self.direction = 3
                elif self.velocity['x'] == 0 and self.velocity['y'] > 0:
                        self.direction = 5
                elif self.velocity['x'] < 0 and self.velocity['y'] == 0:
                        self.direction = 7
                elif self.velocity['x'] == 0 and self.velocity['y'] == 0:
                        #self.direction = 0
                        pass

                if self.direction == 1:
                        if self.flag % 6 == 3:
                                self.image = self.image11
                        elif self.flag % 6 ==0:
                                self.image = self.image12
                elif self.direction == 3:
                        if self.flag % 6 == 3:
                                self.image = self.image31
                        elif self.flag % 6 ==0:
                                self.image = self.image32
                elif self.direction == 5:
                        if self.flag % 6 == 3:
                                self.image = self.image51
                        elif self.flag % 6 ==0:
                                self.image = self.image52
                elif self.direction == 7:
                        if self.flag % 6 == 3:
                                self.image = self.image71
                        elif self.flag % 6 ==0:
                                self.image = self.image72

                if self.velocity['x'] != 0 or self.velocity['y'] != 0:
                        self.flag = self.flag + 1
               
class Item(Sprite):
        def __init__(self):
                pass
       
        def update(self):
                pass

class Sword(Item):
        def __init__(self):
                self.power = 2
       
        def update(self):
                pass

class Monster(Sprite): # Enemies
        def __init__(self):
                Sprite.__init__(self)
                self.image, self.rect=load_image("chara05.png", -1)
                self.posx=70
                self.posy=70
                       
def main():
        random.seed()
        pygame.init()

        # Prepare stage
        screen = pygame.display.set_mode((640, 480))
        pygame.display.set_caption('Ventana')
        screen = pygame.display.get_surface()
        background = load_image('mapa.JPG', None)[0]
        screen.blit(background,(0,0))

        player = Player() # Instance of Player
        player_sprite = pygame.sprite.RenderClear(player)
        m1 = Monster()
       
        screen.blit(player.image, (0, 0))
               
        #music = pygame.mixer.Sound('contradanza.mp3')
        #music.play(-1, 0)
       
        running = True
       
        while running:
                pygame.time.delay(10)
                screen.blit(background, (0,0))
                player_sprite.update()
                screen.blit(m1.image, (m1.posx, m1.posy), (219, 169, 17, 22)) # Imagen 1 de varias
               
                # Keyboard Events
               
                for event in pygame.event.get():
                        if event.type == QUIT:
                                running = 0
                        elif event.type == KEYDOWN:
                                if event.key == K_a:
                                        player.velocity['x'] = -4
                                        player.direction = 7
                                if event.key == K_d:
                                        player.velocity['x'] = 4
                                        player.direction = 3
                                if event.key == K_w:
                                        player.velocity['y'] = -4
                                        player.direction = 1                                   
                                if event.key == K_s:
                                        player.velocity ['y'] = 4
                                        player.direction = 5
                                if event.key == K_ESCAPE:
                                        pygame.event.post(pygame.event.Event(pygame.QUIT))
                                       
                        elif event.type == KEYUP:
                                if event.key == K_a:
                                        player.velocity['x'] = 0
                                elif event.key == K_d:
                                        player.velocity['x'] = 0
                                elif event.key == K_w:
                                        player.velocity['y'] = 0
                                elif event.key == K_s:
                                        player.velocity['y'] = 0
               
                # Clear Everything
                player_sprite.clear(screen, background)
                 
                # Draw Everything
                player_sprite.draw(screen)
                 
                pygame.display.flip()
                       

if __name__ == '__main__': main()


Ahora me falta mirar haber como hago una animación con la espada, al más puro estilo Zelda, cada vez que ataca en función de la posición hace hace un giro de 90º en sentido anti-horario, en el que podría destacar que hay al menos 3 animaciones. la de cuando aparece la espada, la diagonal con la espada en movimiento y la tangente a la primera con "rastros" de movimiento.

El algoritmo se me ocurre para animarlo es si las coordenadas se cogen desde el centro de la imagen. seria algo así como 1/2 distancia del personaje + 1/2 de la distancia de la espada, siguiendo esto, tendría:

1º Imagen, coger la posición del personaje dado por self.direction y elegir si coger las coordenadas x o las coordenadas y, una vez hecho esto, muestro la imagen y le añado algo de retraso, basándome el prototipo que mire, que hacia con flags y %.

2º Imagen, lo mismo que lo de antes pero le sumo ademas la otra coordenada que no puse, quedándome así en diagonal y se le añade también un poco de retraso.

3º Imagen cojo las coordenada que no use al principio y hago como antes.

Espero que se entienda, y además me surgió la duda con los flags y %, que supongo que podría sustituirlo por pygame.time.delay().

Haber que opinan...
Facon
 
Mensajes: 7
Registrado: Mar Jun 23, 2009 2:07 pm

Notapor Juanxo » Lun Jun 29, 2009 2:21 am

Buenas Facon:

Un par de cosillas que a lo mejor no has visto:
- fijate que siempre utilizas el parametro self.rect, con lo que lo vas pisando hasta que llegas a la ultima carga.
Solución: fijate en una de las ultimas lineas de la función de cargar imagenes es rect = image.get_rect
Puedes hacer que la funcion solo devuelva la imagen o hacer lo de obtener solo el primer parametro que te explique, y calcular el rect en el update con lo de self.rect = self.image.get_rect()
Además, podrías crear una lista con las imagenes en vez de tener tanta variable.
Código: Seleccionar todo
                self.rect.move_ip(self.velocity['x'], self.velocity['y'])

lo juntas todo en una linea

Código: Seleccionar todo
if self.velocity['x'] == 0  and self.velocity['y'] <0> 0 and self.velocity['y'] == 0:


aquí te falta algo de código??

Código: Seleccionar todo
                if self.inventory[0] == Sword:

esto no se si te lo compara con la variable sword (con lo que sería falso, python es sensible a Mayusculas) o lo compara con la clase Sword() directamente. A lo mejor me equivoco aquí.




Código: Seleccionar todo
for event in pygame.event.get():
                        if event.type == QUIT:
                                running = 0
                        elif event.type == KEYDOWN:
                                if event.key == K_a:
                                        player.velocity['x'] = -4
                                        player.direction = 7
                                if event.key == K_d:
                                        player.velocity['x'] = 4
                                        player.direction = 3
                                if event.key == K_w:
                                        player.velocity['y'] = -4
                                        player.direction = 1                                   
                                if event.key == K_s:
                                        player.velocity ['y'] = 4
                                        player.direction = 5
                                if event.key == K_ESCAPE:
                                        pygame.event.post(pygame.event.Event(pygame.QUIT))
                                       
                        elif event.type == KEYUP:
                                if event.key == K_a:
                                        player.velocity['x'] = 0
                                elif event.key == K_d:
                                        player.velocity['x'] = 0
                                elif event.key == K_w:
                                        player.velocity['y'] = 0
                                elif event.key == K_s:
                                        player.velocity['y'] = 0


Esto lo cambiaría por:

Código: Seleccionar todo
                    teclas = pygame.key.get_pressed()
                    for event in pygame.event.get():
                        if event.type == QUIT:
                                running = 0
                    if teclas[K_UP]:
                        player.velocity['y'] = -4
                       ..............................................


Lo de la animación no lo entiendo muy bien. Si tuvieras un ejemplo que se pudiera ver (ejecutar) a lo mejor te podría ayudar,

En cuanto a lo del time.delay no te valdría, porque pararía la ejecución de manera temporal, mientras que con el flag, el codigo sigue ejecutandose pero solo ves los cambios de posición o de animación cada cierto tiempo

Un saludo y espero haberte ayudado un poco.
Perdón por tanta corrección, pero no lo hago para mal.
[/code]
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Facon » Lun Jun 29, 2009 1:40 pm

http://www.mediafire.com/?sharekey=98dde2ed254e8480111096d429abd360e04e75f6e8ebb871

Ahí tenéis lo que llevo que se ejecuta bien de momento.
Juanxo escribió:Un par de cosillas que a lo mejor no has visto:
- fijate que siempre utilizas el parámetro self.rect, con lo que lo vas pisando hasta que llegas a la ultima carga.
Solución: fijate en una de las ultimas lineas de la función de cargar imagenes es rect = image.get_rect
Puedes hacer que la funcion solo devuelva la imagen o hacer lo de obtener solo el primer parámetro que te explique, y calcular el rect en el update con lo de self.rect = self.image.get_rect()
Tienes razón. He puesto de esta forma:
Código: Seleccionar todo
                self.image11, self.rect=load_image('player11.bmp', -1)
                self.image12=load_image('player12.bmp', -1)[0]
                self.image31=load_image('player31.bmp', -1)[0]
                self.image32=load_image('player32.bmp', -1)[0]
                self.image51=load_image('player51.bmp', -1)[0]
                self.image52=load_image('player52.bmp', -1)[0]
                self.image71=load_image('player71.bmp', -1)[0]
                self.image72=load_image('player72.bmp', -1)[0]

Y se ejecuta de la misma forma que la que he subido.

En cuanto a lo de la lista, es buena idea, pero de momento quiero basarme en el prototipo. Se que probablemente me dirías que hiciera algo como:
Código: Seleccionar todo
self.image[0], self.rect = load_image("player11.bmp", -1)
self.append(load_image("player12.bmp", -1) [0])
self.append(load_image("player31.bmp", -1) [0])
#Etc...
Seria algo así si declare bien la lista.
Juanxo escribió:Además, podrías crear una lista con las imagenes en vez de tener tanta variable.

Código: Seleccionar todo
self.rect.move_ip(self.velocity['x'], self.velocity['y'])

El prototipo en el que me baso lo declara separado, más concretamente de esta forma, al haber implementado colisiones:
Código: Seleccionar todo
        #move horiz
        self.rect.move_ip((self.x_velocity, 0))
        if self.rect.collidelist(blocked_tile_list) != -1:
            self.rect.move_ip((-self.x_velocity,0))

        #move vert
        self.rect.move_ip((0, self.y_velocity))
        if self.rect.collidelist(blocked_tile_list) != -1:
            self.rect.move_ip((0, -self.y_velocity))

Yo simplemente he hecho un copy & paste, y cuando implemente colisiones quedaría igual.

Lo siguiente que menciones es seguramente porque no cabía el código.

Y de lo siguiente, si me falta mucho código, pues solo he puesto un boceto.

Lo que quiero hacer es que compare la clase y en teoría al menos creo que es así.

Y lo último, no se porque pero he puesto algo similar a lo que pones abajo pero no me funciona, no se porque...

Muchas gracias por todo.
Facon
 
Mensajes: 7
Registrado: Mar Jun 23, 2009 2:07 pm

Notapor Juanxo » Lun Jun 29, 2009 3:48 pm

buenas:
he estado trasteando un poco tu código, y he conseguido que funcione lo de las teclas.

He hecho estos cambios:

Código: Seleccionar todo
for event in pygame.event.get():
                        if event.type == QUIT:
                                running = 0

                teclas = pygame.key.get_pressed()

                if teclas[K_a]:
                        player.velocity['x'] = -4
                        player.direction = 7
                elif teclas[K_d]:
                        player.velocity['x'] = 4
                        player.direction = 3
                if teclas[K_w]:
                        player.velocity['y'] = -4
                        player.direction = 1
                elif teclas[K_s]:
                        player.velocity['y'] = 4
                        player.direction = 5


al final de la funcion update añade esto:
Código: Seleccionar todo
                self.velocity['x'] = 0
                self.velocity['y'] = 0


con esto a mi me funciona
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)


Volver a General

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron