Есть ли способ ограничить количество вызовов функции в PyGame? - PullRequest
1 голос
/ 12 марта 2020

Я программирую шутер для школьного проекта. В игре вы нажимаете, и пуля летит от спрайта игрока к вашему курсору. В настоящее время я запрограммировал целевой рисунок, рисунок спрайта игрока и функцию маркера, однако я хотел бы ограничить, например, сколько раз в секунду игрок может стрелять. Это отчасти для того, чтобы избежать спам-стрельбы, которая портит производительность игры, а также делает ее более сложной, чем просто быстрый щелчок мышью везде. Я бы предположил, что я мог бы использовать команду 'pygame_clock', но я не совсем уверен, как. Ниже приведен код:

import pygame

#Setting window dimensions and caption. (Module 1)

pygame.init()
window = pygame.display.set_mode((800, 575))
pygame.display.set_caption("TARGET PRACTICE")

#Colour variables. (Module 1)

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BLUE = (0, 0, 200)

#py_clock tracks framerate of program for other 'pygame.time' commands. (Module 8)

py_clock = pygame.time.Clock()

#Target class created. (Module 5)

class Target:
  def __init__(self, x, y, h, w, v):
    self.x = x
    self.y = y
    self.h = h
    self.w = w
    self.v = v


#Instantiation of targets. (Module 5)

target_1 = Target(0, 80, 60, 40, 0.5)
target_2 = Target(0, 100, 60, 40, 0.5)
target_3 = Target(0, 50, 60, 40, 0.5)
target_4 = Target(0, 75, 60, 40, 0.5)
target_5 = Target(0, 45, 60, 40, 0.5)
target_6 = Target(0, 85, 60, 40, 0.5)


#Declaring variables to be used in the while loop. (Module 5)

clock = 0

target_2_threshold = 500
target_3_threshold = 1000
target_4_threshold = 1500
target_5_threshold = 2000
target_6_threshold = 2500


#Setting player sprite dimension variables. (Module 6)

player_sprite_x = 357.5
player_sprite_y = 450
player_sprite_h = 125
player_sprite_w = 85

#all_bullets list to store bullets made by function inside loop. (Module7)

all_bullets = []

exec = True

while exec:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      exec = False

    #'IF' statement to trigger the shooting function. (Module 7)

    if event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 1:
            dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
            dy = event.pos[1] - player_sprite_y
            direction = pygame.math.Vector2(dx, dy).normalize()
            bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
            all_bullets.append(bullet)

  #Defines movement of targets and sets delay between drawings. (Module 5)   

  clock += 1
  target_1.x += target_1.v
  if clock > target_2_threshold:
        target_2.x += target_2.v
  if clock > target_3_threshold:
        target_3.x += target_3.v
  if clock > target_4_threshold:
        target_4.x += target_4.v
  if clock > target_5_threshold:
        target_5.x += target_5.v
  if clock > target_6_threshold:
        target_6.x += target_6.v

  #all_bullets_keep list combined with FOR loop retains only bullets in the arena. (Module 7)

  all_bullets_keep = []

  for item in all_bullets:
    item['x'] += item['direction'][0] # item['direction'][0] * 2
    item['y'] += item['direction'][1] # item['direction'][1] * 2

    if 0 < item['x'] < 800 and 0 < item['y'] < 575:
          all_bullets_keep.append(item)

  all_bullets = all_bullets_keep

  #Fill the background (Module 5)

  window.fill(RED)

  #Redraw each target in every frame. (Module 5)

  pygame.draw.rect(window, BLUE, (target_1.x, target_1.y, target_1.h, target_1.w))
  if clock > target_2_threshold:
      pygame.draw.rect(window, BLUE, (target_2.x, target_2.y, target_2.h, target_2.w)) 
  if clock > target_3_threshold:
      pygame.draw.rect(window, BLUE, (target_3.x, target_3.y, target_3.h, target_3.w))
  if clock > target_4_threshold:
      pygame.draw.rect(window, BLUE, (target_4.x, target_4.y, target_4.h, target_4.w))
  if clock > target_5_threshold:
      pygame.draw.rect(window, BLUE, (target_5.x, target_5.y, target_5.h, target_5.w))
  if clock > target_6_threshold:
      pygame.draw.rect(window, BLUE, (target_6.x, target_6.y, target_6.h, target_6.w))

  #Draw the player sprite. (Module 6)

  pygame.draw.rect(window, BLUE, (player_sprite_x, player_sprite_y, player_sprite_w, player_sprite_h))

  #Draw each item in all_bullets. (Module 7)

  for item in all_bullets:
    pygame.draw.rect(window, BLUE, (item['x']-5, item['y']-5, 10, 10))

  pygame.display.update()

  #tick_busy_loop limits number of times the game can refresh per second. (Module 8)

  py_clock.tick_busy_loop(120)

pygame.quit()

1 Ответ

1 голос
/ 12 марта 2020

Возможность ограничить количество пуль. Например:

if event.button == 1 and len(all_bullets) < 5:
    dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
    dy = event.pos[1] - player_sprite_y
    direction = pygame.math.Vector2(dx, dy).normalize()
    bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
    all_bullets.append(bullet)

Другой вариант заключается в обеспечении того, чтобы между двумя щелчками прошло определенное время. Используйте pygame.time.get_ticks(), чтобы получить текущее время в миллисекундах. Когда новая пуля была создана, вычислите время, когда следующая пуля может быть создана. Определите минимальное время появления между двумя пулями и начните момент времени для первой пули с помощью 0:

bullet_delay = 500 # 0.5 seconds
next_bullet_time = 0

Получите текущее время в приложении l oop:

current_time = pygame.time.get_ticks()

При нажатии убедитесь, что текущее время больше next_bullet_time. Если условие выполнено, то появляется пуля и вычисляется момент времени для следующей пули:

if event.button == 1 and current_time > next_bullet_time:
    next_bullet_time = current_time + bullet_delay

например:

bullet_delay = 500 # 0.5 seconds
next_bullet_time = 0

while exec:
    current_time = pygame.time.get_ticks()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exec = False

        if event.type == pygame.MOUSEBUTTONDOWN:

            if event.button == 1 and current_time > next_bullet_time:
                next_bullet_time = current_time + bullet_delay

                dx = event.pos[0] - (player_sprite_x+ player_sprite_w//2)
                dy = event.pos[1] - player_sprite_y
                direction = pygame.math.Vector2(dx, dy).normalize()
                bullet = {'x': player_sprite_x+42, 'y': player_sprite_y, 'direction': direction}
                all_bullets.append(bullet)
...