Hola a tod@s, como os prometí, voy a seguir escribiendo sobre Pygame, esta vez vamos a ver una clase muy pero que muy importante llamada sprite.
Hasta ahora todos los objetos los habíamos creado simplemente cargando la imagen y posicionándola en pantalla, tanto el fondo como el pingüino, pero, evidente mente, el pingüino y el fondo son elementos jerárquicos muy diferentes, ya que el pingüino en algún momento del juego puede interactuar con el medio: colisionar, saltar, morir... mientras que el fondo es una imagen fija y sin vida que siempre va a ser así (al menos en la mayoría de los juegos).
IMPORTANTE: Es imprescindible haber leído con anterioridad los tutoriales sobre la POO para poder entender este artículo:
Así que el pingüino lo crearemos como un sprite, un sprite es un objeto capaz de interactuar con el medio, ya que nos proporciona métodos de movimiento, colisión...
Para ir refrescando la memoria, así teníamos el código en el anterior post:
#!/usr/bin/python #importamos modulos import sys import pygame from pygame.locals import * #definimos constantes altura=640 anchura=480 def main(): #variables locales x=550 y=220 speed=1 #iniciamos pygame pygame.init() #creamos una ventana ventana=pygame.display.set_mode((altura, anchura)) #definimos un titulo para la ventana pygame.display.set_caption("probando pygame...") #cargamos imagenes fondo=pygame.image.load("fondo.jpg").convert() tux=pygame.image.load("tux.png").convert_alpha() #loop del juego while True: teclado=pygame.key.get_pressed() if teclado[K_RIGHT]: x+=speed if teclado[K_LEFT]: x-=speed if teclado[K_UP]: y-=speed if teclado[K_DOWN]: y+=speed ventana.blit(fondo, (0, 0)) ventana.blit(tux, (x, y)) pygame.display.flip() #posibles entradas del teclado for eventos in pygame.event.get(): if eventos.type==pygame.QUIT: sys.exit() if __name__=="__main__": main()
Para crear un sprite, se usa la clase sprite.Sprite(), pero no se usa como anteriormente hemos usado todos los métodos en python, sino que aquí esta clase deberá de ser heredada por otra que nosotros creemos anteriormente, para facilitaros el trabajo, ya lo he hecho yo por vosotr@s:
class objeto(pygame.sprite.Sprite): def __init__(self, foto): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(foto).convert_alpha() self.rect = self.image.get_rect() self.speed = [velo, velo] def update(self): teclado=pygame.key.get_pressed() if teclado[K_RIGHT]: pinguino.rect.x+=velo if teclado[K_LEFT]: pinguino.rect.x-=velo if teclado[K_UP]: pinguino.rect.y-=velo if teclado[K_DOWN]: pinguino.rect.y+=velo ventana.blit(self.image, (self.rect.x, self.rect.y))
Como veis creamos una clase cualquiera pero que debe de heredar de la clase "pygame.sprite.Sprite()", después en el constructor de nuestra clase, debemos de llamar a el constructor de la clase sprite con:
pygame.sprite.Sprite.__init__(self)
Así obtenemos todos los métodos que nos brinda la clase Sprite, también en la clase que yo he creado; los valores del sprite también se especifican en el constructor siento estos:
self.image: La imagen a cargar
self.rect: Obtiene el rectángulo invisible que rodea la foto, para después poder gestionar colisiones...
self.speed: La velocidad de movimiento del sprite
Después para crear un sprite a través de esta clase, simplemente:
pingüino=objeto("tux.png")
Ahora pasamos a analizar el método update de la clase objeto, anteriormente, toda la lógica del pingüino se encontraba en el loop principal, pero claro, si tenemos 100 objetos, imaginaros como se nos quedaría el loop de largo complejo con todas las condiciones que almacenaría, por lo cual en los sprites la inteligencia de estos se crean en el método especial update que aparte de la lógica que nosotros definamos también se encarga de gestionar el sprite, este método update se debe de ejecutar en el loop del programa con un simple:
pinguino.update()
Práctica mente el código que está dentro del update no cambia respecto al código del anterior post donde gestionamos las pulsaciones del teclado, solo que aquí en vez de jugar directa mente con las posiciones de la imagen "cruda", jugamos con las posiciones del rectángulo que lo contiene a través de los métodos "rect.x" y "rect.y".
Así que si adaptamos el código del anterior post con estas nuevas modificaciones, se nos quedaría algo así:
#!/usr/bin/python #importamos modulos import sys import pygame from pygame.locals import * #definimos constantes altura=640 anchura=480 def main(): #variables locales x=550 y=220 velo=3 #iniciamos pygame pygame.init() #creamos una ventana ventana=pygame.display.set_mode((altura, anchura)) #definimos un titulo para la ventana pygame.display.set_caption("probando pygame...") #cargar imagenes fondo=pygame.image.load("fondo.jpg") class objeto(pygame.sprite.Sprite): def __init__(self, foto): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(foto).convert_alpha() self.rect = self.image.get_rect() self.speed = [velo, velo] def update(self): teclado=pygame.key.get_pressed() if teclado[K_RIGHT]: pinguino.rect.x+=velo if teclado[K_LEFT]: pinguino.rect.x-=velo if teclado[K_UP]: pinguino.rect.y-=velo if teclado[K_DOWN]: pinguino.rect.y+=velo ventana.blit(self.image, (self.rect.x, self.rect.y)) pinguino=objeto("tux.png") #loop del juego while True: pygame.display.flip() ventana.blit(fondo, (0,0)) pinguino.update() #posibles entradas del teclado for eventos in pygame.event.get(): if eventos.type==pygame.QUIT: sys.exit() if __name__=="__main__": main()
Si ejecutáis este último código obtendréis los mismos resultados que en el anterior post, pero en este ejemplo, el pingüino es un sprite no una foto normal y corriente, permitiendo que este interactue con el medio mediante métodos de la sprite.Sprite() como las colisiones.
Al principio puede resultar un poco complejo, pero si se lee bien esto y todos los anteriores posts sobre orientación a objetos, resulta llevadero.
Un abrazo a tod@s y hasta el siguiente artículo.
PD: Si el código os da error, copiarlo a mano ya que si no os puede tirar la excepción: "IndentationError: unexpected indent"
PD: Si el código os da error, copiarlo a mano ya que si no os puede tirar la excepción: "IndentationError: unexpected indent"
11 comentarios:
Espero que difundas todo tu esfuerzo ! Y en el futuro poder ver un blog lleno de vida.
Un abrazo!
Gracias, y si, ya me gustaría que aquí hubiera mucha actividad, pero de momento nada.
Un abrazo.
yo esto no lo voy a usar
para hacer un juego sino para
otras cosas,
echale un vistazo a raspberry pi.
Francisco , como puedo hacer un
programa en Tkinter y ejecutarlo en un archivo .py o lo que sea.
GRACIAS
Dan:
Pues es muy sencillo, colocando al final lo siguiente:
el_nombre_de_la_ventana.mainloop()
por ejemplo
ventana.mainloop()
Un Abrazo.
Muchisimas gracias.
Francisco tengo un programa que no va:
¿podrias decirme el fallo?:
Codigo:
from Tkinter import*
ventana=Tk()
titulo = Label(ventana, text="Text Editor 1.0", fg="brown")
titulo.pack()
def a():
exit()
def b():
file=open("a.txt", "a")
file.write(texto)
file.write(texto2)
file.write(texto3)
file.write(texto4)
file.write(texto5)
file.write(texto6)
file.write(texto7)
file.write(texto8)
file.write(texto9)
file.write(texto10)
file.write(texto11)
file.write(texto12)
file.write(texto13)
file.write(texto14)
file.write(texto15)
#para cerrar el archivo
file.close()
f1=Frame(ventana)
b1=Button (f1, text="Guardar", bg="blue", command=b)
b2=Button (f1, text="Salir", bg="red", command=a)
b1.pack(side="left")
b2.pack(side="left")
f1.pack()
f2=Frame(ventana)
texto=Entry(f2, bg="white")
texto.pack()
f2.pack()
ayuda = Label(f2, text="Cada cuadro representa una linea", fg="purple")
texto2 = Entry(f2, bg="white")
texto2.pack()
texto3 = Entry(f2, bg="white")
texto3.pack()
texto4 = Entry(f2, bg="white")
texto4.pack()
texto5 = Entry(f2, bg="white")
texto5.pack()
texto6 = Entry(f2, bg="white")
texto6.pack()
texto7 = Entry(f2, bg="white")
texto7.pack()
texto8 = Entry(f2, bg="white")
texto8.pack()
texto9 = Entry(f2, bg="white")
texto9.pack()
texto10 = Entry(f2, bg="white")
texto10.pack()
texto11 = Entry(f2, bg="white")
texto11.pack()
texto12 = Entry(f2, bg="white")
texto12.pack()
texto13 = Entry(f2, bg="white")
texto13.pack()
texto14 = Entry(f2, bg="white")
texto14.pack()
texto15 = Entry(f2, bg="white")
texto15.pack()
ayuda.pack()
dire = Label(f2, text="Write the file directory:", fg="brown")
dire.pack()
ventana.mainloop()
Dan, antes de nada, cuando tengas alguna duda con algún Script que no te funcione, lo primero que debes aportar es la excepción (el error) que te lanza el intérprete de Python, ya que suelen ser muy precisos y de gran ayuda.
Un saludo.
Francisco, como puedo hacer que un
programa redirija a otro,
es decir que al pulsar un boton se
ejecute una función que ejecute
otro archivo .py
GRACIAS
Daniel, la filosofía de Python no es que un archivo python pueda ejecutar otro, sino que el archivo .py "Principal" aproveche funciones de otros scripts, por ejemplo si el otro archivo se llama "operaciones.py" y tiene dos funciones, un "suma" y otra "resta"
import operaciones
operaciones.suma()
¿Entiendes lo que quiero decir? No sería buena práctica intentar abrir un archivo .py desde otro archivo .py, iría en contra de la filosofía de python.
Un saludo.
Esto es a lo que me referia.
GRACIAS
Publicar un comentario