【问题标题】:Continuous object creation in pygame?在pygame中连续创建对象?
【发布时间】:2017-05-04 19:07:37
【问题描述】:

好的,所以我对这个主题进行了一些研究。我正在用 Python 的 Pygame 创建一个游戏,它是著名的“雷电 2”的复制品。我的游戏循环与我见过的非常相似。我要做的是让构造函数在按住空格键的同时创建一个子弹对象(使用我的 Bullet 类)。但是,以下代码每次按键仅创建一个项目符号。按住按钮什么都不做,只会创建一个项目符号。

while game.play is True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                b = Bullet(x, y)
                bullet_group.add(b)

    bullet_group.draw(screen)

不知道从这里去哪里。欢迎和感谢任何帮助。

【问题讨论】:

  • 所以你想每次按键创建几个子弹?
  • 您只查看KEYDOWN 事件,因此每次按键您只能获得一次事件。对于我喜欢使用的此类实时游戏,pygame.key.get_pressed()
  • @cmd 嘿,它有效!谢谢你的协助。我不知道 KEYDOWN 不适用于创建多个对象...
  • @Minighost 不要忘记接受答案以完成问题/答案过程......(答案左侧的“V”在点击时变为绿色,表示答案已被接受)

标签: python python-2.7 pygame


【解决方案1】:

这应该可以按您的预期工作:

addBullets = False
while game.play is True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                addBullets = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                addBullets = False

    if addBullets: 
        b = Bullet(x, y)
        bullet_group.add(b)

    bullet_group.draw(screen)     

您将项目符号的创建从事件处理中移出,并仅在其中设置一个“标志”,如果释放键停止创建项目符号,则该“标志”将被收回。

而且......正如jsbueno 的评论中提到的那样,这也可以:

while game.play is True:
    for event in pygame.event.get():
       pass # do something with events
    if pygame.key.get_pressed()[pygame.K_SPACE]: 
        b = Bullet(x, y)
        bullet_group.add(b)

【讨论】:

  • 酷。另一种选择是使用pygame.key,get_pressed()[pygame.K_SPACE] 来了解在函数调用时是否按下了给定的键(在本例中为空格)。
  • 哇这么多选择...我想我会坚持@jsbueno 的使用get_pressed() 的方法。似乎与我的代码一致。非常感谢你们!
【解决方案2】:

我认为另一个答案缺少重要的细节。您很可能不想每帧都发射子弹,因此您需要某种计时器。最简单的方法是计算帧数,但是游戏会受到帧率的限制(最好不要这样做)。

firing = False
bullet_timer = 0

while game.play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            game.play = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                firing = True
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                firing = False

    if bullet_timer > 0:
        bullet_timer -= 1
    elif firing:  # Timer is less than 0 and we're firing.
        bullet = Bullet()
        bullet_group.add(bullet)
        bullet_timer = 10   # Reset timer to 10 frames.

与帧速率无关的变体是使用pygame.Clock.tick 返回的时间(自上次调用以来经过的时间)并从计时器变量中减去它。如果计时器是<= 0,我们就可以开火了。

clock = pygame.time.Clock()
firing = False
bullet_timer = 0

while game.play:
    # `dt` is the passed time since the last tick in seconds.
    dt = clock.tick(30) / 1000

    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                firing = True
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                firing = False

    if bullet_timer > 0:
        bullet_timer -= dt
    elif firing:  # Timer is below 0 and we're firing.
        bullet = Bullet()
        bullet_group.add(bullet)
        bullet_timer = .5  # Reset timer to a half second. 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多