def end_anim(screen, win):
    """
    This function handles the final animation of a game.
    - screen: pygame.display to draw to.
    - win: Whether or not the user won. Play a sound and
           display an image accordingly.
    """
    global X
    global Y
    global background

    if win:
        img = pygame.image.load("template-minigame_files" + utils.sep + "win.png").convert_alpha()
    else:
        img = pygame.image.load("template-minigame_files" + utils.sep + "lose.png").convert_alpha()

    screen.fill((0, 0, 0))
    screen.blit(background, (0, 0))
    img_rect = img.get_rect()
    img_rect.center = (utils.width / 2, utils.height/2)
    screen.blit(img, img_rect)

    # Sound
    if win:
        pygame.mixer.Sound.play(utils.win_sound).set_volume(utils.volume)
    else:
        pygame.mixer.Sound.play(utils.lose_sound).set_volume(utils.volume)

    # Info
    utils.draw_points(screen)
    utils.draw_time(screen, utils.time_remaining)

    pygame.display.flip()
    pygame.time.wait(3000)
def end_anim(screen, points, decrease_lives):
    """
    This function handles the final animation of a game.
    - screen: pygame.display to draw to.
    - points: points scored
    """
    global X
    global Y
    global background

    if points == 5:
        img = pygame.image.load("overcoock_files" + utils.sep +
                                "win.png").convert_alpha()
    elif points == 2:
        img = pygame.image.load("overcoock_files" + utils.sep +
                                "ok.png").convert_alpha()
    else:
        decrease_lives()
        img = pygame.image.load("overcoock_files" + utils.sep +
                                "lose.png").convert_alpha()

    screen.fill((0, 0, 0))
    screen.blit(background, (0, 0))
    img_rect = img.get_rect()
    img_rect.center = (utils.width / 2, utils.height / 2)
    screen.blit(img, img_rect)

    # Increment points
    utils.points += points

    # Sound
    if points > 0:
        pygame.mixer.Sound.play(utils.win_sound).set_volume(utils.volume)
    else:
        pygame.mixer.Sound.play(utils.lose_sound).set_volume(utils.volume)

    # Info
    utils.draw_points(screen)
    utils.draw_time(screen, utils.time_remaining)

    pygame.display.flip()
    pygame.time.wait(3000)
