Suscríbete vía RSS Síguenos en Twitter

Pygame V: Moviendo Sprite

adrigm | 14/02/2010 | 5 Comentarios

En el siguiente tutorial aprenderemos a mover nuestra pelota por la ventana y hacer que rebote contra los bordes, Usaremos física y matemáticas básicas para mover la pelota.

El método actualizar

Para mover la pelota crearemos un metodo llamado actualizar dentro de la clase Bola que controle el movimiento de la pelota y si choca contra los bordes de la ventana, el método es el 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 >= WIDTH:
		self.speed[0] = -self.speed[0]
		self.rect.centerx += self.speed[0] * time
	if self.rect.top <= 0 or self.rect.bottom >= HEIGHT:
		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, más adelante lo explicamos.

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 (WIDTH), 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.

Creando un reloj

Ahora vamos a crear un reloj que controle el tiempo del juego, esto es importante para el movimiento, pues sabemos cuanto tiempo a pasado desde la ultima actualización de la pelota y con ello poder situarla en el espacio.

clock = pygame.time.Clock()

Esta línea va justo antes de entrar en el bucle del juego y sirve para crear el reloj con el que gestionar el tiempo.

Ahora necesitamos saber cuanto tiempo pasa cada vez que se ejecuta una interección del bucle, para ello dentro del bucle ponemos como primera línea:

time = clock.tick(60)

El 60 que se le pasa como parámetro es el framerate, con él nos aseguramos de que el juego no va a más de la velocidad estipulada. Con ello conseguimos que el juego corra igual en todos los ordenadores. Aquí más inftomación.

Por último debemos actualizar la posición de la bola antes de actualizarla en la ventana, es decir antes de los screen.blit.

bola.actualizar(time)

Como ves le pasamos el parametro time que es el tiempo que ha pasado desde la última vez que se ejecuto.

El juego queda así:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Módulos
import sys, pygame
from pygame.locals import *

# Constantes
WIDTH = 640
HEIGHT = 480

# Clases
# ---------------------------------------------------------------------

class Bola(pygame.sprite.Sprite):
	def __init__(self):
		pygame.sprite.Sprite.__init__(self)
		self.image = load_image("images/ball.png", True)
		self.rect = self.image.get_rect()
		self.rect.centerx = WIDTH / 2
		self.rect.centery = HEIGHT / 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 >= WIDTH:
			self.speed[0] = -self.speed[0]
			self.rect.centerx += self.speed[0] * time
		if self.rect.top <= 0 or self.rect.bottom >= HEIGHT:
			self.speed[1] = -self.speed[1]
			self.rect.centery += self.speed[1] * time

# ---------------------------------------------------------------------

# Funciones
# ---------------------------------------------------------------------

def load_image(filename, transparent=False):
        try: image = pygame.image.load(filename)
        except pygame.error, message:
                raise SystemExit, message
        image = image.convert()
        if transparent:
                color = image.get_at((0,0))
                image.set_colorkey(color, RLEACCEL)
        return image

# ---------------------------------------------------------------------

def main():
	screen = pygame.display.set_mode((WIDTH, HEIGHT))
	pygame.display.set_caption("Pruebas Pygame")

	background_image = load_image('images/fondo_pong.png')
	bola = Bola()

	clock = pygame.time.Clock()

	while True:
		time = clock.tick(60)
		for eventos in pygame.event.get():
			if eventos.type == QUIT:
				sys.exit(0)

		bola.actualizar(time)
		screen.blit(background_image, (0, 0))
		screen.blit(bola.image, bola.rect)
		pygame.display.flip()
	return 0

if __name__ == '__main__':
	pygame.init()
	main()

Ya nuestra pelota se mueve y rebota contra las paredes. En el próximo tutorial crearemos el Sprite pala y aprenderemos a moverlo con el teclado.

Entradas relacionadas

5 Comentarios

1
Escrito por Miguel el 18 febrero 2010 a las 11:29 am

Primero de todo felicitarte por el gran trabajo. Yo ya soy un “veterano” de la informática y creo recordar que en los tiempos del ZXspectrum, cuando se trabajaba con Sprites, en lugar de dibujar el fondo (sería muy lento) y a continuación el “personaje”, lo que se hacía era:
1- se guardaba la zona del fondo donde se va a “machacar” encima el personaje. Por ejemplo en la variable “temp”.
2- se colocaba el personaje. Si este se movía:
3- se colocaba “temp” en su lugar, borrando el personaje y dejando el fondo como estaba. Y se volvía a guardar en “temp” la siguiente zona donde se iba a colocar el personaje.
4- se colocaba el personaje y así repetidamente.
¿Se puede hacer esto mismo en pygame o sería más lento?

2
Escrito por admin el 18 febrero 2010 a las 20:27 pm

Miguel, en esencia ahora es lo mismo, tu tienes el fondo guardado en un array y metes el personaje encima en una posición, luego si mueves el personaje, vuelves a recolocar el fondo y pintas al personaje encima.

De hecho estoy haciendo ahora un motor de un rpg en pygame con ese estilo, pronto publicaré algo del tema en el blog.

3
Escrito por Kike Alonso el 7 mayo 2010 a las 3:12 am

Muy agradecido por tu excelente tutorial. He aprendido en horas lo que no pude en días. Gracias por tu esfuerzo.
Kike

4
Escrito por animelafuerza el 21 julio 2010 a las 16:48 pm

Heres grande !! xD
bueno dejando las bromas se agradece mucho el esfuerzo, la verdad tengo unos pocos dias que empece a programar con python (pyton para los cuates xD) y ya medio lo voy entendiendo.

por sierto, yo quiero trabajar tambien en un RPG pero tactico.
Saludos

5
Escrito por animelafuerza el 22 julio 2010 a las 18:56 pm

PD: olvide mecionar, ya tengo unos añitos programando con C#, visual Net, Gambas y quiero aprender C o C++ para luego ahi hacer mis Engines

Saludos

Deja un comentario

Su comentario: