Python: вызов функции с задержкой без замедления основного цикла - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь создать простую игру на python, используя модуль pygame.У меня есть основной цикл в коде для этой игры, который отвечает за рисование фигур, перемещение основной фигуры с помощью WASD, спринт, столкновение с другими изображениями и т. Д.

#Main Loop (DONT ADD DELAYS WITHIN MAIN LOOP)

run = True
while run:
    pygame.time.delay(50)

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

    if keys[pygame.K_a] and x > vel:

        x -= vel

    if keys[pygame.K_d] and x < 500 - width - vel:

        x += vel

    if y >= y6-60:

        y = 50

    if not(isJump):

        if keys[pygame.K_w] and y > vel:

            y -= vel

        if keys[pygame.K_s] and y < 500 - height - vel:

            y += vel

        if keys[pygame.K_TAB]:
            if worldMap == False:
                worldMap = True
                x4 = 120
                y4 = 100
            else:
                worldMap = False
                x4 = 600
                y4 = 600          

        if keys[pygame.K_LSHIFT]:

            if plyrStamina != 0:

                plyrStamina -= 10

                print(plyrStamina)

                width2 -= 10

                vel = 10

            else:
                vel = 5

        else:

            vel = 5

            if plyrStamina != 190:

                plyrStamina += 10

                print(plyrStamina)

                width2 += 10

        if keys[pygame.K_SPACE]:
            isJump = True

    else:     
         if jumpCount >= -10:
             neg = 1
             if jumpCount < 0:
                 neg = -1
             y -= (jumpCount ** 2) * 0.5 * neg 
             jumpCount -= 1

         else:
             isJump = False
             jumpCount = 10

     t1 = Thread(target=hungerSystem) #Calling hunger function 
     t1.start() 


     win.fill((0,0,0))

     #Draw images

     #Character
     pygame.draw.rect(win,(255,0,0), (x, y, width, height))
     #Stamina Bar
     pygame.draw.rect(win,(0,128,0), (x2, y2, width2, height2))
     #Hunger Bar
     pygame.draw.rect(win,(255,165,0), (x3, y3, width3, height3))
     #World Map
     pygame.draw.rect(win,(255,223,0), (x4, y4, width4, height4))
     #health bar
     pygame.draw.rect(win,(255,0,0), (x5, y5, width5, height5))
     #lava
     pygame.draw.rect(win,(255,160,122), (x6, y6, width6, height6))
     #update display
     pygame.display.update()

 pygame.quit()

У меня есть функция, которая отвечаетдля голода игрока.Эта функция будет просто уменьшать переменную на -10 каждые 3 секунды, используя время модуля.Эта функция вызывается в основном цикле, и поскольку основной цикл не имеет задержек, функция будет вызываться постоянно.

plyrHunger = 190
width3 = 190

def hungerSystem():

    global plyrHunger

    global width3

    if plyrHunger > 0:

        time.sleep(3)

        plyrHunger -= 10

        width3 -= 10

        print(plyrHunger)


    else:
        causeDeath = 1
        print("You're dead!") 

Проблема, с которой я столкнулся, была вызвана попыткой вызовафункция, подобная этой:

hungerSystem()

, которая, кажется, замедляет весь основной цикл на 3 секунды, так как функция должна быть завершена для повторения основного цикла.

Для борьбы с этимЯ использовал модуль потоков, который позволяет мне вызывать функцию hungerSystem, не дожидаясь ее завершения.

t1 = Thread(target=hungerSystem) #Calling hunger function 
     t1.start()

Однако теперь у меня возникает проблема, когда функция, кажется, функционирует правильно один раз, изатем впоследствии time.sleep в функции hungerSystem, похоже, игнорируется, так же как и оператор if, проверяющий, больше ли значение plyrHunger, чем 0. Результатом является очень странное и неожиданное непрерывное вычитание переменной plyrHunger без какой-либо задержки вообще.Кроме того, переменная будет затем вычтена в отрицательные значения, даже если для этого будет применен оператор if.

В функции (ниже) области, которые я прокомментировал, казалось, обошли стороной после первого вызова этой функции.

plyrHunger = 190
width3 = 190

def hungerSystem():

    global plyrHunger

    global width3

    if plyrHunger > 0: #BYPASSED WHEN FUNCTION CALLED

        time.sleep(3) #BYPASSED WHEN FUNCTION CALLED

        plyrHunger -= 10

        width3 -= 10

        print(plyrHunger)


else:
    causeDeath = 1
    print("You're dead!")

Кто-нибудь знает лучший способ вызова этой функции, чем использование Thread, поскольку она, кажется, вызывает проблемы?Благодарю.

1 Ответ

0 голосов
/ 18 декабря 2018

Лучше всего, если код просто отслеживает время.Запишите время, в течение которого вычитается точка голода, и не делайте этого снова, пока не истечет 3 секунды.Любое использование time.sleep() заблокирует ваш код.

Я думаю, что использование потока для отслеживания этого не обязательно:

import time

HUNGER_POINT_LASTS=3  #seconds

# About the player    
player_hunger_points = 10
player_hungry_time   = time.time()

while ( True ):
    now = time.time()

    # Is the player hungry now?
    if ( player_hungry_time + HUNGER_POINT_LASTS < now ):
        print( "Player is hungry ..." )
        player_hunger_points -= 1
        player_hungry_time = now

    # Has the player starved?
    if ( player_hunger_points == -1 ):
        print( "... starved to death" )
        break

    # ... rest of code

    pygame.display.update() 

Код также может публиковать событие в обычном событии Pygameочередь:

USEREVENT_HUNGRY  = pygame.USEREVENT + 1
USEREVENT_STARVED = pygame.USEREVENT + 2

...

# Is the player hungry now?
if ( player_hungry_time + HUNGER_POINT_LASTS < now ):
    player_hunger_points -= 1
    player_hungry_time = now   
    if ( player_hunger_points > -1 ):
        new_event = pygame.event.Event(USEREVENT_HUNGRY)
    else:
        new_event = pygame.event.Event(USEREVENT_STARVED)
    pygame.event.post(new_event)


 ...

 if ( event.type == USEREVENT_HUNGRY ):
     # player just lost a hunger point, do something
 elif ( event.type == USEREVENT_STARVED ):
     # player starved, do something
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...