使用 Tkinter 入门 2D 游戏(第 8 部分):向精灵添加恶魔图像
发布: (2025年12月24日 GMT+8 13:54)
4 min read
原文: Dev.to
Source: Dev.to
请提供您希望翻译的完整文本内容,我将按照要求保留源链接并翻译正文部分。
1. 准备恶魔图片
请复制并在你的游戏中使用以下恶魔图片。
| 类型 | 活动图片 | 文件名(活动) | 死亡图片 | 文件名(死亡) |
|---|---|---|---|---|
| Blue Demon | ![]() | dmn_alive_b.png | ![]() | dmn_dead_b.png |
| Green Demon | ![]() | dmn_alive_g.png | ![]() | dmn_dead_g.png |
| Red Demon | ![]() | dmn_alive_r.png | ![]() | dmn_dead_r.png |
将所有图片文件放入 images 文件夹。
# Folder structure
project_folder/
├─ main.py
├─ sprite.py
└─ images/
├─ bg_jigoku.png
├─ dmn_alive_b.png # Blue demon (alive)
├─ dmn_alive_g.png # Green demon (alive)
├─ dmn_alive_r.png # Red demon (alive)
├─ dmn_dead_b.png # Blue demon (dead)
├─ dmn_dead_g.png # Green demon (dead)
└─ dmn_dead_r.png # Red demon (dead)
2. 改进 DemonSprite 类
在 DemonSprite 类的构造函数中加入图像加载逻辑。
- 图像对象使用
tkinter.PhotoImage()创建,并通过canvas.create_image()显示。 - 随机选择恶魔颜色(
"r"、"g"或"b")。 - 活着的图像保存在
self.photo_alive中。 - 死亡的图像保存在
self.photo_dead中。 - 当前显示的图像保存在
self.image中。
# sprite.py (excerpt)
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
# 圆形(碰撞参考)
self.oval = cvs.create_oval(
x - r, y - r, x + r, y + r,
fill="white", width=0
)
# 随机选择恶魔类型: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)
在 die() 方法中使用 canvas.itemconfig() 更新图像:
# sprite.py (excerpt)
def die(self, cvs):
self.dead = True
self.stop()
# 更改碰撞圆的颜色
cvs.itemconfig(self.oval, fill="red")
# 切换为死亡的精灵图像
cvs.itemconfig(self.image, image=self.photo_dead)
实现上述功能后,点击精灵会使其停止并切换图像。

完整代码
下面是包含所有功能的完整实现。
# sprite.py (complete code)
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
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)
# Start with the alive image
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
# Additional methods (e.g., stop, die) would go here
随意将此类集成到你的主游戏循环中,享受动画恶魔吧!
其他辅助函数
def move(self, spd, deg):
rad = deg * math.pi / 180
self.vx = spd * math.cos(rad)
self.vy = spd * math.sin(rad)
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
def on_mouse_clicked(e):
for demon in demons:
if demon.is_inside(e.x, e.y) and not demon.is_dead():
demon.die(cvs)
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("<Button-1>", on_mouse_clicked)
root.bind("<Motion>", on_mouse_moved)
cvs = tkinter.Canvas(width=W, height=H, bg="black")
cvs.pack()
init()
update()
root.mainloop()
接下来是什么?
感谢阅读!
在下一篇文章中,我们将在屏幕上显示计数器。
敬请期待!





