我昨天开始写这个答案,但与此同时你解决了你的问题:) 但我把我的代码,也许它对某人有用。它展示了如何使用scheduler 和animate
顺便说一句:我说波兰语,但我将所有变量重命名为英语(并转换文本),因为它是首选 - 更多信息请参阅 PEP 8 -- Style Guide for Python Code
主要问题是您使用sleep() 会阻止所有代码,而不能阻止其他元素。
在游戏和 GUI 框架中,您不应该使用 sleep() 和长时间运行的代码 - 它可能需要特殊的非阻塞函数来休眠 - 例如 pygame.time.get_ticks() - 或者它需要在单独的线程中运行代码(但它可以给其他问题)。
我以前从未使用过pgzero,但我创建了代码(没有sleep),它使用小步骤随机飞行x += random.randint(-5, 5)y += random.randint(-5, 5)。我使用Clock.scheduler() 而不是sleep 在死后几秒钟重新启动/重生飞行。
在这个版本中,苍蝇会做出许多小的随机动作。
import pgzrun
from pgzero.builtins import Actor, animate, keys
import random
import time
import os
# --- constants ---
WIDTH = 800
HEIGHT = 600
TITLE = 'KILL FLY!'
#ICON = 'data/fly.png'
# --- functions ---
def killed_fly():
screen.draw.text('Fly killed!', (280, 350), color=(255,0 ,0), fontsize=60, alpha=0.8)
def draw_score():
screen.draw.text('Killed:', (5,10), color=(0, 128, 128))
screen.draw.text(str(killed), (100,10), color=(0, 128, 0))
screen.draw.text('Missed:', (5,30), color=(0, 128, 128))
screen.draw.text(str(missed), (100,30), color=(0, 128, 0))
def respawn():
fly.x = random.randint(150, WIDTH-150)
fly.y = random.randint(100, HEIGHT-100)
fly.life = True
fly.image = 'fly'
def on_mouse_down(pos):
global killed
global missed
if fly.collidepoint(pos):
killed += 1
fly.life = False
fly.image = 'fly-swatter'
clock.schedule(respawn, 1.0)
else:
missed += 1
def update():
if fly.life:
fly.x += random.randint(-5, 5)
fly.y += random.randint(-5, 5)
# keep inside window
if fly.left < 0:
fly.left = 0
elif fly.right > WIDTH:
fly.right = WIDTH
if fly.top < 0:
fly.top = 0
elif fly.bottom > HEIGHT:
fly.bottom = HEIGHT
def draw():
background.draw()
fly.draw()
draw_score()
if not fly.life:
killed_fly()
# --- main ---
killed = 0
missed = 0
background = Actor('background')
fly = Actor('fly')
#fly.speed = 2
respawn() # (re)set some values at start
pgzrun.go()
接下来我创建了使用animate() 移动飞行的版本,我不需要update() 中的代码。函数animate() 使用on_finished=... 再次运行此函数,以便进行下一步。
import os
import random
import pgzrun
from pgzero.builtins import Actor, animate, keys
# --- constants ---
WIDTH = 512
HEIGHT = 512
TITLE = 'KILL FLY!'
#ICON = 'data/fly.png'
# --- functions ---
def killed_fly():
text_killed = screen.draw.text('Fly killed!', (280, 350), color=(255,0 ,0), fontsize=60, alpha=0.8)
def draw_score():
screen.draw.text('Killed:', (5,10), color=(0, 128, 128))
screen.draw.text(str(killed), (100,10), color=(0, 128, 0))
screen.draw.text('Missed:', (5,30), color=(0, 128, 128))
screen.draw.text(str(missed), (100,30), color=(0, 128, 0))
def respawn():
"""reset some values before every respawn"""
fly.x = random.randint(150, WIDTH-150)
fly.y = random.randint(100, HEIGHT-100)
fly.life = True
fly.image = 'fly'
animate_fly()
def animate_fly():
global anim
new_x = random.randint(5, WIDTH-5)
new_y = random.randint(5, HEIGHT-5)
anim = animate(fly, pos=(new_x, new_y), duration=3, on_finished=animate_fly)
def on_mouse_down(pos):
global killed
global missed
if fly.collidepoint(pos):
if anim:
anim.stop()
killed += 1
fly.life = False
fly.image = 'fly-swatter'
clock.schedule(respawn, 1.0)
else:
missed += 1
def update():
pass
def draw():
background.draw()
fly.draw()
draw_score()
if not fly.life:
killed_fly()
# --- main ---
killed = 0
missed = 0
anim = None
background = Actor('background')
fly = Actor('fly')
fly.speed = 2
respawn() # st
pgzrun.go()
编辑:
使用clock.scheduler 每 5 秒更改一次级别的版本。它将新苍蝇添加到列表中并更新所有苍蝇的速度。
为了简单起见,我创建了 Fly(Actor) 类以在类中包含所有属性和函数。
import os
import random
import pgzrun
from pgzero.builtins import Actor, animate, keys
# --- constants ---
WIDTH = 512
HEIGHT = 512
TITLE = 'KILL FLY!'
# --- classes ---
class Fly(Actor):
def __init__(self, *args, speed=2, **kwargs):
super().__init__(*args, **kwargs)
self.speed = speed
self.reset()
def reset(self):
"""reset some values before every respawn"""
self.x = random.randint(150, WIDTH-150)
self.y = random.randint(100, HEIGHT-100)
self.life = True
self.image = 'fly'
self.animate()
def animate(self):
new_x = random.randint(5, WIDTH-5)
new_y = random.randint(5, HEIGHT-5)
distance = self.distance_to((new_x, new_y))
duration = (distance/self.speed)/50
self.anim = animate(self, pos=(new_x, new_y), duration=duration, on_finished=self.animate)
def check_collision(self, pos):
if self.collidepoint(pos) and self.life:
if self.anim:
self.anim.stop()
self.life = False
self.image = 'fly-swatter'
clock.schedule(self.reset, 1.0)
return True
else:
return False
# --- functions ---
def killed_fly():
screen.draw.text('Fly killed!', (280, 350), color=(255,0 ,0), fontsize=60, alpha=0.8)
def draw_score():
screen.draw.text('Killed:', (5,10), color=(0, 128, 128))
screen.draw.text(str(killed), (100,10), color=(0, 128, 0))
screen.draw.text('Missed:', (5,30), color=(0, 128, 128))
screen.draw.text(str(missed), (100,30), color=(0, 128, 0))
screen.draw.text('Level:', (WIDTH-105,10), color=(0, 128, 128))
screen.draw.text(str(level), (WIDTH-45,10), color=(0, 128, 0))
def on_mouse_down(pos):
global killed
global missed
hit = False
for fly in flies:
if fly.check_collision(pos):
killed += 1
hit = True
if not hit:
missed += 1
#def on_key_down(key):
# global paused
#
# if key == keys.SPACE:
# paused = not paused
def update():
pass
def draw():
background.draw()
for fly in flies:
fly.draw()
draw_score()
#if paused:
# screen.draw.text('PAUSE', center=(WIDTH//2, HEIGHT//2), color=(0, 0, 0), fontsize=150)
#if not fly.life:
# killed_fly()
def level_up():
global level
global speed
# level number
level += 1
# bigger speed for flies
speed += .5
# add new fly with new speed (it will automaticaly run `animate` with this speed
flies.append(Fly('fly', speed=speed))
# change speed for other flies
for fly in flies:
fly.speed = speed
# run it again after 5 seconds
clock.schedule(level_up, 5.0)
# --- main ---
#paused = False
level = 1 # current level
speed = 2 # current speed
killed = 0
missed = 0
background = Actor('background')
# create list with only one fly
flies = [
Fly('fly'),
]
# update level after 5 seconds
clock.schedule(level_up, 5.0)
pgzrun.go()
顺便说一句:当您按下 Space 时,我尝试添加功能 Pause,但似乎 animate() 没有暂停它的方法 - 它需要创建自己的 animate()。
(使用OBS录制并使用ffmpeg转换为动画.gif
想运行它的人的图像。
images/background.png
(来自维基百科的图片Lenna)
images/fly.png
images/fly-swatter.png
(fly 在免费的Inkscape 中创建为.svg 并导出到.png)