Saltar a contenido

Acelerando el juego

Como paso final, vamos a acelerar el juego a medida que acumulamos puntos. Con cada 5 puntos, sumaremos 1 al desplazamiento vertical de la bola. Eso hará que se mueva a mayor velocidad.

Añadiremos un contador de niveles. Inicialmente tomará el valor de 1, y cada vez que incrementemos el desplazamiento, aumentaremos el nivel y lo mostraremos en la barra de título.

Al reiniciar el juego, volveremos a poner el nivel a 1. No hace falta resetear el desplazamiento de la bola, porque estamos destruyendo los objetos bola y paleta, y creando unos nuevos.

12Nivel.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
import tkinter
import random

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

        # Configurar ventana
        self.ventana.title('Bola (nivel '+str(self.nivel)+')')
        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
        self.reiniciar= False
        self.puntos=0
        self.id_puntos = self.lienzo.create_text(
                                10, 385,
                                text=f'Puntuación: {0}',
                                fill='red',
                                anchor='nw')        

        self.texto = self.lienzo.create_text(250, 250, text='PULSE ESPACIO PARA INICIAR')

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

    def gestionar_tecla(self,evento):
        if evento.keysym=='Escape':
            self.terminar = True
        elif evento.keysym=='space':            
            self.en_juego = True
            self.lienzo.itemconfig(self.texto, state='hidden')
        elif evento.keysym=='Left':
            self.paleta.desplaz_paleta(-1)
        elif evento.keysym=='Right':
            self.paleta.desplaz_paleta(1)

    def detener_paleta(self,evento):
            self.paleta.desplaz_paleta(0)

    def mostrar_puntos(self):
            self.lienzo.itemconfig(self.id_puntos, text=f'Puntuación: {self.puntos}')

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

            if self.reiniciar and self.en_juego:
                self.lienzo.delete(self.id_bola)
                self.lienzo.delete(self.id_paleta)
                self.bola = Bola(self)
                self.paleta = Paleta(self)
                self.reiniciar = False
                self.puntos=0
                self.mostrar_puntos()
                self.nivel=1
                self.ventana.title('Bola (nivel '+str(self.nivel)+')')

            if self.en_juego:
                self.ventana.update_idletasks()
                self.bola.mostrar()
                self.paleta.mostrar()

            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 mostrar(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 toca la paleta, empezar a subir
        if self.toca_paleta():
            direccion = 1 if abs(self.desplaz_x)== self.desplaz_x else -1
            self.desplaz_x = random.choice([2, 3, 4]) * direccion
            self.desplaz_y = abs(self.desplaz_y)*(-1)
            self.juego.puntos += 1
            self.juego.mostrar_puntos()
            if self.juego.puntos > 1 and self.juego.puntos%5==0:
                self.juego.nivel +=1
                self.desplaz_y -=1
                self.juego.ventana.title('Bola (nivel '+str(self.juego.nivel)+')')

        # si toca el borde inferior, fin del juego
        if borde_inf_bola >= self.lienzo_alto:
            self.juego.en_juego = False
            self.juego.reiniciar = True
            self.juego.lienzo.itemconfig(self.juego.texto, state='normal')

        # 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)

    def toca_paleta(self):
        pos_bola = self.juego.lienzo.coords(self.juego.id_bola)
        pos_paleta = self.juego.lienzo.coords(self.juego.id_paleta)

        bola_sup = pos_bola[1]
        bola_inf = pos_bola[3]
        bola_izd = pos_bola[0]
        bola_dch = pos_bola[2]

        paleta_sup = pos_paleta[1]
        paleta_inf = pos_paleta[3]
        paleta_izd = pos_paleta[0]
        paleta_dch = pos_paleta[2]

        encima = bola_inf < paleta_sup
        debajo = bola_sup > paleta_inf
        izda   = bola_dch < paleta_izd
        dcha   = bola_izd > paleta_dch

        if debajo or encima:
            return False
        if izda or dcha:
            return False
        return True

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')
        self.desplaz = velocidad_paleta
        self.desplaz_x = 0

        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)

    def desplaz_paleta(self, sentido):
        if not self.juego.en_juego:
            return

        if sentido==0:
            self.desplaz_x=0

        coord = self.juego.lienzo.coords(self.juego.id_paleta)
        borde_izd_paleta = coord[0]
        borde_dch_paleta = coord[2]

        self.desplaz_x = 0
        if borde_izd_paleta > 0 and sentido == -1:
            self.desplaz_x = -velocidad_paleta

        elif borde_dch_paleta < self.lienzo_ancho and sentido == 1:        
            self.desplaz_x = velocidad_paleta

    def mostrar(self):
        self.juego.lienzo.move(self.juego.id_paleta, self.desplaz_x, 0)          

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