如何利用时间在pygame中制作随机箭头?
How can I use time to make random arrows in pygame?
我正在尝试在 pygame 中编写一个随机显示箭头精灵的代码(如 DDR)。我有使用时间的想法,但是睡眠暂停了整个程序,我只想暂停一个箭头。
我曾尝试创建一个随机列表类型的调用方,但这不起作用,因为箭头需要在它们消失之前到达终点。
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()
最后,箭头应该到达屏幕的尽头并随机出现。当它们与灰色箭头碰撞时它们也应该消失。
首先不要为每个箭头创建 class。 class 是具有属性的对象。使用 class 的属性并创建具有不同外观和行为的 class 实例。将参数添加到构造函数的签名中,并使用参数来初始化属性。
为位置和图像文件名添加参数:
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()
to repeatedly create an 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。
我正在尝试在 pygame 中编写一个随机显示箭头精灵的代码(如 DDR)。我有使用时间的想法,但是睡眠暂停了整个程序,我只想暂停一个箭头。
我曾尝试创建一个随机列表类型的调用方,但这不起作用,因为箭头需要在它们消失之前到达终点。
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()
最后,箭头应该到达屏幕的尽头并随机出现。当它们与灰色箭头碰撞时它们也应该消失。
首先不要为每个箭头创建 class。 class 是具有属性的对象。使用 class 的属性并创建具有不同外观和行为的 class 实例。将参数添加到构造函数的签名中,并使用参数来初始化属性。
为位置和图像文件名添加参数:
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()
to repeatedly create an 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。