如何在 pygame 中创建冷却功能?
How to create a cooldown function in pygame?
我正在制作一个游戏,我希望角色只能每 0.4 秒左右射击一次。目前,该角色可以发射子弹,看起来像一条长长的子弹从角色中射出。我怎样才能让角色等到下一颗子弹出来。
我认为这适用于 pygame.time.get_clicks()
,但我真的不知道如何。
我试过这样做但是没有子弹出来。我怎样才能让它发挥作用?
def fire():
last = pygame.time.get_ticks()
cooldown = 300
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE]:
now = pygame.time.get_ticks()
if now - last >= cooldown:
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
如果有人需要的话,这里是完整的代码(我把它变成了一个矩形而不是图片精灵,所以任何人都可以尝试。
pygame.init()
win = pygame.display.set_mode((500, 500))
class player():
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 4
self.left = False
self.right = False
def draw(self, win):
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
if self.left:
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
elif self.right:
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
class projectile():
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.vel = 7
def draw(self, win):
pygame.draw.rect(win, self.color, (self.x, self.y, self.height, self. width))
def move():
if keys[pygame.K_LEFT] and man.x > man.vel:
man.x -= man.vel
man.left = True
man.right = False
elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
man.x += man.vel
man.left = False
man.right = True
def fire():
last = pygame.time.get_ticks() # remove this if you want to try it working
cooldown = 400 # remove this if you want to try it working
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE]:
now = pygame.time.get_ticks() # remove this if you want to try it working
if now - last >= cooldown: # remove this if you want to try it working
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
def re_draw():
win.fill((0, 0, 0))
man.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
man = player(400, 400, 64, 64)
bullets = []
run = True
shoot_loop = 0
clock = pygame.time.Clock()
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
fire()
move()
clock.tick(60)
re_draw()
pygame.quit()
我认为这个问题是你每次都设置 last
,即使发射不成功。移动线
last = pygame.time.get_ticks()
里面
if now - last >= cooldown:
应该可以解决这个问题。这样 last
存储上次成功开火的时间,而不是上次尝试的时间。
正如@gregk 所说,错误是您在 fire
函数中设置了 last = pygame.time.get_ticks()
,主循环的每次迭代都会调用该函数。
您是在对程序说最后一次拍摄的时间始终是最后一次迭代的时间,即使没有拍摄。因此 now - last >= cooldown
永远不会为真,因为 last
总是更新到以后的时间。
这个可以有很多方法解决,关键是如何追踪流淌的时间。您不必每次迭代都更新 last
。
以下是一种接近您当前代码的方法(以避免编辑大量内容)。以这种方式编辑您的 fire()
函数:
def fire():
global cooldown_tracker
cooldown_tracker += clock.get_time()
if cooldown_tracker > 400:
cooldown_tracker = 0
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE] and cooldown_tracker == 0:
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
并添加
cooldown_tracker = 0
在主循环之前(就在 while run
之前)。
在此解决方案中,我使用的是您已有的 clock
对象,而不是 pygame.time.get_ticks()
。
我用了一个cooldown_tracker
变量,每次迭代(调用fire()
函数时)最后一次迭代的时间加入到tracker中,如果这个时间大于400ms , tracker 重置为 0。只有当 tracker 为 0 时,才会将一颗子弹添加到列表中(一枪),这意味着冷却时间已经过去。
我正在制作一个游戏,我希望角色只能每 0.4 秒左右射击一次。目前,该角色可以发射子弹,看起来像一条长长的子弹从角色中射出。我怎样才能让角色等到下一颗子弹出来。
我认为这适用于 pygame.time.get_clicks()
,但我真的不知道如何。
我试过这样做但是没有子弹出来。我怎样才能让它发挥作用?
def fire():
last = pygame.time.get_ticks()
cooldown = 300
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE]:
now = pygame.time.get_ticks()
if now - last >= cooldown:
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
如果有人需要的话,这里是完整的代码(我把它变成了一个矩形而不是图片精灵,所以任何人都可以尝试。
pygame.init()
win = pygame.display.set_mode((500, 500))
class player():
def __init__(self, x, y, width, height):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = 4
self.left = False
self.right = False
def draw(self, win):
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
if self.left:
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
elif self.right:
pygame.draw.rect(win, (0, 200, 0), (man.x, man.y, man.height, man.width))
class projectile():
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
self.vel = 7
def draw(self, win):
pygame.draw.rect(win, self.color, (self.x, self.y, self.height, self. width))
def move():
if keys[pygame.K_LEFT] and man.x > man.vel:
man.x -= man.vel
man.left = True
man.right = False
elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
man.x += man.vel
man.left = False
man.right = True
def fire():
last = pygame.time.get_ticks() # remove this if you want to try it working
cooldown = 400 # remove this if you want to try it working
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE]:
now = pygame.time.get_ticks() # remove this if you want to try it working
if now - last >= cooldown: # remove this if you want to try it working
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
def re_draw():
win.fill((0, 0, 0))
man.draw(win)
for bullet in bullets:
bullet.draw(win)
pygame.display.update()
man = player(400, 400, 64, 64)
bullets = []
run = True
shoot_loop = 0
clock = pygame.time.Clock()
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
fire()
move()
clock.tick(60)
re_draw()
pygame.quit()
我认为这个问题是你每次都设置 last
,即使发射不成功。移动线
last = pygame.time.get_ticks()
里面
if now - last >= cooldown:
应该可以解决这个问题。这样 last
存储上次成功开火的时间,而不是上次尝试的时间。
正如@gregk 所说,错误是您在 fire
函数中设置了 last = pygame.time.get_ticks()
,主循环的每次迭代都会调用该函数。
您是在对程序说最后一次拍摄的时间始终是最后一次迭代的时间,即使没有拍摄。因此 now - last >= cooldown
永远不会为真,因为 last
总是更新到以后的时间。
这个可以有很多方法解决,关键是如何追踪流淌的时间。您不必每次迭代都更新 last
。
以下是一种接近您当前代码的方法(以避免编辑大量内容)。以这种方式编辑您的 fire()
函数:
def fire():
global cooldown_tracker
cooldown_tracker += clock.get_time()
if cooldown_tracker > 400:
cooldown_tracker = 0
for bullet in bullets:
if bullet.y < 500 and bullet.y > 0:
bullet.y -= bullet.vel
else:
bullets.pop(bullets.index(bullet))
if keys[pygame.K_SPACE] and cooldown_tracker == 0:
bullets.append(projectile((man.x + man.width // 2), (man.y - 7), 7, 3, (255, 0, 0)))
并添加
cooldown_tracker = 0
在主循环之前(就在 while run
之前)。
在此解决方案中,我使用的是您已有的 clock
对象,而不是 pygame.time.get_ticks()
。
我用了一个cooldown_tracker
变量,每次迭代(调用fire()
函数时)最后一次迭代的时间加入到tracker中,如果这个时间大于400ms , tracker 重置为 0。只有当 tracker 为 0 时,才会将一颗子弹添加到列表中(一枪),这意味着冷却时间已经过去。