Saltar a contenido

Añadir puntuación

Ahora que ya tenemos el juego funcional, vamos a mostrar una puntuación en el margen inferior izquierdo de la ventana. Cada vez que la bola rebota en la paleta, además de cambiar de dirección, sumamos un punto.

11Puntuacion.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
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
        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()

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

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

Al crear al juego, añadimos un contador de puntos y un texto en el fondo del canvas:

self.puntos=0
self.id_puntos = self.lienzo.create_text(
                            10, 385,
                            text=f'Puntuación: {0}',
                            fill='red',
                            anchor='nw')

Cada vez que la pelota rebota en la paleta, sumamos un punto y refrescamos el texto:

self.juego.puntos += 1
self.juego.mostrar_puntos()

Al reiniciar el juego, ponemos el contador a cero:

self.puntos=0
self.mostrar_puntos()

Necesitamos que el juego tenga un método mostrar_puntos():

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