【问题标题】:How can I use time to make random arrows in pygame? [duplicate]如何利用时间在 pygame 中制作随机箭头? [复制]
【发布时间】:2020-02-29 08:18:39
【问题描述】:

我试图在 pygame 中编写一个随机显示箭头精灵的代码(如 DDR)。我有使用时间的想法,但是 sleep 会暂停整个程序,我只想暂停一个箭头。

我试图创建一个随机列表类型的调用者,但这不起作用,因为箭头需要在它们消失之前到达终点。

import pygame, sys
from pygame.locals import *
from random import randint
from time import sleep

#Variables
WIDTH = 800
HEIGHT = 450
FPS = 30
running = True
BLACK = (0, 0, 0)
SALMON = (253, 171, 159)

screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Tempoify")

pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()

#####################################
# Gray Arrows

class ArrowRightGray(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("gray right.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (750, 25)


class ArrowLeftGray(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("gray left.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (750, 125)


class ArrowUpGray(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("gray up.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (750, 250)

class ArrowDownGray(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("gray down.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (750, 375)

class ArrowRight(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("red right.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (25, 25)

  def update(self):
    self.rect.x += 5
    if (self.rect.left > (WIDTH + 50)):
        self.rect.right = 0

class ArrowLeft(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("blue left.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (25, 125)

  def update(self):
    self.rect.x += 5
    if (self.rect.left > (WIDTH + 50)):
        self.rect.right = 0

class ArrowUp(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("green up.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (25, 250)

  def update(self):
    self.rect.x += 5
    if (self.rect.left > (WIDTH + 50)):
        self.rect.right = 0

class ArrowDown(pygame.sprite.Sprite):

  def __init__(self):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("yellow down.png").convert()
    self.image.set_colorkey(BLACK)
    self.rect = self.image.get_rect()
    self.rect.center = (25, 375)

  def update(self):
    self.rect.x += 5
    if (self.rect.left > (WIDTH + 50)):
        self.rect.right = 0

allArrows = pygame.sprite.Group()
a1g = ArrowRightGray()
a1 = ArrowRight()

a2g = ArrowLeftGray()
a2 = ArrowLeft()

a3g = ArrowUpGray()
a3 = ArrowUp()

a4g = ArrowDownGray()
a4 = ArrowDown()

allArrows.add(a1g)
allArrows.add(a1)
allArrows.add(a2g)
allArrows.add(a2)
allArrows.add(a3g)
allArrows.add(a3)
allArrows.add(a4g)
allArrows.add(a4)

while running:
  clock.tick(FPS)

  #Update
  allArrows.update()

  keys = pygame.key.get_pressed()

  for event in pygame.event.get():
      if keys[pygame.K_RIGHT]:
          if pygame.sprite.collide_rect(a1, a1g):
              a1.rect.center = (900, 600)
      elif keys[pygame.K_LEFT]:
          if pygame.sprite.collide_rect(a2, a2g):
              a2.rect.center = (900, 600)
      elif keys[pygame.K_UP]:
          if pygame.sprite.collide_rect(a3, a3g):
              a3.rect.center = (900, 600)
      elif keys[pygame.K_DOWN]:
          if pygame.sprite.collide_rect(a4, a4g):
              a4.rect.center = (900, 600)
  #draw
  screen.fill(SALMON)
  allArrows.draw(screen)

  pygame.display.flip()

pygame.quit()

最后,箭头应该会到达屏幕的尽头并随机显示。当它们与灰色箭头碰撞时,它们也应该消失。

【问题讨论】:

    标签: python python-2.7 time pygame pygame-clock


    【解决方案1】:

    首先不要为每个箭头创建类。类是具有属性的对象。使用类的属性并创建具有不同外观和行为的类的实例。将参数添加到构造函数的签名中,并使用参数来初始化属性。

    为位置和图像文件名添加参数:

    class ArrowGray(pygame.sprite.Sprite):
    
        def __init__(self, pos, imagename):
            pygame.sprite.Sprite.__init__(self)
            self.image = pygame.image.load(imagename).convert()
            self.image.set_colorkey(BLACK)
            self.rect = self.image.get_rect()
            self.rect.center = pos
    
    class Arrow(pygame.sprite.Sprite):
    
        def __init__(self, pos, imagename):
            pygame.sprite.Sprite.__init__(self)
            self.image = pygame.image.load(imagename).convert()
            self.image.set_colorkey(BLACK)
            self.rect = self.image.get_rect()
            self.rect.center = pos
    
        def update(self):
            self.rect.x += 5
            if (self.rect.left > (WIDTH + 50)):
                self.rect.right = 0
    
    a1g = ArrowGray((750, 25), "gray right.png")
    a2g = ArrowGray((750, 125), "gray left.png")
    a3g = ArrowGray((750, 250), "gray up.png")
    a4g = ArrowGray((750, 375), "gray down.png")
    
    a1 = Arrow((25, 25), "red right.png")
    a2 = Arrow((25, 125), "blue left.png")
    a3 = Arrow((25, 250), "green up.png")
    a4 = Arrow((25, 375), "yellow down.png")
    

    我建议使用计时器事件。使用pygame.time.set_timer() 重复创建USEREVENT。例如:

    arrowGrayList = [a1g, a2g, a3g, a4g]
    arrowList = [a1, a2, a3, a4]
    allArrows = pygame.sprite.Group()
    
    millisecondsDelay = 500 # 0.5 seconds
    arrowTimerEvent = pygame.USEREVENT + 1
    pygame.time.set_timer(arrowTimerEvent, millisecondsDelay)
    spawned = 0
    
    while running:
        clock.tick(FPS)
    
        #Update
        allArrows.update()
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
    
            if event.type == arrowTimerEvent:
                if spawned < len(arrowList):
                    allArrows.add(arrowGrayList[spawned])
                    allArrows.add(arrowList[spawned])
                    spawned += 1
    
        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT]:
            if pygame.sprite.collide_rect(a1, a1g):
                a1.rect.center = (900, 600)
        if keys[pygame.K_LEFT]:
            if pygame.sprite.collide_rect(a2, a2g):
                a2.rect.center = (900, 600)
        if keys[pygame.K_UP]:
            if pygame.sprite.collide_rect(a3, a3g):
                a3.rect.center = (900, 600)
        if keys[pygame.K_DOWN]:
            if pygame.sprite.collide_rect(a4, a4g):
                a4.rect.center = (900, 600)
        #draw
        screen.fill(SALMON)
        allArrows.draw(screen)
    
        pygame.display.flip()
    
    pygame.quit()
    

    注意,在 pygame 中可以定义客户事件。每个事件都需要一个唯一的 ID。用户事件的 ID 必须从 pygame.USEREVENT 开始。在这种情况下,pygame.USEREVENT+1 是计时器事件的事件 ID,它会产生箭头。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-31
      • 2018-09-24
      • 2017-09-17
      • 1970-01-01
      • 2015-12-28
      • 2017-07-13
      相关资源
      最近更新 更多