Curso Python. Volumen XXI: Pygame, videojuegos en python. Parte VI

Escrito por Javier Ceballos Fernández
Programación
0

Bienvenidos un día más al curso de Python. En este capítulo vamos a añadir el control con el teclado, de modo que podamos interactuar con el videojuego que estamos realizando con la librería “Pygame”. En el capítulo anterior ya hicimos que el movimiento de nuestro juego fuera fluido gracias a la sincronización. Así que pongámonos manos a la obra.

Añadiendo control de teclado

Lo que vamos a añadir a nuestro código es una clase paleta, la cual contendrá todo lo relacionado con la raqueta y revisaremos la función principal ya que tendrá que estar a la escucha de los eventos de teclado. A continuación, os mostramos el código:

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

# ---------------------------
# Importacion de los módulos
# ---------------------------

import pygame
from pygame.locals import *
import os
import sys

# -----------
# Constantes
# -----------

SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
IMG_DIR = "imagenes"

# ------------------------------
# Clases y Funciones utilizadas
# ------------------------------


def load_image(nombre, dir_imagen, alpha=False):
    # Encontramos la ruta completa de la imagen
    ruta = os.path.join(dir_imagen, nombre)
    try:
        image = pygame.image.load(ruta)
    except:
        print("Error, no se puede cargar la imagen: " + ruta)
        sys.exit(1)
    # Comprobar si la imagen tiene "canal alpha" (como los png)
    if alpha is True:
        image = image.convert_alpha()
    else:
        image = image.convert()
    return image


# -----------------------------------------------
# Creamos los sprites (clases) de los objetos del juego:


class Pelota(pygame.sprite.Sprite):
    "La bola y su comportamiento en la pantalla"

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = load_image("bola.png", IMG_DIR, alpha=True)
        self.rect = self.image.get_rect()
        self.rect.centerx = SCREEN_WIDTH / 2
        self.rect.centery = SCREEN_HEIGHT / 2
        self.speed = [3, 3]

    def update(self):
        if self.rect.left < 0 or self.rect.right > SCREEN_WIDTH:
            self.speed[0] = -self.speed[0]
        if self.rect.top < 0 or self.rect.bottom > SCREEN_HEIGHT:
            self.speed[1] = -self.speed[1]
        self.rect.move_ip((self.speed[0], self.speed[1]))


class Paleta(pygame.sprite.Sprite):
    "Define el comportamiento de las paletas de ambos jugadores"

    def __init__(self, x):
        pygame.sprite.Sprite.__init__(self)
        self.image = load_image("paleta.png", IMG_DIR, alpha=True)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.centery = SCREEN_HEIGHT / 2

    def humano(self):
        # Controlar que la paleta no salga de la pantalla
        if self.rect.bottom >= SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT
        elif self.rect.top <= 0:
            self.rect.top = 0


# ------------------------------
# Funcion principal del juego
# ------------------------------


def main():
    pygame.init()
    # creamos la ventana y le indicamos un titulo:
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Ejemplo de un Pong Simple")

    # cargamos los objetos
    fondo = load_image("fondo.jpg", IMG_DIR, alpha=False)
    bola = Pelota()
    jugador1 = Paleta(40)

    clock = pygame.time.Clock()

    # el bucle principal del juego
    while True:
        clock.tick(60)

        # Actualizamos los objetos en pantalla
        jugador1.humano()
        bola.update()

        # Posibles entradas del teclado y mouse
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == K_UP:
                    jugador1.rect.centery -= 5
                elif event.key == K_DOWN:
                    jugador1.rect.centery += 5
                elif event.key == K_ESCAPE:
                    sys.exit(0)
            elif event.type == pygame.KEYUP:
                if event.key == K_UP:
                    jugador1.rect.centery += 0
                elif event.key == K_DOWN:
                    jugador1.rect.centery += 0

        #actualizamos la pantalla
        screen.blit(fondo, (0, 0))
        screen.blit(bola.image, bola.rect)
        screen.blit(jugador1.image, jugador1.rect)
        pygame.display.flip()


if __name__ == "__main__":
    main()

Como os hemos indicado, definimos la clase paleta. Lo hacemos de manera análoga a la clase pelota, la única diferencia es que el “def __init__(self, x)” recibe como argumento adicional la coordenada “x” de la paleta (así con la misma clase se puede cargar una paleta a la izquierda y otra a la derecha), en cuanto a la coordenada “y” (el eje vertical), esta clase deja centrada la paleta (verticalmente).

Después, dentro de la clase hemos definido un método “def humano(self)”, este método lo que hace es definir los límites de movimiento de la paleta cuando los mueve un jugador para que la paleta no se salga de la pantalla. Cuando la paleta llega a uno de estos límites, lo que hará es pararse.

En la función principal del juego, podemos ver que hemos iniciado la clase “jugador1 = Paleta(25)” para crear una raqueta controlada por el jugador (el 25 es para que la paleta quede a 25 píxeles del borde izquierdo) y unas líneas más abajo indicamos al programa que esa paleta es controlada por una persona. El resto de instrucciones son para actualizar la pantalla como hemos estado haciendo hasta el momento.

Dentro del bucle de juego comprobamos los eventos utilizando el método “pygame.event.get”, así cada vez que se pulsa una tecla (del teclado) se obtiene un evento “pygame.KEYDOWN” y cada vez que se suelta una tecla se produce un evento “pygame.KEYUP”. Esos eventos devuelven el valor de la tecla pulsada

Así que simplemente se revisa dentro del evento “pygame.KEYDOWN” que tecla se pulsó, si se trata de la tecla flecha hacia arriba (“K_UP”) la paleta se desplazará 5 píxeles hacia arriba y si se trata de la tecla flecha hacia abajo (“K_DOWN”) se desplazará 5 píxeles hacia abajo. En el caso de que puse la tecla “K_ESCAPE” simplemente cerraremos la aplicación.

Realizamos un control similar para cuando se dejan de pulsar las teclas (“pygame.KEYUP”) para dejar de mover la paleta. Es verdad que en este juego no tiene demasiado sentido ya que por defecto nuestra paleta está quieta, pero puede resultar útil para otro videojuego y por esa razón lo hemos querido utilizar.

Dentro de “pygame.key” existe el método “get_pressed()” que devuelve una lista con todas las teclas pulsadas, usar esto puede ser más simple que ir comprobando una por una las teclas pero tiene como inconveniente que:

  • no hay forma de conocer el orden de las teclas pulsadas.
  • las pulsaciones muy rápidas de teclas pueden pasar desapercibidas.

Aquí lo dejamos por hoy, os recomendamos que hagáis un repaso de lo aprendido por el momento y que experimentéis. Id probando el juego y haciendo modificaciones para dejar el juego a vuestro gusto.

En el próximo capítulo os enseñaremos cómo podemos mejorar la interacción con el usuario y haremos el tratamiento de colisiones. Comentaros que para todos los que se acaban de incorporar indicarles que tenemos un índice con todos los capítulos del curso, ya que nunca es tarde para empezar.

Fuente > GitHub dbfuentes


Últimos análisis

Valoración RZ
10
Valoración RZ
7
Valoración RZ
9
Valoración RZ
10
Valoración RZ
8
Valoración RZ
10
Valoración RZ
9
Valoración RZ
9
Valoración RZ
10