python自定义事件event_python – PyGame自定义事件

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

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

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():

...

这是完整的例子:

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)

玩法 1)不设过关卡的设置,砖块是一层层压下来的,随着时间或者分数的推移,压的速度变快,每一层生成的砖的均衡的生命值在不断的提高,记录玩家所获得的最高分。 2)两边的墙会随着玩家分数的提高,逐步的变软,最终消失。消失的时候两边的墙会变成两块挡板,也需要玩家的控制,当球在左右两边没有接住的时候,损失生命值。 3)挡板也是有生命的,随着球的不断的打击,挡板的生命值也在不断的减少,需要补充道具掉下来的生命值,不然也会死亡。(现在不处理) 4)球有三种能量类型,火球,冰球,电球,相对应,挡板也有三种类型。每种类型对砖和挡板造成的伤害会不同,例如火球是一种范围伤害,冰球可以降低挡板移动的速度。(还是设想) 挡板三种能量类型有不同的性质,挡板可以吃道具变形(或者特定分数强制变形)。 火球能量类型的挡板的速度,加速度,摩擦力都比较适中,容易控制,但是生命最大值比较小。 冰球能量类型的挡板的加速度,摩擦力,最大的速度都很大,虽然不容易控制,但是生命值最大。 电球能量类型的挡板的加速度,和最大速度都是最大的,摩擦力比较小,很容易达到非常快的速度,适合与喜欢高速的玩家。 挡板吃到掉落的物品能够改变能量类型,球落到挡板上的时候改变成同样的能量类型。 6)物品能够改变生命值,加速度和能量类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值