Getting Started with 2D Games Using Tkinter (Part 9): Display a Counter
Source: Dev.to
Display a Counter
In this article we add a counter that shows how many demons remain on the screen.
First, create a variable named counter to keep track of the remaining number of demons.
# Demon counter
counter = TOTAL_DEMONS
Each time a demon is captured we decrement the counter inside the on_mouse_clicked() function.
Since counter is a global variable, declare it with global.
def on_mouse_clicked(e):
global counter
# Demon group
for demon in demons:
if demon.is_inside(e.x, e.y):
if demon.is_dead():
continue
demon.die(cvs)
counter = counter - 1 # Decrease demon counter
break
Inside the update() function, draw the counter on the screen using the counter variable.
def update():
"""Update function"""
cvs.delete("hud")
# Draw mouse coordinates
msg = "x:{}, y:{}".format(mx, my)
cvs.create_text(
mx, my,
text=msg,
fill="white",
font=FONT,
tag="hud"
)
# Draw demon counter
msg = "Remaining Demons: {}".format(counter)
cvs.create_text(
20, 20,
text=msg,
fill="white",
font=FONT,
tag="hud",
anchor="nw"
)
# Demon group
for demon in demons:
overlap_area(demon) # Screen wrap check
demon.update(cvs)
root.after(F_INTERVAL, update)
After implementing this, the number of remaining demons will be displayed on the screen.
Complete Code
sprite.py
import math
import random
import tkinter
class DemonSprite:
def __init__(self, cvs, x, y, r):
self.x = x
self.y = y
self.r = r
self.vx = 0
self.vy = 0
self.dead = False
# Circle for collision detection
self.oval = cvs.create_oval(
x - r, y - r, x + r, y + r,
fill="white", width=0
)
# Random demon type: r, g, b
self.type = random.choice(("r", "g", "b"))
file_alive = f"images/dmn_alive_{self.type}.png"
self.photo_alive = tkinter.PhotoImage(file=file_alive)
file_dead = f"images/dmn_dead_{self.type}.png"
self.photo_dead = tkinter.PhotoImage(file=file_dead)
self.image = cvs.create_image(x, y, image=self.photo_alive)
def update(self, cvs):
self.x += self.vx
self.y += self.vy
# Update circle position
cvs.coords(
self.oval,
self.x - self.r, self.y - self.r,
self.x + self.r, self.y + self.r
)
# Update image position
cvs.coords(self.image, self.x, self.y)
def set_x(self, x):
self.x = x
def set_y(self, y):
self.y = y
def move(self, spd, deg):
radian = deg * math.pi / 180
self.vx = spd * math.cos(radian)
self.vy = spd * math.sin(radian)
def stop(self):
self.move(0, 0)
def die(self, cvs):
self.dead = True
self.stop()
cvs.itemconfig(self.oval, fill="red")
cvs.itemconfig(self.image, image=self.photo_dead)
def is_dead(self):
return self.dead
def is_inside(self, x, y):
dx = (self.x - x) ** 2
dy = (self.y - y) ** 2
dist = (dx + dy) ** 0.5
return dist W: obj.set_x(0)
if obj.y H: obj.set_y(0)
Main script
def on_mouse_clicked(e):
global counter
for demon in demons:
if demon.is_inside(e.x, e.y):
if demon.is_dead():
continue
demon.die(cvs)
counter -= 1
break
def on_mouse_moved(e):
global mx, my
mx, my = e.x, e.y
root = tkinter.Tk()
root.title("Hello, Tkinter!!")
root.resizable(False, False)
root.bind("", on_mouse_clicked)
root.bind("", on_mouse_moved)
cvs = tkinter.Canvas(width=W, height=H, bg="black")
cvs.pack()
init()
update()
root.mainloop()
Stay tuned!