Juego de Pong en Python
AnneONyme
-
AnneONyme -
AnneONyme -
Hola.
Con la ayuda del libro "aprendo a programar con Python" de Usborne, intento programar un juego de pong (con una única raqueta que se dirige con las flechas del teclado). Este juego es la versión más simple porque no hay puntuación y la pelota no acelera durante el juego. Aun así, me surge un problema: cuando se deja caer la pelota, el libro explica cómo mostrar un mensaje "¿Quieres volver a jugar?" con dos botones "sí" y "no". Si haces clic en no, se cierra la ventana de tkinter, y si haces clic en sí, el juego vuelve a empezar. Eso es lo que se supone que debe hacer el programa... Cuando el jugador hace clic en sí, la raqueta se posiciona a la izquierda, la pelota justo encima, pero pulsar las teclas flecha izquierda y flecha derecha no tiene efecto. > ( Al principio pensé que era yo quien había escrito mal el código propuesto por mi libro, así que descargué directamente el código del sitio www.usborne.com. Mismo problema. Concluyo que quizá se hayan equivocado al escribir el libro. Nadie parece haber tenido el mismo problema que yo... Utilizo Python 3.7.1 y aquí está mi código:
**Modificado por la moderación para una lectura más fácil del código; en el futuro usa las etiquetas, VER ESTA PÁGINA
Con la ayuda del libro "aprendo a programar con Python" de Usborne, intento programar un juego de pong (con una única raqueta que se dirige con las flechas del teclado). Este juego es la versión más simple porque no hay puntuación y la pelota no acelera durante el juego. Aun así, me surge un problema: cuando se deja caer la pelota, el libro explica cómo mostrar un mensaje "¿Quieres volver a jugar?" con dos botones "sí" y "no". Si haces clic en no, se cierra la ventana de tkinter, y si haces clic en sí, el juego vuelve a empezar. Eso es lo que se supone que debe hacer el programa... Cuando el jugador hace clic en sí, la raqueta se posiciona a la izquierda, la pelota justo encima, pero pulsar las teclas flecha izquierda y flecha derecha no tiene efecto. > ( Al principio pensé que era yo quien había escrito mal el código propuesto por mi libro, así que descargué directamente el código del sitio www.usborne.com. Mismo problema. Concluyo que quizá se hayan equivocado al escribir el libro. Nadie parece haber tenido el mismo problema que yo... Utilizo Python 3.7.1 y aquí está mi código:
**Modificado por la moderación para una lectura más fácil del código; en el futuro usa las etiquetas, VER ESTA PÁGINA
import tkinter from tkinter import messagebox import time canvasWidth = 750 canvasHeight = 500 fenêtre = tkinter.Tk() canvas = tkinter.Canvas(fenêtre, width=canvasWidth, height=canvasHeight, bg="dodgerblue4") canvas.pack() raquette = canvas.create_rectangle(0, 0, 40, 10, fill="dark turquoise") balle = canvas.create_oval(0, 0, 10, 10, fill="deep pink") fenêtre_ouverte = True def jouer_a_pong(): while fenêtre_ouverte == True: déplacer_la_raquette() déplacer_la_balle() fenêtre.update() time.sleep(0.02) if fenêtre_ouverte == True: vérifier_game_over() gauche_appuyé = 0 droite_appuyé = 0 def quand_touche_appuyée(event): global gauche_appuyé, droite_appuyé if event.keysym == "Left": gauche_appuyé = 1 elif event.keysym == "Right": droite_appuyé = 1 def quand_touche_relâchée(event): global gauche_appuyé, droite_appuyé if event.keysym == "Left": gauche_appuyé = 0 elif event.keysym == "Right": droite_appuyé = 0 vitesse_raquette = 6 def déplacer_la_raquette(): mouvement_raquette = vitesse_raquette * droite_appuyé - vitesse_raquette * gauche_appuyé (gauche_raquette, haut_raquette, droite_raquette, bas_raquette) = canvas.coords(raquette) if (gauche_raquette > 0 or mouvement_raquette > 0) and (droite_raquette < canvasWidth or mouvement_raquette < 0): canvas.move(raquette, mouvement_raquette, 0) mouvement_balle_X = 4 mouvement_balle_Y = -4 déf_haut_raquette = canvasHeight-40 déf_bas_raquette = canvasHeight-30 def déplacer_la_balle(): global mouvement_balle_X, mouvement_balle_Y (gauche_balle, haut_balle, droite_balle, bas_balle) = canvas.coords(balle) if mouvement_balle_X > 0 and droite_balle > canvasWidth: mouvement_balle_X = -mouvement_balle_X if mouvement_balle_X < 0 and gauche_balle < 0: mouvement_balle_X = -mouvement_balle_X if mouvement_balle_Y < 0 and haut_balle < 0: mouvement_balle_Y = -mouvement_balle_Y if mouvement_balle_Y > 0 and bas_balle > déf_haut_raquette and bas_balle < déf_bas_raquette: (gauche_raquette, haut_raquette, droite_raquette, bas_raquette) = canvas.coords(raquette) if droite_balle > gauche_raquette and gauche_balle < droite_raquette: mouvement_balle_Y = -mouvement_balle_Y canvas.move(balle, mouvement_balle_X, mouvement_balle_Y) def vérifier_game_over(): (gauche_balle, haut_balle, droite_balle, bas_balle) = canvas.coords(balle) if haut_balle > canvasHeight: rejouer = tkinter.messagebox.askyesno(message = " Veux-tu rejouer ? ") if rejouer == True: réinitialiser() else: fermer() def fermer(): global fenêtre_ouverte fenêtre_ouverte = False fenêtre.destroy() def réinitialiser(): global gauche_appuyé, droite_appuyé global mouvement_balle_X, mouvement_balle_Y gauche_appuyé = 0 droite_appuyé = 0 mouvement_balle_X = 4 mouvement_balle_Y = -4 canvas.coords(raquette, 10, déf_haut_raquette, 50, déf_bas_raquette) canvas.coords(balle, 20, déf_haut_raquette-10, 30, déf_haut_raquette) fenêtre.protocol("WM_DELETE_WINDOW", fermer) fenêtre.bind("<keypress>", quand_touche_appuyée) fenêtre.bind("<keyrelease>", quand_touche_relâchée) réinitialiser() jouer_a_pong()</keyrelease></keypress>
5 respuestas
Hola,
Es simplemente una historia de enfoque.
Cuando la toplevel se muestra preguntando si el jugador quiere volver a jugar, el canvas pierde el foco a favor de la toplevel, y cuando esta se cierra haciendo clic en el botón sí, el foco se asigna a otro widget a voluntad del gestor gráfico del sistema operativo; en tu caso, parece que a la ventana principal de Tk, en mi caso y en otros a otro widget que fue el anterior.
Es necesario entonces forzar el foco en el canvas. En la función reiniciar, la simple adición de la instrucción
canvas.focus_set()asegurará devolver el foco al canvas antes del inicio de una partida.
por cierto, la primera vez que se juega, tienen una especie de marco negro que no estaba ahí antes... ¿el foco?