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

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

how to run turtle graphics in Colaboratory

Export result set on Dbeaver to CSV