为了账号安全,请及时绑定邮箱和手机立即绑定

在Pygame中每隔几秒钟移动一个对象

/ 猿问

在Pygame中每隔几秒钟移动一个对象

慕盖茨1488219 2019-12-06 15:20:23

我正在使用pygame制作街机游戏,并且试图每隔几秒钟就有一个精灵更改位置。

我尝试使用time.sleep(1)并将帧频更改为.5clock.tick(.5))。

两者都仅在经过时间间隔后才能使对象改变位置,但是它们也使跟随我的鼠标更新的精灵以相同的速率移动。

我一直在研究,似乎无法找到另一种方法来使Sprite移动,而不会使我的程序每次运行时刷新速度变慢或“休眠”。


查看完整描述

3 回答

?
动漫人物

您可以Event结合使用pygame.time.set_timer():


pygame.time.set_timer()

在事件队列上重复创建一个事件

set_timer(eventid, milliseconds) -> None


设置事件类型以每给定的毫秒数出现在事件队列中


这是一个简单的完整示例。请注意敌人是如何每1000毫秒向侧面移动一次,每3500毫秒向下移动一次,并且您可以每450毫秒射击一次(所有事件都使用事件)。


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

分享编辑


查看完整回答
反对 回复 2019-12-06
?
慕码人8056858

怎么样


var = 0


while True:

    event_handling()


    game_logic()


    if var == 5:

        sprite.update.position()

        var = 0


    pygame.display.flip()

    var += 1

显然,这只是伪代码,但是您知道了。


查看完整回答
反对 回复 2019-12-06
?
aluckdog

如果Rect播放器在屏幕的Rect外部(例如,x坐标为负或x坐标+宽度大于屏幕宽度),那么钳制功能将“将其移回”它位于屏幕内部。Rect类的大多数函数都将返回一个新的Rect,但是它们具有_ip(就地)版本,它将代替原来的Rect。因此,这条线基本上只是确保播放器不能移出屏幕

查看完整回答
反对 回复 2019-12-06

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信