Razón Artificial

La ciencia y el arte de crear videojuegos

Pygame VI: Control del teclado

Escrito por adrigm el 14 de febrero de 2010 en Desarrollo Videojuegos, Noticias, Programación | 9 Comentarios.

Bien ya tenemos nuestra pelota que se mueve como loca por toda la pantalla. El siguiente paso es crear un nuevo Sprite para las palas, este a diferencia de la bola no se moverá solo sino que lo controlaremos nosotros por el teclado.

Creando el Sprite Pala

Lo primero que necesitamos es una imagen que la represente, descargarla aquí y como siempre, al directorio images. Como ves la pala no es más que un rectángulo blanco, no es cuestión de complicarse.

La clase Pala es casi idéntica a la clase Bola, salvo por unos pequeños cambios:

class Pala(pygame.sprite.Sprite):
	def __init__(self, x):
		pygame.sprite.Sprite.__init__(self)
		self.image = load_image("images/pala.png")
		self.rect = self.image.get_rect()
		self.rect.centerx = x
		self.rect.centery = HEIGHT / 2
		self.speed = 0.5

Como vemos es idéntica salvo que ahora le pasamos el parámetro x para usarlo en self.rect.centerx, esto es debido a que necesitamos dos palas una en la parte izquierda y otra en la derecha, con el parámetro x definimos a que altura del eje x queremos colocar el Sprite.

Otro cambio es la velocidad, como la pala del Pong solo se mueve en el eje y no definimos velocidad para el eje x.

para crear la pala del jugador ya sabéis, debajo de donde habéis creado la bola ponéis la siguiente línea:

pala_jug = Pala(30)

La llamo pala_jug porque habrá otra que será la pala_cpu que será la que maneje el ordenador. Como ves le paso como valor de x = 30, esto quiere decir que centerx estará a 30 px del borde derecho de la ventana.

Por último dentro del bucle lo de siempre, despues de actualizar el fondo y la bola actualizamos la pala:

screen.blit(pala_jug.image, pala_jug.rect)

Moviendo la pala

Para mover la pala definimos el método mover dentro de la clase Pala:

def mover(self, time, keys):
	if self.rect.top >= 0:
		if keys[K_UP]:
			self.rect.centery -= self.speed * time
	if self.rect.bottom <= HEIGHT:
		if keys[K_DOWN]:
			self.rect.centery += self.speed * time

Recibe los parámetros self y time como el método actualizar de la bola y además recibe el parámetro keys que luego definiremos y que es una lista con el valor booleano de las teclas pulsadas.

La línea 2 y 5 comprueban que la parte superior (en el caso de la linea 2) de la pala sea mayor o igual a 0 y que la parte inferior de la pala (línea 5) sea menor o igual que que la altura de la ventana. Resumiendo comprueban que la pala no se sale de la ventana.

La línea 3 comprueba si la constante K_UP de keys es 1, lo que querría decir que tenemos presionada la tecla de la flecha hacia arriba del teclado.

La línea 5 en caso de tener la tecla presionada disminuye el valor de centery haciendo que la pala se mueva hacia arriba.

La línea 6 y 7 hacen lo mismo, pero para abajo y aumentando el valor de centery.

Ahora solo debemos saber que teclas se están pulsando creando la variable keys, esto se consigue añadiendo la siguiente línea en el bucle principal, justo despues de comprobar el tiempo transcurrido con time.

keys = pygame.key.get_pressed()

Esto nos devuelve las teclas pulsadas en una lista como explicamos arriba.

Por ultimo debemos llamar al método mover en el bucle justo después de actualizar la bola, con la línea:

pala_jug.mover(time, keys)

El código nos 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

