3

I want score to based on time passed in the game. To do this I want to have two loops running simultaneously. The game loop, and the score loop, which adds 1 to the score every 1.5 seconds. When I run the program, the score does not appear. Am I using multi-threading properly? Is that the best way to do this? For simplicity I have posted only the relevant code. Thanks!

def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()

def displayScore(text):
    while(True):
        textStyle = pygame.font.Font('freesansbold.ttf', 25)
        # pop up window defining window and textRect to align text properly
        textWindow, textRect = text_objects(text, textStyle)
        textRect.center = ((display_width/2)), ((display_height/2))
        gameDisplay.blit(textWindow, textRect)
        pygame.display.update()
        time.sleep(1.5)
        text = int(text)
        text +=1
        text = str(text)

def gameStart():

    x_change = 0
    y_change = 0
    x = (display_width * 0.39)
    y = (display_height * 0.7)
    car_width = 200
    x_brick = (display_width * random.uniform(.05, .95))
    y_brick = display_height - 925

    # exception for the game crashing and the game loop
    gameExit = False

    while not gameExit:

    # capturing user actions
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

        # key-down events for car movements
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_change = -5
            elif event.key == pygame.K_RIGHT:
                x_change = 5
            elif event.key == pygame.K_UP:
                y_change = -5
            elif event.key == pygame.K_DOWN:
                y_change = 5

        # cancelling out key-up events
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_change = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                y_change = 0


    # crash conditions
    if x > display_width - car_width or x < 0:
        crash()
    if y > display_height - 175 or y < 0 - 10:
        crash()


    # updating car movements
    x += x_change
    y += y_change

    # generating display
    gameDisplay.fill(white)
    car(x, y)
    brick(x_brick, y_brick)

    # moving the brick
    y_brick += brick_speed

    # updates for parameter given or entire surface
    pygame.display.update()

    # frames per second, the more frames per second the faster and smoother things move, taxing on processing speed
    clock.tick(60)


t1 = Thread(target=gameStart())
t2 = Thread(target=displayScore('0'))
t1.start()
t2.start()

Edit: Ended up with this..

import time

score = 0

def timer(oldsec):
    currentsec = time.time()
    if abs(currentsec - oldsec > 3):
        return True
    else:
        False


oldsec = time.time() # what time is it now

while True:
    if timer(oldsec) == True:
        score += 1
        oldsec = time.time()
        print (score)
John Fisher
  • 433
  • 6
  • 13
  • 1
    No, you are not doing this correctly. You should only do things that _actually_ require time to complete in a separate thread (like procedural world generation). Also, like quite a few other GUI/rendering libraries, Pygame in my opinion does not support multiple threads. That is, you cannot render anything to the screen from a thread other than the main event loop thread. – EvilTak Nov 14 '17 at 10:18
  • Okay, thank you for explaining this. Do you have suggestions as to how to run two loops simultaneously? – John Fisher Nov 14 '17 at 10:38
  • 1
    If you want to run a second loop for the purpose of updating the score every 1.5 seconds, don't. You can do this in the update loop by simply checking if 1.5 seconds have passed since the last score update. If they have, update the score otherwise don't. Ideally you would abstract this out to a `Timer` or `TimedEvent` class which calls a method every `x` seconds, and checks if the `x` seconds have elapsed every time the event loop is run. – EvilTak Nov 14 '17 at 10:43
  • Awesome, thank you! – John Fisher Nov 14 '17 at 10:47
  • 1
    Just use one of [these timers](https://stackoverflow.com/q/30720665/6220679) (I mean the `pygame.time.get_ticks`, `set_timer` and my delta time solution) instead of creating a new thread. – skrx Nov 14 '17 at 13:33

1 Answers1

0

You could use _thread.

from _thread import *

count = 0

def Your_other_loop():
    global count
    while True:
        #Do loop stuff



def loop():
    global count
    while True:
        print(count)

start_new_thread(Your_other_loop,())
loop()