I am trying to do code a simple game in python using tkinter where a block jumps over obstacles, however I got stuck on the jumping part. Every time I call the jump function it jumps slower and slower, and I don't know the reason. Ty in advance.
import time
import tkinter
import random
bg = "white"
f = 2
k=0
t = 0.01
groundLevel = 550
root = tkinter.Tk()
root.geometry("1000x600")
canvas = tkinter.Canvas(root,width = 1000,height = 1000,bg = bg)
canvas.pack(fill= tkinter.BOTH, expand= True)
posX = 50
posY= 530
startButton = tkinter.Button(canvas,text=" Start ")
def startPlayer(xx,yy):
canvas.create_rectangle(xx-20,yy-22,xx 20,yy 18,fill = "orange")
return(xx,yy)
def move(x,y,x2,y2,direction,fill,outline):
global f
#direction 0 = up
#direction 1 = down
#direction 2 = left
#direction 3 = right
if direction == 0:
canvas.create_rectangle(x,y,x2,y2,fill="cyan",outline="cyan")
canvas.create_rectangle(x,y-f,x2,y2-f,fill=fill,outline=outline)
if direction == 1:
canvas.create_rectangle(x,y,x2,y2,fill="cyan",outline="cyan")
canvas.create_rectangle(x,y f,x2,y2 f,fill=fill,outline=outline)
if direction == 2:
canvas.create_rectangle(x,y,x2,y2,fill="cyan",outline="cyan")
canvas.create_rectangle(x,y,x2,y2,fill=fill,outline=outline)
if direction == 3:
canvas.create_rectangle(x,y,x2,y2,fill="cyan",outline="cyan")
canvas.create_rectangle(x,y,x2,y2,fill=fill,outline=outline)
def playerJump():
global groundLevel, f, k,posX,posY,t
while k != 1:
move(posX-20,posY-22,posX 20,posY 18,direction = 0, fill = "orange",outline = "black")
posY -= 2
canvas.update()
if (posY) == 480:
k = 1
time.sleep(t)
k = 0
while k != 1:
move(posX-20,posY-22,posX 20,posY 18,direction = 1, fill = "orange",outline = "black")
posY = 2
canvas.update()
if (posY) == 530:
k = 1
time.sleep(t)
k = 0
def start():
canvas.create_rectangle(0,0,1000,600,fill="cyan")
canvas.create_line(0,550,1000,550,width = 3)
startButton.destroy()
startPlayer(50,530)
startGameButton = tkinter.Button(canvas, text ="Go!",command = playerJump)
startGameButton.place(x = 35, y=400)
return(startGameButton)
def resetButton():
global startGameButton
startGameButton.destroy()
startGameButton = tkinter.Button(canvas, text ="Go!",command = playerJump)
startGameButton.place(x = 35, y=400)
startImage = tkinter.PhotoImage(file="C:/Users/marti/OneDrive/Desktop/Wheel finder/startSign.png")
canvas.create_rectangle(0,0,1000,1000,fill="green")
startButton.config(image = startImage,command = start)
startButton.place(x = 130, y= 25)
canvas.create_rectangle(300,400,700,500,fill="#113B08",outline = "black",width = 3)
canvas.create_text(500,450,text = "By: --------", font = "Arial 30",fill ="white")
I shrinking the sleep time every time it runs so its faster, but that is only a temporary solution and it didn't even work.
CodePudding user response:
Problem with your code is you are always adding new items into your canvas. When you jump you update orange rectangle and repaint its old place. However they stack top of each other and handling too many elements makes slower your program.
We create player and return it to main function.
def startPlayer(xx,yy):
player=canvas.create_rectangle(xx-20,yy-22,xx 20,yy 18,fill = "orange")
return player
This is new start function. Check that we get player and send to playerjump function.
def start():
canvas.create_rectangle(0,0,1000,600,fill="cyan")
canvas.create_line(0,550,1000,550,width = 3)
startButton.destroy()
player = startPlayer(50,530)
startGameButton = tkinter.Button(canvas, text ="Go!",command = lambda :playerJump(player))
startGameButton.place(x = 35, y=400)
return(startGameButton)
And this is playerjump function.We get player and sent to move function.
def playerJump(player):
global groundLevel, f, k,posX,posY,t
while k != 1:
move(posX-20,posY-22,posX 20,posY 18,direction = 0, fill = "orange",outline = "black",player=player)
posY -= 2
canvas.update()
if (posY) == 480:
k = 1
time.sleep(t)
k = 0
while k != 1:
move(posX-20,posY-22,posX 20,posY 18,direction = 1, fill = "orange",outline = "black",player=player)
posY = 2
canvas.update()
if (posY) == 530:
k = 1
time.sleep(t)
k = 0
Except move lines, I didn't change anything in this function.
Okay now let's check key part.
def move(x,y,x2,y2,direction,fill,outline,player):
global f
#direction 0 = up
#direction 1 = down
#direction 2 = left
#direction 3 = right
if direction == 0:
canvas.coords(player,x,y-f,x2,y2-f)
if direction == 1:
canvas.coords(player,x,y f,x2,y2 f)
if direction == 2:
canvas.coords(player,x,y,x2,y2)
if direction == 3:
canvas.coords(player,x,y,x2,y2)
look that instead of creating new rectangles,we updated existing one. which is much more stable
Also you forgot adding root.mainloop in your code snippet.