Pygame VI: Control del teclado
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
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.
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.
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.
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.
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…
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.
[…] Pygame VI: Control del teclado […]
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
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.