I have a game - catching coins into a bowl. However, one of the criteria is to make it limited by entering time in seconds - how long will the game last. The time user enters is from tkinter.Entry
, and I have no idea how to execute a timer and a function at the same time. Code progress:
import tkinter, random, time
from threading import Thread
window = tkinter.Tk()
window.title("Dukaty")
canvas = tkinter.Canvas(window, height = 400, width = 800)
canvas.pack()
timeLabel = tkinter.Label(text = "Time:", font = "Helvetica 15")
timeLabel.pack()
timeEntry = tkinter.Entry(bd = 1)
timeEntry.pack()
mistakesLabel = tkinter.Label(text = "Allowed mistakes:", font = "Helvetica 15")
mistakesLabel.pack()
mistakesEntry = tkinter.Entry(bd = 1)
mistakesEntry.pack()
timeEntry.insert(0, "0")
mistakesEntry.insert(0, "0")
speed = 250
score = 0
mistakes = 0
allowedTime = ""
def countdown(t):
while t:
mins, secs = divmod(t, 60)
timer = '{:02d}:{:02d}'.format(mins, secs)
allowedTime = timer
print(allowedTime)
time.sleep(1)
t -= 1
print("Time's up!")
def timedGame():
time = int(timeEntry.get())
canvas.after(time * 1000)
end()
def movingCoin():
global speed, score, mistakes, allowedTime
time = int(timeEntry.get())
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
canvas.create_text(700, 50, text = str(score), font = "Helvetica 20", fill = "green", tags = "score")
canvas.create_text(700, 80, text = str(mistakes), font = "Helvetica 20", fill = "red", tags = "mistakes")
# ENDLESS
if timeEntry.get() == "0" and mistakesEntry.get() == "0":
while True:
if canvas.coords(coin)[1] < 360:
canvas.move(coin, 0, 5)
canvas.after(speed)
canvas.update()
elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
canvas.delete("score")
score += 1
canvas.create_text(700, 50, text=str(score), font="Helvetica 20", fill="green", tags="score")
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
else:
canvas.delete("mistakes")
mistakes += 1
canvas.create_text(700, 80, text=str(mistakes), font="Helvetica 20", fill="red", tags="mistakes")
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
# TIME - not done yet
elif timeEntry.get() != "0" and mistakesEntry.get() == "0":
while str(allowedTime) != "00:00":
if canvas.coords(coin)[1] < 360:
canvas.move(coin, 0, 5)
canvas.after(speed)
canvas.update()
elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
score += 1
print(score)
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
else:
mistakes += 1
print(mistakes)
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
# MISTAKES
elif timeEntry.get() == "0" and mistakesEntry != "0":
allowedMistakes = int(mistakesEntry.get())
print("Allowed mistakes: " + str(allowedMistakes))
while True:
if canvas.coords(coin)[1] < 360:
canvas.move(coin, 0, 5)
canvas.after(speed)
canvas.update()
elif canvas.coords(coin)[1] >= 360 and (canvas.coords(coin)[0] > (canvas.coords(bowl)[0] - 40) and canvas.coords(coin)[0] < (canvas.coords(bowl)[0] + 40)):
canvas.delete("score")
score += 1
canvas.create_text(700, 50, text=str(score), font="Helvetica 20", fill="green", tags="score")
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
else:
if allowedMistakes > mistakes:
canvas.delete("mistakes")
mistakes += 1
canvas.create_text(700, 80, text=str(mistakes), font="Helvetica 20", fill="red", tags="mistakes")
canvas.delete(coin)
coin = canvas.create_image(random.randint(15, 585), 18, image=coinImg, tags="coin")
speed -= 10
elif allowedMistakes == mistakes:
print("ending the program")
break
def end():
window.destroy()
def tap():
Thread(target=countdown(int(timeEntry.get()))).start()
Thread(target=movingCoin).start()
endButton = tkinter.Button(text = "End", command = end)
endButton.pack(side = "right")
startButton = tkinter.Button(text = "Start", command = tap)
startButton.pack(side = "left")
window.mainloop()
What this does, is that it starts the timer, and when it comes to end, THEN it executes the movingCoin function.
What I want to achieve is to make the timer start (when in Entry is value greater than 0) and at the same time execute the movingCoin - which then drops to the time section and the while breaks when the time is up.
You can use this method
window.after(1000,<function_name>)
It means the function call after 1 sec. If you are use recursion with this method then you can create timer.
I hope it works for you, cheer.
import time
# time.time() return in second
game_duration = float(input('duration: ')) + time.time()
game_is_running = True
while game_is_running:
if game_duration == time.time(): # this means: if now equal to game_duration
game_is_running = False
# note: it is quite critical where you place time.time()
# I used the following technique to build an explosion animation for 30 seconds, then it will do something else.
class Explosion(pygame.sprite.Sprite):
def __init__(self, center):
pygame.sprite.Sprite.__init__(self)
self.image = explosion_animation[0]
self.rect = self.image.get_rect()
self.rect.center = center
self.frame = 0
self.last_update = pygame.time.get_ticks()
self.duration = 30
def update(self):
now = pygame.time.get_ticks()
if now - self.last_update > self.duration:
self.last_update = now
self.frame += 1
if self.frame == len(explosion_animation):
self.kill()
else:
center = self.rect.center
self.image = explosion_animation[self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.