class Pala(pygame.sprite.Sprite):
	def __init__(self, x):
		pygame.sprite.Sprite.__init__(self)
		self.image = load_image("images/pala.png")
		self.rect = self.image.get_rect()
		self.rect.centerx = x
		self.rect.centery = HEIGHT / 2
		self.speed = 0.5

	def mover(self, time, keys):
		if self.rect.top >= 0:
			if keys[K_UP]:
				self.rect.centery -= self.speed * time
		if self.rect.bottom <= HEIGHT:
			if keys[K_DOWN]:
				self.rect.centery += self.speed * 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()
	pala_jug = Pala(30)

	clock = pygame.time.Clock()

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

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

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

Ya tenemos nuestra pala que podemos controlar con el teclado, pero la bola como vemos para olímpicamente de ella y la atraviesa. En el siguiente tutorial aprenderemos a crear colisiones entre Sprites

9 Comentarios en "Pygame VI: Control del teclado"

  1. Dokan dice:

    Gracias, he aprendido dos cosas importantes.
    Una pregunta, ¿Por qué actualizas la pala después de la bola y no antes? Creo que para evitar casos en que parece que has llegado pero la bola pasó de largo debería ser al revés, o no, tampoco estoy seguro.
    Otra cosa, donde dices «La línea 5 en caso de tener la tecla presionada disminuye el valor de centery haciendo que la pala se mueva hacia arriba.» te refieres a la linea 4.

  2. adrigm dice:

    Dokan, en realidad no tiene mucho que ver cual se actualice antes porque es tan rápido que no va a ver grandes diferencias. Prueba a ponerlo al revés y verás.

    Obviamente es la línea 4.

  3. Kurai dice:

    Dokan lo que pasa es que los graficos en una computadora no operan como en un sistema cartesiano:

    PC:

    (0,0) ————————-> x
    |
    |
    |
    |
    |
    |
    |
    v
    y

    Disculpa que lo explique de esta forma, pero tampoco soy un experto :P

    Saludos desde Venezuela.

    PD: adrigm hermano, sos grande, felicitaciones y muchas gracias por tu trabajo.

  4. adrigm dice:

    Más bien Pygame, opera como dice Kurai. Otras bibliotecas como Pyglet tienen el (0, 0) En la esquina inferior izquierda, como el eje cartesiano.

    Que a mi me parece mucho más correcto, no se porque la tontería de ponerlo arriba y rotar los ejes.

  5. Camilo dice:

    Gracias por el tutorial esta muy bueno y me sirvio un monton….
    esta bueno q haya gente dispuesta a colaborar de esta forma y a liberar su codigo fuente, esto ayuda mucho a gente como yo q recien estamos aprendiendo python.
    De verdad MUCHAS GRACIAS ademas esto si funciona perfecto solo hay q saber interpretar el codigo y no buscar detalles (x los otrs comentarios) los detalles corren por su cuenta esta persona colaboro con un muy buen aporte pero tampoco es tu prof de python…

  6. Joa dice:

    Hola. Quería avisarte que en el método mover del objeto Pala en ciertas ocasiones la imagen no puede verse por completo. Te dejo una captura http://img199.imageshack.us/img199/8662/pantallazojh.png.
    En la consola la primer línea es self.rect.top. Fijate que es negativo por lo tanto la imagen aparece cortada.

  7. […] Pygame VI: Control del teclado […]

  8. Gabriel Herrera dice:

    Es sensacional, estoy aprendiendo una enormidad, pero mi interés en aprender es para poder hacer un karaoke, y quisiera que me ayudaras en este juego un fondo de pantalla (cualquier foto-paisaje), una pista mp3, ogg o video y poder usar como split las letras codificadas como subtítulos .ass que con el programa Aegisub se sincroniza y se le da el efecto karaoke a las letras y solo tengo la intención, me falta el conocimiento que se lo adquiriré con la ayuda de todos

  9. fernando dice:

    Gran Tutorial!

    solo tengo un problemilla, cuando muevo la pala y toca la parte superior de la pantalla se queda en esa posicion y no la puedo mover más.

Deja un comentario