Saltar a contenido

Mover la bola (2ª parte)

Como sexto paso, vamos a añadir el movimiento en horizontal. La bola rebotará en los cuatro lados del lienzo.

06MoverBola2.py
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
import tkinter
import random

class Juego:
    def __init__(self, ventana):
        self.ventana = ventana

        # Configurar ventana
        self.ventana.title('Bola')
        self.ventana.resizable(False, False)
        self.ventana.wm_attributes('-topmost', True)

        # Crear lienzo
        self.lienzo = tkinter.Canvas(self.ventana,
                                     width=500,
                                     height=400,
                                     bd=0)
        self.lienzo.pack()
        self.ventana.update()

        # Crear bola y paleta
        self.bola = Bola(self)
        self.paleta = Paleta(self)        

        # Indicadores
        self.terminar = False
        self.en_juego=False

        # Asociar eventos de teclado
        self.ventana.bind_all('<KeyPress>', self.gestionar_tecla)

    def gestionar_tecla(self,evento):
        if evento.keysym=='Escape':
            self.terminar = True
        elif evento.keysym=='space':            
            self.en_juego = True

    def bucle(self):
        while True:
            if self.terminar:
                break

            if self.en_juego:
                self.bola.mover()

            self.ventana.update_idletasks()
            self.ventana.update()

class Bola:
    def __init__(self, juego):
        self.juego  = juego

        tamaño = 15
        self.lienzo_ancho = self.juego.lienzo.winfo_width()
        self.lienzo_alto = self.juego.lienzo.winfo_height()

        self.juego.id_bola = self.juego.lienzo.create_oval(0, 0, tamaño, tamaño,
                                                           fill='red')
        centro_x = self.lienzo_ancho/2 - tamaño/2
        centro_y = self.lienzo_alto/2 - tamaño/2
        self.juego.lienzo.move(self.juego.id_bola, centro_x, centro_y)

        self.desplaz_y = -(velocidad_bola)
        self.desplaz_x = random.choice([-2, -3, -4, 2, 3, 4])

    def mover(self):
        # obtener coordenadas bola (x1, y1, x2, y2)
        coord_bola = self.juego.lienzo.coords(self.juego.id_bola)
        borde_sup_bola = coord_bola[1]
        borde_inf_bola = coord_bola[3]
        borde_izd_bola = coord_bola[0]
        borde_dch_bola = coord_bola[2]

        # si ha tocado el borde superior, empezar a bajar
        if borde_sup_bola <= 1:
            self.desplaz_y = abs(self.desplaz_y)

        # si ha tocado el borde inferior, empezar a subir
        if borde_inf_bola >= self.lienzo_alto-1:
            self.desplaz_y = abs(self.desplaz_y)*(-1)

        # si ha tocado el borde lateral, cambiar de dirección
        if borde_izd_bola <= 1:
            self.desplaz_x = abs(self.desplaz_x)
        elif borde_dch_bola >= self.lienzo_ancho-1:
            self.desplaz_x = abs(self.desplaz_x)*(-1)

        # desplazar
        self.juego.lienzo.move(self.juego.id_bola, self.desplaz_x, self.desplaz_y)

class Paleta:
    def __init__(self, juego):
        self.juego  = juego

        ancho = 60
        self.lienzo_ancho = self.juego.lienzo.winfo_width()
        self.lienzo_alto = self.juego.lienzo.winfo_height()

        self.juego.id_paleta = self.juego.lienzo.create_rectangle(0, 0, ancho, 10, fill='blue')

        centro_x = self.lienzo_ancho/2 - ancho/2
        centro_y = self.lienzo_alto - 50

        self.juego.lienzo.move(self.juego.id_paleta, centro_x, centro_y)

velocidad_bola=4
v = tkinter.Tk()
juego = Juego(v)
juego.bucle()
juego.ventana.update_idletasks()
juego.ventana.destroy()

Vemos que la bola tiene una nueva propiedad, desplaz_x, que mide el número de pixels a desplazar en cada iteración. En cada juego la inicializamos con un valor al azar, 2, 3 o 4:

self.desplaz_x = random.choice([-2, -3, -4, 2, 3, 4])

Ralentizar el juego

Ajustando los desplazamientos podemos acelerar o ralentizar el juego. Pero hay un mecanismo adicional que podemos usar para introducir un retardo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
    import time
    ... 

    while True:
        if self.terminar:
            break

        if self.en_juego:
            self.bola.mover()
            time.sleep(0.01)    

        self.ventana.update_idletasks()
        self.ventana.update()

la función time.sleep(n) de la biblioteca estándar de Python genera una pausa de n segundos en la ejecución del programa. Invocándola en el bucle obtenemos un retardo que podemos ajustar cambiando el argumento. Normalmente pasaremos una fracción de segundo, décimas, centésimas o milésimas.