viernes, 4 de mayo de 2012

Colocando sprites y darles movimiento - Pygame

Hola gente, hoy les voy a mostrar como colocar un sprite en la pantalla, posicionarlo, y darle movimiento.

Vamos a apuntar hacia hacer un juego simple, el clasico pong, y utilizaremos el codigo de mi anterior post, pero cambiaremos el fondo, colocandole uno mas apropiado, yo utilizare la siguiente imagen:


y para la pelota esta imagen:




ok, entonces tenemos nuestras imagenes (no se olviden de ponerlas en la carpeta del juego y cambiarle el nombre al fondo en el codigo).

La clase pelota

Lo siguiente es crear una clase que contenga la pelota y sus propiedades de sprite:

class Pelota(pygame.sprite.Sprite):
      def __init__(self):
          pygame.sprite.Sprite.__init__(self)
          self.imagen = cargar_imagen("datos/pelota.png", True)
          self.rect = self.imagen.get_rect()
          self.rect.centerx = 640 / 2
          self.rect.centery = 480 / 2
          self.speed = [0.5, -0.5]

La línea 1 crea la clase pelota que hereda los métodos de la clase pygame.sprite.Sprite, esto es muy importante debido a que contiene métodos necesarios para el manejo de Sprites.

La línea 2 crea la funcion (o metodo)  __init__ que inicializa la clase.

La línea 3 invoca a la funcion init de la clase heredada, muy importante también y difícil de explicar.

La línea 4 ya nos suena más y lo que hace es cargar con nuestra función cargar_imagen() la imagen de la pelota, como vemos tenemos puesto True porque la pelota si tiene zonas transparentes.

La línea 5 es de las cosas más útiles de pygame, la función self.image.get_rect() obtiene un rectangulo con las dimensiones y posición de la imagen (en este caso self.image) y se lo asignamos a self.rect

Aqui quiero comentar sobre los parametros utiles con los que cuenta get_rect(), ellos son los siguientes:
  • top, left, bottom, right
  • topleft, bottomleft, topright, bottomright
  • midtop, midleft, midbottom, midright
  • center, centerx, centery
  • size, width, height
  • w, h
Así que podemos acceder a los diferentes valores como self.rect.centerx que nos devuelve la posición central de la pelota respecto al ancho de la pantalla, y así con todos es cuestión de probarlos, pero más o menos se entiende lo que devuelve cada uno. Lo mejor de todos ellos es que si cambias el valor de alguno el resto se actualiza.

Volviendo al codigo, en la linea 6 y 7 usamos las propiedades de rect y con centerx y centery definimos el centro de la pelota en el centro de la pantalla.

La linea 8 define la velocidad que queremos para la pelota, separamos la velocidad en dos, para los ejes x y, luego veremos porque.


Colocando la pelota en la ventana

Ya que tenemos una clase creada para la pelota, vamos a crear la pelota

pelota = Pelota()
Ahora solo tenemos que "pegarla" en nuestra ventana con el siguiente comando

pantalla.blit(pelota.imagen, pelota.rect)
Como se puede ver no le pasamos la imagen ahora, y en vez de unas coordenadas como con el fondo, le pasamos el rect de la pelota, con esto conseguiremos que cada vez que movamos el rect, moveremos la pelota.

Es muy importante "ponerla en pantalla despues que el fondo" porque si primero colocamos la pelota y luego el fondo, esta no se veria porque quedaria detras del fondo.

Con esto, ya tenemos a nuestra pelota colocada encima de nuestro fondo, pero todo esta estatico.
Para cambiar eso, le agregaremos movimiento

El metodo actualizar

