gpt4 book ai didi

python - PyGame 自定义事件

转载 作者:太空狗 更新时间:2023-10-29 22:07:57 25 4
gpt4 key购买 nike

想问下pygame中自定义事件的使用..
我用 pygame 做了一些实验,所以我知道 pygame 生成的事件通常是如何工作的……
我的问题是,为什么会有人对用户事件感兴趣,它是否有助于简化
组合 pygame-events
? 人们会如何实现它,并在现实世界的例子中
中受益......?

我在 a book I have been reading lately 中找到了一个例子..

# creating the event
CATONKEYBOARD = USEREVENT+1
my_event = pygame.event.Event(CATONKEYBOARD, message="Bad cat!")
pygame.event.post(my_event)

# handling it
for event in pygame.event.get():
if event.type == CATONKEYBOARD:
print event.message


我试过了,我发现该事件只生成一次(一旦发布)
有人能给我解释一下吗..?

谢谢..

最佳答案

您可以使用 pygame.event.post 手动发布自定义事件,如您的示例所示。

此外,您可以使用 pygame.time.set_timer 在特定时间间隔发布自定义事件。这是我为 another question 写的一个小例子,其中自定义事件用于移动对象和控制重新加载超时:

enter image description here

import pygame

# you'll be able to shoot every 450ms
RELOAD_SPEED = 450

# the foes move every 1000ms sideways and every 3500ms down
MOVE_SIDE = 1000
MOVE_DOWN = 3500

screen = pygame.display.set_mode((300, 200))
clock = pygame.time.Clock()

pygame.display.set_caption("Micro Invader")

# create a bunch of events
move_side_event = pygame.USEREVENT + 1
move_down_event = pygame.USEREVENT + 2
reloaded_event = pygame.USEREVENT + 3

move_left, reloaded = True, True

invaders, colors, shots = [], [] ,[]
for x in range(15, 300, 15):
for y in range(10, 100, 15):
invaders.append(pygame.Rect(x, y, 7, 7))
colors.append(((x * 0.7) % 256, (y * 2.4) % 256))

# set timer for the movement events
pygame.time.set_timer(move_side_event, MOVE_SIDE)
pygame.time.set_timer(move_down_event, MOVE_DOWN)

player = pygame.Rect(150, 180, 10, 7)

while True:
clock.tick(40)
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
if e.type == move_side_event:
for invader in invaders:
invader.move_ip((-10 if move_left else 10, 0))
move_left = not move_left
elif e.type == move_down_event:
for invader in invaders:
invader.move_ip(0, 10)
elif e.type == reloaded_event:
# when the reload timer runs out, reset it
reloaded = True
pygame.time.set_timer(reloaded_event, 0)

for shot in shots[:]:
shot.move_ip((0, -4))
if not screen.get_rect().contains(shot):
shots.remove(shot)
else:
hit = False
for invader in invaders[:]:
if invader.colliderect(shot):
hit = True
i = invaders.index(invader)
del colors[i]
del invaders[i]
if hit:
shots.remove(shot)

pressed = pygame.key.get_pressed()
if pressed[pygame.K_LEFT]: player.move_ip((-4, 0))
if pressed[pygame.K_RIGHT]: player.move_ip((4, 0))

if pressed[pygame.K_SPACE]:
if reloaded:
shots.append(player.copy())
reloaded = False
# when shooting, create a timeout of RELOAD_SPEED
pygame.time.set_timer(reloaded_event, RELOAD_SPEED)

player.clamp_ip(screen.get_rect())

screen.fill((0, 0, 0))

for invader, (a, b) in zip(invaders, colors):
pygame.draw.rect(screen, (150, a, b), invader)

for shot in shots:
pygame.draw.rect(screen, (255, 180, 0), shot)

pygame.draw.rect(screen, (180, 180, 180), player)
pygame.display.flip()

Can't I just "give in" the suitable conditions for posting the event, so that it can generate it automatically then ? I think that way it'd be more practical ...

实现这样的功能非常简单。只需创建条件和事件列表并检查主循环中的每个条件:

conditions = [ # blink if player is outside screen
(lambda: not s_r.contains(player), pygame.event.Event(E_OUTSIDE)),
# if mouse if over player then grow and shrink player
(lambda: player.collidepoint(pygame.mouse.get_pos()), pygame.event.Event(E_MOUSE))]

while True:
# generate events from conditions
map(pygame.event.post, [e for (c, e) in conditions if c()])

for event in pygame.event.get():
...

这是完整的例子:

enter image description here

import pygame

pygame.init()

screen = pygame.display.set_mode((300, 300))
s_r = screen.get_rect()
player = pygame.Rect((100, 100, 50, 50))
timer = pygame.time.Clock()
flash = 0
grow = True
color = pygame.color.Color('Black')

E_OUTSIDE = pygame.USEREVENT + 1
E_MOUSE = pygame.USEREVENT + 2

conditions = [ # blink if player is outside screen
(lambda: not s_r.contains(player), pygame.event.Event(E_OUTSIDE)),
# if mouse if over player then grow and shrink player
(lambda: player.collidepoint(pygame.mouse.get_pos()), pygame.event.Event(E_MOUSE))]

while True:
# generate events from conditions
map(pygame.event.post, [e for (c, e) in conditions if c()])

for event in pygame.event.get():
if event.type == pygame.QUIT:
raise
elif event.type == E_OUTSIDE and not flash:
flash = 5
elif event.type == E_MOUSE:
if grow:
player.inflate_ip(4, 4)
grow = player.width < 75
else:
player.inflate_ip(-4, -4)
grow = player.width < 50

flash = max(flash - 1, 0)
if flash % 2:
color = pygame.color.Color('White')

pressed = pygame.key.get_pressed()
l, r, u, d = map(lambda x: x*4, [pressed[k] for k in pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_s])
player.move_ip((-l + r, -u + d))

screen.fill(color)
color = pygame.color.Color('Black')

pygame.draw.rect(screen, pygame.color.Color('Grey'), player)

pygame.display.flip()
timer.tick(25)

关于python - PyGame 自定义事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24475718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com