def templateminigame_game(screen, get_data, decrease_lives):
    """
    This function handles the 'template-minigame' minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise points variable
    points_counter = utils.points

    # Load main sprite:
    # Use this method only if the sprite is a single image.
    # If you want to animate it, jump to line #68
    # to see how to import an animated sprite.
    main_sprite = pygame.image.load("template-minigame_files" + utils.sep + "main.png").convert_alpha()

    # Main sprite's coordinates
    X = 600
    Y = utils.height - 20 - 320 # 320 is the sprite's height, just an example

    # Init animated sprite
    animated_sprite = template-minigame_files.sprite1.Sprite1()
    animated_sprite_g = pygame.sprite.Group()
    animated_sprite_g.add(animated_sprite)

    # Load backgound image
    background = pygame.image.load("template-minigame_files" + utils.sep + "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("template-minigame_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    utils.text_colour = (255, 255, 255) # Set the text colour for the minigame
    while True:
        # Game logic
        if time.time() - seconds_counter > 1:
            # Timer
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0: # Enough time remaining condition
            utils.run_in_thread(get_data)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            # Microbit input here. Manipulate the data
            # as per minigame's needs. The data comes in
            # an array stored in the utils.data variable.
            # Example of data manipulation (from dinorun minigame):
            jump = (utils.data[0] == 1)

            animated_sprite.animate()

            screen.blit(background, (0, 0))
            animated_sprite_g.draw(screen)
            animated_sprite_g.update()

            # Info
            utils.draw_text(screen, "Insert info here", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60) # Pick the clock that best suits your game
        else:
            pygame.mixer.music.stop()
            if utils.points - points_counter < 6:
                # If true, the user lost. Feel free to change the points needed to win
                decrease_lives()
                end_anim(screen, False)
            else:
                end_anim(screen, True)

            utils.minigame_end(screen, get_data)
            break
    return
def match_game(screen, get_data, decrease_lives):
    """
    This function handles the match minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise here the points variables
    points = 0

    # Load drinks sprite:
    red_sprite = pygame.image.load("match_files" + utils.sep +
                                   "red.png").convert_alpha()
    green_sprite = pygame.image.load("match_files" + utils.sep +
                                     "green.png").convert_alpha()
    blue_sprite = pygame.image.load("match_files" + utils.sep +
                                    "blue.png").convert_alpha()

    # Drink sprites' coordinates
    X = utils.width
    Y = utils.height / 2

    # Load backgound image
    background = pygame.image.load("match_files" + utils.sep +
                                   "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("match_files" + utils.sep + "music.ogg")

    seconds_counter = time.time()
    generated = False
    potions_list = [red_sprite, green_sprite, blue_sprite]
    shuffle(potions_list)  # Shuffle list
    buttons_list_tmp = [1, 2, 3, 4]
    shuffle(buttons_list_tmp)  # Shuffle list
    buttons_list = []
    for i in range(0, 3):
        buttons_list.append(
            buttons_list_tmp[i])  # make buttons and potions list same length

    index = 0
    button_press = 0
    colour = (255, 250, 0)
    utils.text_colour = colour
    utils.text_colour = (255, 255, 255)  # Set the text colour for the minigame

    directions(screen, potions_list, buttons_list, get_data)

    utils.text_colour = colour
    pygame.mixer.music.play(-1)  # Game can last more than 27 seconds
    while True:
        # Game logic
        if points == 12:  # winning condition
            pygame.mixer.music.stop()
            end_anim(screen, True)
            utils.time_remaining = 0  # Make sure the game stops

        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            utils.check_data_integrity(screen)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            if index == 3:
                index = 0
                generated = False

            if generated == False:
                potions_list, buttons_list = shuffle_lists(
                    potions_list, buttons_list)
                generated = True

            # Make sure button presses are not duplicated
            if utils.data[0] != button_press:
                button_press = utils.data[0]
            else:
                button_press = 0

            if button_press == buttons_list[index]:
                blit_all(screen, potions_list, index)

                index += 1
                points += 1
                utils.points += 1
                counter = 0
                utils.text_colour = (9, 140, 0)
                utils.draw_text(screen, "Right!", X / 2, Y / 2)
                pygame.display.flip()
                pygame.time.wait(1200)
                utils.text_colour = colour
                utils.time_remaining += 3
                utils.data[0] = 0
            elif button_press != 0:
                blit_all(screen, potions_list, index)

                utils.text_colour = (0, 4, 198)
                utils.draw_text(screen, "Wrong!", X / 2, Y / 2)
                pygame.display.flip()
                pygame.time.wait(1200)
                utils.text_colour = colour
                utils.time_remaining -= 7
                utils.data[0] = 0

            blit_all(screen, potions_list, index)

            # Info
            #utils.draw_text(screen, "Directions", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            if points < 12:  # If true, the user lost
                decrease_lives()
                end_anim(screen, False)

            utils.minigame_end(screen, get_data)
            break
    return
def coin_game(screen, get_data, decrease_lives):
    """
    This function handles the 'coin' minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise here the points variables
    points_counter = utils.points
    other_useful_var = 0

    # Load bucket sprite
    bucket_sprite = pygame.image.load("coin_files" + utils.sep + "bucket.png").convert_alpha()

    # Main sprite's coordinates
    X = utils.width / 2
    Y = utils.height - (320 / 2) - 20 # 320 is the sprite's height


    # Init coin sprite
    coin_sprite = coin_files.coin.Coin()
    coin_sprite_g = pygame.sprite.Group()
    coin_sprite_g.add(coin_sprite)

    # Load backgound image
    background = pygame.image.load("coin_files" + utils.sep + "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("coin_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    utils.text_colour = (200, 89, 78) # Set the text colour for the minigame
    while True:
        # Game logic
        if utils.points - points_counter == 5: # winning condition
            pygame.mixer.music.stop()
            end_anim(screen, True)
            utils.time_remaining = 0 # Make sure the game stops

        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            utils.check_data_integrity(screen)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            # Check what button has been pressed
            if utils.data[0] == 2 and X > 0: # Left
                X -= 5
            elif utils.data[0] == 4 and X < utils.width: # Right
                X += 5

            
            bucket_rect = bucket_sprite.get_rect(center=(X, Y))
            # Coin animation
            coin_sprite.animate(bucket_rect)

            screen.blit(background, (0, 0))
            coin_sprite_g.draw(screen)
            screen.blit(bucket_sprite, bucket_rect)
            coin_sprite_g.update()

            # Info
            utils.draw_text(screen, "R and L buttons to move", utils.width / 2, 222)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            if utils.points - points_counter < 5: # If true, the user lost
                end_anim(screen, False)
                decrease_lives()

            utils.minigame_end(screen, get_data)
            break
    return
def overcoock_game(screen, get_data, decrease_lives):
    """
    This function handles the overcoock minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise here the points variables
    points = 0
    stage = 0
    presses = 0

    # Init meat sprite
    meat_sprite = overcoock_files.meat.Meat()
    meat_sprite_g = pygame.sprite.Group()
    meat_sprite_g.add(meat_sprite)

    # Init fire sprite
    fire_sprite = overcoock_files.fire.Fire()
    fire_sprite_g = pygame.sprite.Group()
    fire_sprite_g.add(fire_sprite)

    # Load backgound image
    background = pygame.image.load("overcoock_files" + utils.sep +
                                   "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("overcoock_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(
        1
    )  # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    utils.text_colour = (98, 28, 68)  # Set the text colour for the minigame
    utils.data[
        0] = 0  # Resest the control number as it might get mashed from the mid minigames screen.
    while True:
        # Game logic
        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            utils.check_data_integrity(screen)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            # Register 125 (5 / (1 / 25)) button inputs (Down) to increase cooking state.
            # Register 1 button input (Up) to finish cooking.
            up = (utils.data[0] == 1)
            down = (utils.data[0] == 3)
            if down == True:
                presses += 1 / 25
                if int(presses) == 5:
                    presses = 0
                    if stage < 6:
                        stage += 1
                    meat_sprite.animate(stage)
            elif up == True:
                if stage < 3:
                    points = 0
                elif stage < 5:
                    points = 2
                elif stage < 6:
                    points = 5
                else:
                    points = 0
                utils.time_remaining = 0

            # Animate the fire sprite
            fire_sprite.animate()

            screen.blit(background, (0, 0))
            meat_sprite_g.draw(screen)
            fire_sprite_g.draw(screen)
            meat_sprite_g.update()
            fire_sprite_g.update()

            # Info
            utils.draw_text(screen, "U to finish, D to cook", utils.width / 2,
                            322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            end_anim(screen, points, decrease_lives)
            utils.minigame_end(screen, get_data)
            break
    return
Пример #7
0
def wheelie_game(screen, get_data, decrease_lives):
    """
    This function handles the 'wheelie' minigame.
    - screen: pygame screen.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global angle
    global angle_opponent
    global background

    # Initialise points variable
    points_counter = utils.points

    # Init bike sprite
    X = 350
    Y = (utils.height - 15) - (372 / 2) # 372 is the sprite's height, 20 is the floor's height
    bike = wheelie_files.bike.Bike(X, Y, False)
    bike_sprites = pygame.sprite.Group()
    bike_sprites.add(bike)
    angle = 0

    # Init opponent bike sprite
    X = 950
    opponent = wheelie_files.bike.Bike(X, Y, True)
    opponent_sprites = pygame.sprite.Group()
    opponent_sprites.add(opponent)

    # Init backgound images
    background = pygame.image.load("wheelie_files" + utils.sep + "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("wheelie_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    mathcing_time_remaining = 3
    utils.text_colour = (255, 0, 0)
    while True:
        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            mathcing_time_remaining -= 1

            # Check if the user has matched the opponent
            if mathcing_time_remaining == 0:
                mathcing_time_remaining = 3

                if abs(angle - angle_opponent) <= 15:
                    utils.points += 1

                angle_opponent = randint(0, 70)

            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            utils.check_data_integrity(screen)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            
            screen.fill((0, 0, 0))
            # Backgound
            scroll_background(background, screen)

            # Check what button has been pressed
            if utils.data[0] == 3 and angle > 0: # Down
                angle -= 0.5
            elif utils.data[0] == 1 and angle < 70: # Up
                angle += 0.5

            bike_sprites.draw(screen)
            opponent_sprites.draw(screen)
            bike.wheel_angle(angle)
            opponent.wheel_angle(angle_opponent)

            bike_sprites.update()
            opponent_sprites.update()

            # Info
            utils.draw_text(screen, "U/D to wheelie", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.draw_number_counter(screen, mathcing_time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            if utils.points - points_counter < 3:
                # If true, the user lost.
                decrease_lives()
                end_anim(screen, False)
            else:
                end_anim(screen, True)
            
            utils.minigame_end(screen, get_data)

            while True:
                get_data()
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        sys.exit()
                if type(utils.data[0]) == float and utils.data[0] != 0:
                    break
            break
    return
Пример #8
0
def dinorun_game(screen, get_data, decrease_lives):
    """
    This function handles the dinorun minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise points variable
    points_counter = utils.points

    # Init dinosaur sprite
    dinosaur_sprite = dinorun_files.dino.Dino()
    dinosaur_sprite_g = pygame.sprite.Group()
    dinosaur_sprite_g.add(dinosaur_sprite)
    # Init wizard sprite
    wizard_sprite = dinorun_files.wizard.Wizard()
    wizard_sprite_g = pygame.sprite.Group()
    wizard_sprite_g.add(wizard_sprite)

    # Load backgound image
    background = pygame.image.load("dinorun_files" + utils.sep + "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("dinorun_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    utils.text_colour = (0, 0, 224) # Set the text colour for the minigame
    while True:
        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            jump = (utils.data[0] == 1)
            dinosaur_sprite.animate(jump)
            wizard_sprite.animate(dinosaur_sprite.rect)

            screen.blit(background, (0, 0))
            dinosaur_sprite_g.draw(screen)
            wizard_sprite_g.draw(screen)
            dinosaur_sprite_g.update()
            wizard_sprite_g.update()

            # Info
            utils.draw_text(screen, "U to jump", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            if utils.points - points_counter < 6: # If true, the user lost
                decrease_lives()
                end_anim(screen, False)
            else:
                end_anim(screen, True)

            utils.minigame_end(screen, get_data)
            break
    return
Пример #9
0
from numpy.lib.type_check import imag
from utils import draw_time
from constants import colors, CANVAS_SIZE, radius
import utils

image = np.zeros(CANVAS_SIZE, dtype=np.uint8)
image[:] = [255,255,255]

init, final = utils.clock_dots_and_ticks()



for i in range(len(init)):
    if i % 5 == 0:
        cv2.line(image, init[i], final[i], colors['black'], 3)
    else:
        cv2.circle(image, init[i], 5, colors['gray'], -1)

cv2.circle(image, (320, 320), radius+10, colors['dark_red'], 2)

cv2.putText(image, "Cv2Clock", (190,230), cv2.FONT_HERSHEY_DUPLEX, 2, colors['dark_gray'], 1, cv2.LINE_AA)

while True:
    image_orig = image.copy()
    clock = draw_time(image_orig)
    cv2.imshow("analog clock", image_orig)

    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()
def whichpath_game(screen, get_data, decrease_lives):
    """
    This function handles the 'template-minigame' minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global X
    global Y
    global background

    # Initialise points variable
    points_counter = utils.points

    # Load main sprite:
    # Use this method only if the sprite is a single image.
    # If you want to animate it, jump to line #68
    # to see how to import an animated sprite.
    character_sprite = pygame.image.load("whichpath_files" + utils.sep +
                                         "character_F.png").convert_alpha()

    # Main sprite's coordinates
    X = (utils.width / 2) - (32 / 2)  # 32 is the sprite's width
    Y = utils.height - 50 - 32  # 32 is the sprite's height, just an example

    # Init animated sprite
    character = whichpath_files.character.character()
    character_sprites = pygame.sprite.Group()
    character_sprites.add(character)

    # Load backgound image
    background = pygame.image.load("whichpath_files" + utils.sep +
                                   "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("whichpath_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(
        1
    )  # Do not loop the song, play it once. -1 to play in a loop if you ever need it.
    seconds_counter = time.time()
    utils.text_colour = (255, 255, 255)  # Set the text colour for the minigame
    while True:
        # Game logic
        if utils.points - points_counter == 2:  # Winning condition
            pygame.mixer.music.stop()
            end_anim(screen, True)
            utils.time_remaining = 0  # Make sure the game stops

        if time.time() - seconds_counter > 1:
            # Timer
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:  # Enough time remaining condition
            utils.run_in_thread(get_data)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            # Microbit input here. Manipulate the data
            # as per minigame's needs. The data comes in
            # an array stored in the utils.data variable.
            # Example of data manipulation (from dinorun minigame):

            if utils.data[0] == 2 and X > 0:  # Left
                X -= 5

            elif utils.data[0] == 4 and X < utils.width:  # Right
                X += 5

            character_rect = character_sprite.get_rect(center=(X, Y))

            finnished = 0

            if (X < 400 and finnished == 0):
                utils.points += 1
                pygame.mixer.music.stop()
                end_anim(screen, True)
                utils.time_remaining = 0  # Make sure the game stops
                finnished += 1

            elif (X > 1200 and finnished == 0):
                pygame.mixer.music.stop()
                utils.time_remaining = 0  # Make sure the game stops
                finnished += 1

            character.animate(character_rect)

            screen.blit(background, (0, 0))
            #character_sprites.draw(screen)
            screen.blit(character_sprite, character_rect)
            #character_sprites.update()

            # Info
            utils.draw_text(screen, "L or R", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)  # Pick the clock that best suits your game
        else:
            pygame.mixer.music.stop()
            if utils.points - points_counter < 1:
                # If true, the user lost. Feel free to change the points needed to win
                decrease_lives()
                end_anim(screen, False)

            utils.minigame_end(screen, get_data)
            break
    return
def engine_game(screen, get_data, decrease_lives):
    """
    This function handles the 'wheelie' minigame.
    - screen: pygame.display to draw to.
    - get_data: get_data function to retrieve data
                from the microbit.
    """
    global angle
    global angle_opponent
    global X
    global Y
    global car
    global background

    blow_points = 0
    old_blow_points = 0
    stage = 0

    # Load car sprite
    car = pygame.image.load("engine_files" + utils.sep +
                            "car.png").convert_alpha()

    # Car sprite's coordinates
    X = 600
    Y = utils.height - 20 - 320  # 320 is the sprite's height

    # Init engine temperature sprite
    temp_indicator = engine_files.engine_temp.EngineTemp()
    indicator_sprites = pygame.sprite.Group()
    indicator_sprites.add(temp_indicator)

    # Init smoke sprite
    smoke = engine_files.smoke.Smoke()
    smoke_sprites = pygame.sprite.Group()
    smoke_sprites.add(smoke)

    # Load backgound image
    background = pygame.image.load("engine_files" + utils.sep +
                                   "background.png").convert_alpha()

    # Game
    pygame.mixer.music.load("engine_files" + utils.sep + "music.ogg")
    pygame.mixer.music.play(1)  # Do not loop the song, play it once
    seconds_counter = time.time()
    utils.text_colour = (190, 150, 200)
    while True:
        old_blow_points = blow_points

        if stage == 5:
            pygame.mixer.music.stop()
            end_anim(screen, True)
            utils.time_remaining = 0  # Make sure the game stops

        if time.time() - seconds_counter > 1:
            utils.time_remaining -= 1
            seconds_counter = time.time()

        if utils.time_remaining > 0:
            utils.run_in_thread(get_data)
            utils.check_data_integrity(screen)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
            screen.fill((0, 0, 0))

            # Map the data coming from the microbit to a
            # scale of 0 to 100.
            # If the engine is not spinning, the pin is floating
            # due to the diode protection. Might need adjustement.
            blow = utils.map(utils.data[3], 80, 560, 0, 100)
            if blow > 70:
                blow_points += 0.02

            if int(blow_points) > int(old_blow_points):
                stage += 1
                utils.points += 1
                temp_indicator.change_temp(stage)

            smoke.animate()

            screen.blit(background, (0, 0))
            indicator_sprites.draw(screen)
            screen.blit(car, (X, Y))
            smoke_sprites.draw(screen)
            smoke_sprites.update()
            indicator_sprites.update()

            # Info
            utils.draw_text(screen, "Blow on the fan!", utils.width / 2, 322)
            utils.draw_points(screen)
            utils.draw_time(screen, utils.time_remaining)
            utils.run_in_thread(utils.draw_volume(screen))

            pygame.display.flip()
            utils.clock.tick(60)
        else:
            pygame.mixer.music.stop()
            if stage < 5:
                decrease_lives()
                end_anim(screen, False)

            utils.minigame_end(screen, get_data)
            break
    return