@bread_making_machine

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

#Я пишу простенькую игру на pygame и хочу добавить игроку возможность стрелять, для этого я создал отдельный класс Gun, а в нём функцию shoot() которая по нажатии клавиши на клаве будет создавать цикл for который изменяет координаты пули и отображает её, но я столкнулся с проблемой: при исполнении этой функции пуля создаётся и изменяет свои координаты почти мгновенно, чтобы решить эту проблему можно добавить что-то вроде time.sleep в конец цикла, чтобы добавить плавности перемещению пули, но в таком случае остановится вся программа. Кто-нибудь знает замену time.sleep, которая не будет стопить всю прогу (желательно используя pygame)?

Вот сам код:

#импорт нужных модулей и библиотек
import pygame
from pygame.locals import *
from random import * #в будующем планирую использовать рандом

pygame.init()

#создание окна и его настройка
close = False
window = pygame.display.set_mode((1280, 720))
window.fill((255, 255, 255))

player_x, player_y = 640, 360
bullet_x, bullet_y = 100, 100
frames = pygame.time.get_ticks()

#импорт изображения персонажа
sprite_image = pygame.image.load("survivor.png")

#создание нового объекта спрайта
ssprite = pygame.sprite.Sprite()
#изменение размера спрайта
scaled_sprite_image = pygame.transform.scale(sprite_image, (100, 100))
#создание самого спрайта путём конвертации scaled_sprite_image из png в поддержеваемый на pygame формат файлов с изображениями
ssprite.survivor = scaled_sprite_image.convert()
#создание повёрнутых изображений
flipped_left_survivor = pygame.transform.rotate(ssprite.survivor, 180)
flipped_right_survivor = pygame.transform.rotate(ssprite.survivor, 0)
flipped_down_survivor = pygame.transform.rotate(ssprite.survivor, 270)
flipped_up_survivor = pygame.transform.rotate(ssprite.survivor, 90)

#создание пули
bullet_image = pygame.image.load("bullet.png")
bsprite = pygame.sprite.Sprite()
bsprite.bullet = bullet_image.convert()

#класс отвечающий за упралением гг
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()

    def move(self):
        global player_x, player_y, ssprite
        keys = pygame.key.get_pressed()
        if keys[K_w]:
            player_y -= 0.3
            ssprite.survivor = flipped_up_survivor
        elif keys[K_s]:
            player_y += 0.3
            ssprite.survivor = flipped_down_survivor
        elif keys[K_d]:
            player_x += 0.3
            ssprite.survivor = flipped_right_survivor
        elif keys[K_a]:
            player_x -= 0.3
            ssprite.survivor = flipped_left_survivor

#класс отвечающий за стрельбу
class Gun(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()

    def shoot(self):
        global ssprite, bsprite, bullet_x, bullet_y

        flipped_left_bullet = pygame.transform.rotate(bsprite.bullet, 180)
        flipped_right_bullet = pygame.transform.rotate(bsprite.bullet, 0)
        flipped_down_bullet = pygame.transform.rotate(bsprite.bullet, 270)
        flipped_up_bullet = pygame.transform.rotate(bsprite.bullet, 90)

        keys = pygame.key.get_pressed()
        if keys[K_DOWN]:
            ssprite.survivor = flipped_down_survivor

            bullet_x, bullet_y = player_x + 22, player_y + 100
            
            for i in range(0, 720, 10):
                bullet_y += 10
                window.blit(flipped_down_bullet, (bullet_x, bullet_y))
                pygame.display.update()

            if bullet_y > 720:
                del flipped_down_bullet


        if keys[K_UP]:
            ssprite.survivor = flipped_up_survivor

            bullet_x, bullet_y = player_x + 72, player_y
            
            for i in range(720, 0, -10):
                bullet_y -= 10
                window.blit(flipped_up_bullet, (bullet_x, bullet_y))
                pygame.display.update()
            if bullet_y < 0:
                del flipped_down_bullet


        if keys[K_LEFT]:
            ssprite.survivor = flipped_left_survivor

            bullet_x, bullet_y = player_x + 22, player_y + 22
            
            for i in range(1280, 0, -10):
                bullet_x -= 10
                window.blit(flipped_left_bullet, (bullet_x, bullet_y))
                pygame.display.update()
            if bullet_x < 0:
                del flipped_down_bullet


        if keys[K_RIGHT]:
            ssprite.survivor = flipped_right_survivor

            bullet_x, bullet_y = player_x + 90, player_y + 75
            
            for i in range(0, 1280, 10):
                bullet_x += 10
                window.blit(flipped_right_bullet, (bullet_x, bullet_y))
                pygame.display.update()
            if bullet_x > 1280:
                del flipped_down_bullet

            

                    
player = Player()
gun = Gun()                   

#создание игрового цикла
while not close:
    window.fill((255, 255, 255))

    player.move()
    gun.shoot()

    for i in pygame.event.get():
        if i.type == QUIT:
            close = True

        elif i.type == KEYDOWN:
            if i.key == K_ESCAPE:
                close = True

    #отображение спрайта
    window.blit(ssprite.survivor, (player_x, player_y))

            

    #создание регулярного обновления окна
    pygame.display.update()

pygame.quit()
  • Вопрос задан
  • 66 просмотров
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
У тебя должна быть фиксированная частота обновления логики игры.
Тогда ты сможешь любые задержки выражать в числе кадров, которое должно пройти, прежде чем можно выполнить следующее действие. Соответственно у каждого действия есть счётчик кадров, если он не 0 - действие на кулдауне и выполнять его нельзя. Каждый кадр уменьшаешь ненулевые счётчики на 1.

Чуть более тонкий подход - хранить время, оставшееся до истечения кулдауна. На каждом кадре измерять, сколько времени прошло с прошлого кадра, и вычитать этот интервал. Точность всё равно будет порядка одного кадра, но хотя бы при тормозах кулдауны не будут замедляться.

Заодно почитай, что такое автомат состояний. Пригодится.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы