Как можно создать анимацию или выполнить функции в определенный момент времени в pygame, не блокируя работу программы?

Как можно заменить time.sleep в механизме перемещения пули в pygame, чтобы обеспечить плавность её движения без остановки всей программы?
  • 1 января 2024 г. 19:47
Ответы на вопрос 2
One way to create animation or execute functions at a specific point in time in pygame without blocking the program is by using the pygame Clock object and the pygame event system.

Here's an example of how you can achieve smooth movement of a bullet without using time.sleep:

```python
import pygame
import sys

# Initialize pygame
pygame.init()

# Set up the game window
window_width = 800
window_height = 600
window = pygame.display.set_mode((window_width, window_height))

# Define the bullet class
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((20, 20))
        self.image.fill((255, 0, 0))
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)
        self.speed = 5

    def update(self):
        self.rect.x += self.speed

# Create a group to hold the bullets
bullet_group = pygame.sprite.Group()

# Set up the clock object
clock = pygame.time.Clock()

# Set up a variable to track elapsed time
elapsed_time = 0

# Game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # Create a bullet and add it to the bullet group
    bullet = Bullet(0, window_height//2)
    bullet_group.add(bullet)

    # Update the position of all bullets in the bullet group
    bullet_group.update()

    # Clear the screen
    window.fill((0, 0, 0))

    # Draw all bullets on the screen
    bullet_group.draw(window)

    # Update the display
    pygame.display.flip()

    # Limit the frame rate
    clock.tick(60)

    # Update the elapsed time
    elapsed_time += clock.get_time()

    # Check if a certain amount of time has passed
    if elapsed_time >= 1000:
        # Execute a function or perform an action
        print("1 second has passed")
        elapsed_time = 0
```

In this example, the bullet is created and added to a sprite group. The bullet's position is updated in the `update` method of the Bullet class. The screen is cleared and the bullets are drawn on the screen inside the game loop. The clock object is used to limit the frame rate and keep track of elapsed time. The `pygame.time.Clock.tick` method controls the speed of the game loop. The elapsed time is updated using `clock.get_time()` and is used to check if a certain amount of time has passed. Once the desired time has passed, you can execute a function or perform an action. In this example, "1 second has passed" is printed to the console.
У тебя должна быть фиксированная частота обновления логики игры. 
Тогда ты сможешь любые задержки выражать в числе кадров, которое должно пройти, прежде чем можно выполнить следующее действие. Соответственно у каждого действия есть счётчик кадров, если он не 0 - действие на кулдауне и выполнять его нельзя. Каждый кадр уменьшаешь ненулевые счётчики на 1.

Заодно почитай, что такое автомат состояний. Пригодится.
Похожие вопросы