Python:调用有延迟的函数,而不减慢主循环

标签 python multithreading function pygame

我正在尝试使用 pygame 模块在 python 中创建一个简单的游戏。我在这个游戏的代码中有一个主循环,负责绘制形状、使用 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()

我有一个负责玩家饥饿的函数。此函数将使用模块时间每 3 秒将变量减少 -10。该函数在主循环内调用,由于主循环没有任何延迟,因此该函数将不断被调用。

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 秒,因为必须完成该函数才能再次重复主循环。

为了解决这个问题,我使用了线程模块,它允许我调用函数饥饿系统,而不必等待函数完成。

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

但是,现在我遇到了一个问题,该函数似乎运行正确一次,然后饥饿系统函数中的 time.sleep 以及检查 plyrHunger 是否大于 0 的 if 语句似乎被忽略。结果是变量 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,因为它似乎会引起问题?谢谢。

最佳答案

如果代码只跟踪时间可能是最好的。记录扣除“饥饿”点的时间,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

关于Python:调用有延迟的函数,而不减慢主循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53822715/

相关文章:

c - C程序不会终止

c# - 当调用方法已经拥有同一对象上的锁时,尝试获取该对象上的锁

c++ - 具有函数模板的递归函数

python - 在 Python 3 中发送多个 HTTP 请求的最佳方式是什么?

javascript - 访问首次创建后已更改的外部变量

c - (嵌入式)C : void function() or #define for low level register handling

Python 解析时出现意外的 EOF

python - 在没有字符串格式的情况下在 iPython 中设置千位分隔符

Python 和从图中删除注释

python - 针对线程中的错误启动调试器