Para mover la pelota, crearemos un metodo llamado actualizar dentro de la clase Pelota, y esto controlara el movimiento de la pelota, y si choca contra los bordes de la ventana.
La funcion es la siguiente:
def actualizar(self, time):
 self.rect.centerx += self.speed[0] * time
 self.rect.centery += self.speed[1] * time
 if self.rect.left <= 0 or self.rect.right >= 640:
  self.speed[0] = -self.speed[0]
  self.rect.centerx += self.speed[0] * time
 if self.rect.top <= 0 or self.rect.bottom >= 480:
  self.speed[1] = -self.speed[1]
  self.rect.centery += self.speed[1] * time

La linea 1 define el método, recibe el parámetro self (como siempre) y el parámetro time que es el tiempo transcurrido.

La línea 2 y 3 usa la física básica de espacio es igual a la velocidad por el tiempo (e = v*t), por tanto establecemos que el centro de nuestro rectangulo en x es el valor que tenía (self.rect.centerx) más (+=) la valocidad a la que se mueve en el eje x (self.speed[0]) por (*) el tiempo transcurrido (time). Lo mismo se aplica al eje y en la línea 3.

La linea 4, 5 y 6 establece que si la parte izquierda del rectángulo de la bola es menor o igual a 0 ó mayor o igual a el ancho de la pantalla, es decir,  que este en el extremo izquierdo o derecho, la velocidad de x (self.speed[0]) cambie de signo (-self.speed[0]) con esto conseguiremos que vaya hacia el otro lado.

Las líneas 7, 8 y 9 es lo mismo pero en el eje y como se puede ver.

Debemos actualizar la posicion de la pelota a medida que transcurre el juego, esto es simple, solo basta con poner

pelota.actualizar(time)

Entonces, ahora nuestro codigo quedaria asi

#importamos librerias
import pygame
from pygame.locals import *

#iniciamos pygame
pygame.init()

#definimos constantes
pantalla = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Titulo de ventana')

reloj = pygame.time.Clock()

#definimos clases
class Pelota(pygame.sprite.Sprite):
 def __init__(self):
  pygame.sprite.Sprite.__init__(self)
  self.imagen = cargar_imagen("datos/pelota.png", True)
  self.rect = self.imagen.get_rect()
  self.rect.centerx = 640 / 2
  self.rect.centery = 480 / 2
  self.speed = [0.5, -0.5]
 def actualizar(self, time):
  self.rect.centerx += self.speed[0] * time
  self.rect.centery += self.speed[1] * time
  if self.rect.left <= 0 or self.rect.right >= 640:
   self.speed[0] = -self.speed[0]
   self.rect.centerx += self.speed[0] * time
  if self.rect.top <= 0 or self.rect.bottom >= 480:
   self.speed[1] = -self.speed[1]
   self.rect.centery += self.speed[1] * time



#definimos funciones
def cargar_imagen(nombre,transparente=False):
     try: imagen = pygame.image.load(nombre)

     except pygame.error, message:
          raise SystemExit, message
     imagen = imagen.convert()
     if transparente:
          color = imagen.get_at((0,0))
          imagen.set_colorkey(color, RLEACCEL)
     return imagen

fondo = cargar_imagen('datos/fondo.png')
pelota = Pelota()

#Bucle principal del juego
while 1:
 time = reloj.tick(60)
 pelota.actualizar(time)
 for event in pygame.event.get():
  if event.type == QUIT:
   pygame.quit()
   sys.exit()
  elif event.type == KEYDOWN:
   if event.type == K_ESCAPE:
    pygame.quit()
    sys.exit()
 pantalla.blit(fondo, (0, 0)) 
 pantalla.blit(pelota.imagen, pelota.rect)
 pygame.display.flip()

Y listo!  ahora ya tenemos una pelota que se mueve por la pantalla :) , en los proximos tutoriales iremos completando este juego.

1 comentario:

  1. Casino de Las Vegas: Casino de Las Vegas - Dr.MCD
    Play a 진주 출장안마 thrilling Vegas casino games with hundreds of 의왕 출장안마 Vegas casino games 동해 출장샵 and slots. Get your Vegas fix in the 이천 출장샵 largest 김제 출장안마 selection of slot machines in the

    ResponderEliminar