Why does my pong game freeze after the ball hits the bottom and it doesn't display the “Game Over” screen?
Why does my pong game freeze after the ball hits the bottom and it doesn't display the “Game Over” screen?
I am a high school student and also a python enthusiast. I am trying to make a pong game in python and most of it worked but I am trying to make the program wait 3 seconds before the ball starts moving and when the ball hits the bottom the program just freezes and it doesn't display the "Game Over" screen. Would anyone be able to help me with this? Here is the code I am working on.
from tkinter import *
import random
import time
class Ball:
def __init__(self, canvas, color, size, paddle):
self.canvas = canvas
self.paddle = paddle
self.id = canvas.create_oval(15, 15, size, size, fill=color)
self.canvas.move(self.id, 245, 100)
self.xspeed = random.randrange(-3,3)
self.yspeed = -1
self.hit_bottom = False
self.score = 0
def draw(self):
self.canvas.move(self.id, self.xspeed, self.yspeed)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.yspeed = 9
if pos[3] >= 400:
self.hit_bottom = True
if pos[0] <= 0:
self.xspeed = 9
if pos[2] >= 500:
self.xspeed = -9
if self.hit_paddle(pos) == True:
self.yspeed = -9
self.xspeed = random.randrange(-3,3)
self.score += 1
def hit_paddle(self, pos):
paddle_pos = self.canvas.coords(self.paddle.id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2]:
if pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
return True
return False
class Paddle:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_rectangle(0,0, 168, 20, fill=color)
self.canvas.move(self.id, 200, 300)
self.xspeed = 0
self.canvas.bind_all('<KeyPress-Left>', self.move_left)
self.canvas.bind_all('<KeyPress-Right>', self.move_right)
def draw(self):
self.canvas.move(self.id, self.xspeed, 0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.xspeed = 0
if pos[2] >= 500:
self.xspeed = 0
def move_left(self, evt):
self.xspeed = -12
def move_right(self, evt):
self.xspeed = 12
tk = Tk()
tk.title("Pong")
canvas = Canvas(tk, width=500, height=400, bd=0, bg='#ff4fea')
canvas.pack()
label = canvas.create_text(5, 5, anchor=NW, text="Score: 0")
tk.update()
paddle = Paddle(canvas, '#2be2ff')
ball = Ball(canvas, '#ddff00', 38, paddle)
while ball.hit_bottom == False:
ball.draw()
paddle.draw()
canvas.itemconfig(label, text="Score: "+str(ball.score))
tk.update_idletasks()
tk.update()
time.sleep(0.01)
while ball.hit_bottom == True:
print
go_label = canvas.create_text(250,200,text="Game Over Play Again")
tk.update()
1 Answer
1
You should not use time.sleep
in a tkinter application; use root.after
instead.
You also do not need to create your own game loop inside a while loop; tk.mainloop
does it for you.
calling update
or update_idle_tasks
is rarely necessary; let tkinter handle all these low levels actions for you.
time.sleep
root.after
tk.mainloop
update
update_idle_tasks
Here is a working version of your Pong app that addresses the main issues, and answers your question. It does not restart the game, you will have to work this out by yourself. Maybe you will want to place the game logic in a class that will handle the restarting ans setting up for you? Please ask a new question if you are having difficulties.
I changed the star import to import tkinter as tk
which keeps the namespace tidy, and I renamed your variable tk
using root
instead.
import tkinter as tk
tk
root
import tkinter as tk
import random
class Ball:
def __init__(self, canvas, color, size, paddle):
self.canvas = canvas
self.paddle = paddle
self.id = canvas.create_oval(15, 15, size, size, fill=color)
self.canvas.move(self.id, 245, 100)
self.xspeed = random.randrange(-3,3)
self.yspeed = -1
self.hit_bottom = False
self.score = 0
def draw(self):
self.canvas.move(self.id, self.xspeed, self.yspeed)
pos = self.canvas.coords(self.id)
if pos[1] <= 0:
self.yspeed = 9
if pos[3] >= 400:
self.hit_bottom = True
if pos[0] <= 0:
self.xspeed = 9
if pos[2] >= 500:
self.xspeed = -9
if self.hit_paddle(pos):
self.yspeed = -9
self.xspeed = random.randrange(-3,3)
self.score += 1
def hit_paddle(self, pos):
paddle_pos = self.canvas.coords(self.paddle.id)
if pos[2] >= paddle_pos[0] and pos[0] <= paddle_pos[2] and
pos[3] >= paddle_pos[1] and pos[3] <= paddle_pos[3]:
return True
return False
class Paddle:
def __init__(self, canvas, color):
self.canvas = canvas
self.id = canvas.create_rectangle(0, 0, 168, 20, fill=color)
self.canvas.move(self.id, 200, 300)
self.xspeed = 0
self.canvas.bind_all('<KeyPress-Left>', self.move_left)
self.canvas.bind_all('<KeyPress-Right>', self.move_right)
def draw(self):
self.canvas.move(self.id, self.xspeed, 0)
pos = self.canvas.coords(self.id)
if pos[0] <= 0:
self.xspeed = 0
if pos[2] >= 500:
self.xspeed = 0
def move_left(self, evt):
self.xspeed = -12
def move_right(self, evt):
self.xspeed = 12
def run_game():
ball.draw()
paddle.draw()
canvas.itemconfig(label, text="Score: "+str(ball.score))
if not ball.hit_bottom:
root.after(10, run_game)
else:
canvas.create_text(250, 200, text="Game Over Play Again")
if __name__ == '__main__':
root = tk.Tk()
root.title("Pong")
canvas = tk.Canvas(root, width=500, height=400, bd=0, bg='#ff4fea')
canvas.pack()
label = canvas.create_text(5, 5, anchor=tk.NW, text="Score: 0")
paddle = Paddle(canvas, '#2be2ff')
ball = Ball(canvas, '#ddff00', 38, paddle)
run_game()
tk.mainloop()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Comments
Post a Comment