Reputation: 1959
I'm attempting to implement a simple Pong game in Python using Tkinter, but unfortunately I'm having some major issues with flickering. I'm using a Canvas widget that covers the entire window and I'm drawing rectangles on said canvas many times per second. When I do this all drawn rectangles flicker regularly while the game is running, disappearing for a fraction of a second before appearing again.
A simple example of the logic I use for drawing in my game can be seen below, by running it you should be able to see the flickering in action:
from tkinter import *
import threading, time
def loop():
FRAME_TIME = 1 / 60
while True:
render()
time.sleep(FRAME_TIME)
def render():
canvas.delete(ALL)
canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill='black')
WIDTH = 800
HEIGHT = 600
root = Tk()
canvas = Canvas(root, width=800, height=600)
canvas.pack()
threading.Thread(target=loop, daemon=True).start()
root.mainloop()
Any ideas as to what is causing it?
Upvotes: 5
Views: 5237
Reputation: 5319
The threading is totally not needed for your script (The Tkinter
doesn't love the threading).
You should use the widget.after()
instead of infinite for
loop.
I guess you should define the canvas and the rectangle on the canvas and in a function you should move the other widgets. In this case you shouldn't delete/recreate the widgets.
The black "background" (rectangle) is static and it is not updated during the script running. An oval widget has been created on the canvas (create_oval()
) and this widget moves in the render
function (randomly change the X-Y positions between -3 and 3).
The canvas.after(10, render)
means to call again-and-again the render
function in every 10 secs. So actually it is an animation and the oval will move always on your canvas.
Example:
from tkinter import *
import random
def render():
canvas.move(oval, random.randint(-3, 3), random.randint(-3, 3))
canvas.after(10, render)
WIDTH = 800
HEIGHT = 600
root = Tk()
canvas = Canvas(root, width=800, height=600)
canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill="black")
oval = canvas.create_oval(400, 400, 410, 410, fill="red")
canvas.pack()
render()
root.mainloop()
GUI:
I think it is a good starting point for you to implement the complete pong game.
Upvotes: 1