Example #1
0
class MathHurdler:
    def __init__(self):
        # Set up a clock for managing the frame rate.
        self.clock = pygame.time.Clock()

        self.x = -100
        self.vx = 10

        self.paused = False
        self.direction = -1

        self.circle_size = 150

        self.horse_change_semaphore = 3
        self.horse_change = 0

        self.font = pygame.font.SysFont('monospace', 36)
        self.lg_font = pygame.font.SysFont('monospace', 60)
        self.xlg_font = pygame.font.SysFont('monospace', 90)

        self.hurdle_number = 0

        self.points = 0

        self.question = Question()

        self.question_text_label = self.lg_font.render(str(self.question), 1,
                                                       Color.BLACK)

        self.question_label = self.font.render(
            'Hurdle #' + str(self.hurdle_number), 1, Color.BLACK)

        self.score_label = self.lg_font.render(str(self.points), 1,
                                               Color.BLACK)

        self.buttons = []

        self.songs = [
            self.get_sound_path('william_tell_overture_intro.wav'),
            self.get_sound_path('william_tell_overture_race.wav')
        ]

        self.death_sfx = pygame.mixer.Sound(
            self.get_sound_path('sad_trombone.wav'))
        self.jump_sfx = pygame.mixer.Sound(self.get_sound_path('success.wav'))

    def set_paused(self, paused):
        self.paused = paused
        if paused:
            pygame.mixer.music.stop()
        else:
            pygame.mixer.music.play(-1)

    def set_gameover(self, gameover):
        self.gameover = gameover
        if gameover:
            pygame.mixer.music.stop()
            self.death_sfx.play()

    def set_playing(self, playing):
        self.playing = playing
        self.set_paused(False)
        self.set_gameover(False)
        if playing:
            pygame.mixer.music.load(self.songs[1])
            pygame.mixer.music.play(-1)
        else:
            pygame.mixer.music.load(self.songs[0])
            pygame.mixer.music.play(-1)

    def get_image_path(self, asset_name):
        return os.path.join('./assets/images', asset_name)

    def get_sound_path(self, sound_name):
        return os.path.join('./assets/sounds', sound_name)

    # The main game loop.
    def run(self):
        self.running = True
        self.playing = False
        self.gameover = False
        self.paused = False
        self.last_answer = -1
        self.last_answer_index = -1
        question_dirty = True

        display_info = pygame.display.Info()
        background_color = Color.SKYBLUE

        screen = pygame.display.get_surface()
        screen_size = screen.get_size()

        ground = pygame.Surface((screen_size[0], screen_size[1] / 3))
        ground = ground.convert()
        ground.fill(Color.BROWN)

        button_panel = pygame.Surface((screen_size[0] / 3, screen_size[1] / 7))

        self.buttons = [
            Button(str(self.question.choices[i]), self.lg_font, Color.BLACK,
                   button_panel.get_width() / 2,
                   button_panel.get_height() / 2, Color.WHITE, Color.BLACK, -2)
            for i in range(4)
        ]

        grass = pygame.draw.line(ground, Color.GREEN, (0, 0),
                                 (ground.get_width(), 0),
                                 ground.get_height() / 2)

        points_label = self.lg_font.render('POINTS', 1, Color.BLACK)

        sun = Sun()
        sun.rect.topleft = (screen_size[0] - sun.image.get_width(), 0)

        horse = Horse()
        horse.rect.x = display_info.current_h / 3
        horse.rect.y = display_info.current_h - horse.image.get_height(
        ) - ground.get_height()

        hurdle = pygame.image.load('./assets/images/hurdle.png')
        hurdle = pygame.transform.scale(
            hurdle, (hurdle.get_height() / 3, hurdle.get_width() / 3))

        hurdle_y = display_info.current_h - hurdle.get_height() - (
            2 * ground.get_height() / 3)

        question_board = pygame.Surface(
            (screen_size[0] / 3, screen_size[1] / 5))
        question_board = question_board.convert()
        question_board.fill(Color.WHITE)

        play_button = Button('Play', self.lg_font, Color.BLACK, 200, 100,
                             Color.WHITE, Color.BLACK, -2)

        menu_label = self.xlg_font.render('MATH HURDLER', 1, Color.BLACK)
        gameover_label = self.xlg_font.render('GAME OVER', 1, Color.BLACK)

        pygame.mixer.music.load(self.songs[0])
        pygame.mixer.music.play(-1)

        def reset():
            question_dirty = True

            self.points = 0
            self.hurdle_number = 0

            self.x = -100
            self.vx = 0

            self.direction = -1

            horse.set_horse(Horse.BASE)

            set_answer(-1)

        def generate_question():
            self.question.next()

            self.buttons[0].set_text(str(self.question.choices[0]))
            self.buttons[1].set_text(str(self.question.choices[1]))
            self.buttons[2].set_text(str(self.question.choices[2]))
            self.buttons[3].set_text(str(self.question.choices[3]))

            self.buttons[0].set_color(self.buttons[0].color, False)
            self.buttons[1].set_color(self.buttons[0].color, False)
            self.buttons[2].set_color(self.buttons[0].color, False)
            self.buttons[3].set_color(self.buttons[0].color, False)

            self.question_text_label = self.lg_font.render(
                str(self.question), 1, Color.BLACK)
            self.hurdle_number += 1
            self.score_label = self.lg_font.render(str(self.points), 1,
                                                   Color.BLACK)
            self.question_label = self.font.render(
                "Hurdle #" + str(self.hurdle_number), 1, Color.BLACK)
            question_board.fill(Color.WHITE)

            self.score_label = self.lg_font.render(str(self.points), 1,
                                                   Color.BLACK)

        def set_answer(answer_index):
            #unselect the previous answer button
            if self.last_answer_index >= 0:
                self.buttons[self.last_answer_index].set_selected(False)

            if answer_index >= 0:
                self.last_answer = Fraction(self.buttons[answer_index].text)
                self.buttons[answer_index].set_selected(True)
                self.last_answer_index = answer_index
            else:
                self.last_answer = -1
                self.last_answer_index = -1

        def evaluate_answer(answer):
            if self.question.is_answer(answer):
                self.points += 100
                self.score_label = self.lg_font.render(str(self.points), 1,
                                                       Color.BLACK)
                self.jump_sfx.play()
            else:
                self.set_gameover(True)
                if self.last_answer_index >= 0:
                    self.buttons[self.last_answer_index].set_color(
                        Color.RED, False)

            self.buttons[self.question.answer_index].set_color(
                Color.GREEN, False)

        while self.running:
            if self.playing:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        return
                    elif event.type == pygame.VIDEORESIZE:
                        pygame.display.set_mode(event.size, pygame.RESIZABLE)
                    elif event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_p:
                            self.paused = not self.paused
                        elif event.key == pygame.K_c:
                            set_answer(self.question.answer_index)
                    elif event.type == pygame.MOUSEBUTTONDOWN:
                        if not self.gameover:
                            for i in range(0, 4):
                                self.buttons[i].mouse_click(
                                    pygame.mouse.get_pos(), set_answer, i)

                screen_size = screen.get_size()

                if not self.paused and not self.gameover:

                    #start at vx=5 and accelerate towards vx=10
                    self.vx = 4 + (self.hurdle_number *
                                   6) / (self.hurdle_number + 5)

                    self.x += self.vx * self.direction
                    if self.direction == 1 and self.x > screen.get_width() + 50:
                        self.x = -50
                    elif self.direction == -1 and self.x < -50:
                        self.x = screen.get_width() + 50

                    hurdle_rect = hurdle.get_rect(topleft=(self.x, hurdle_y))

                    if (horse.active_horse == Horse.JUMP) and (
                            not horse.rect.colliderect(hurdle_rect)):
                        horse.set_horse(Horse.BASE)
                    if (self.horse_change == self.horse_change_semaphore):
                        horse.gallop()
                        self.horse_change = 0

                    self.horse_change += 1

                    horse.rect.x = display_info.current_w / 3
                    horse.rect.y = display_info.current_h - hurdle.get_height(
                    ) - (3 * ground.get_height() / 4)

                    # Check if hurdle and horse in same spot.
                    if horse.rect.colliderect(hurdle_rect):
                        #evaluate answer on first frame of hurdle collision
                        if not question_dirty:
                            evaluate_answer(self.last_answer)
                            question_dirty = True

                        #if not gameover, jump the hurdle
                        if not self.gameover:
                            horse.set_horse(Horse.JUMP)
                            horse.rect.x = display_info.current_w / 3
                            horse.rect.y = display_info.current_h - horse.image.get_height(
                            ) - ground.get_height() - 100

                    #if not colliding with hurdle and question still dirty, generate new question
                    elif question_dirty:
                        generate_question()
                        question_dirty = False
                        set_answer(-1)

                if self.gameover:
                    #spin the horse
                    horse.set_horse(Horse.DEAD)

                # Set the "sky" color to blue
                screen.fill(background_color)

                sun.rect.topleft = (screen_size[0] - sun.image.get_width(), 0)

                screen.blit(question_board,
                            (screen_size[0] / 4, screen_size[1] / 5))
                question_board.blit(self.question_label, (10, 10))
                question_board.blit(
                    self.question_text_label,
                    (10, self.question_label.get_height() + 10))

                screen.blit(ground, (0, screen_size[1] - ground.get_height()))
                button_panel_x = ground.get_width() / 4
                button_panel_y = screen_size[1] - ground.get_height(
                ) + ground.get_height() / 3 + 10
                screen.blit(button_panel, (button_panel_x, button_panel_y))

                self.buttons[0].rect.x = button_panel_x
                self.buttons[0].rect.y = button_panel_y
                self.buttons[0].draw(screen)

                self.buttons[1].rect.x = button_panel_x + self.buttons[
                    0].image.get_width()
                self.buttons[1].rect.y = button_panel_y
                self.buttons[1].draw(screen)

                self.buttons[2].rect.x = button_panel_x
                self.buttons[2].rect.y = button_panel_y + self.buttons[
                    0].image.get_height()
                self.buttons[2].draw(screen)

                self.buttons[3].rect.x = button_panel_x + self.buttons[
                    2].image.get_width()
                self.buttons[3].rect.y = button_panel_y + self.buttons[
                    2].image.get_height()
                self.buttons[3].draw(screen)

                screen.blit(hurdle, (self.x, hurdle_y))

                allsprites = pygame.sprite.RenderPlain(sun, horse)
                allsprites.draw(screen)

                screen.blit(self.score_label,
                            (sun.rect.x + sun.image.get_width() / 4,
                             sun.rect.y + sun.image.get_height() / 3))

                screen.blit(points_label,
                            (sun.rect.x + sun.image.get_width() / 4,
                             sun.rect.y + sun.image.get_height() / 3 +
                             self.score_label.get_height()))

                if self.gameover:
                    screen.blit(gameover_label, (
                        (screen_size[0] - gameover_label.get_width()) / 2,
                        (screen_size[1] - gameover_label.get_height()) / 2,
                    ))

                # Draw the frame
                pygame.display.flip()

                if self.gameover:
                    pygame.time.delay(6000)
                    self.set_playing(False)
                    reset()

                # Try to stay at 30 FPS
                self.clock.tick(30)

            else:

                def start_game():
                    reset()
                    self.set_playing(True)

                #in the menu
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        return
                    elif event.type == pygame.VIDEORESIZE:
                        pygame.display.set_mode(event.size, pygame.RESIZABLE)
                    elif event.type == pygame.MOUSEBUTTONDOWN:
                        play_button.mouse_click(pygame.mouse.get_pos(),
                                                start_game)

                screen_size = screen.get_size()

                if (self.horse_change == self.horse_change_semaphore):
                    horse.gallop()
                    self.horse_change = 0

                self.horse_change += 1

                #draw rainbow background fill
                screen.fill(
                    (math.floor(
                        math.sin(pygame.time.get_ticks() * .001) * 55 + 200),
                     math.floor(
                         math.sin(pygame.time.get_ticks() * .001 + math.pi) *
                         55 + 200),
                     math.floor(
                         math.sin(pygame.time.get_ticks() * .001 +
                                  math.pi * .5) * 55 + 200)))

                #draw menu horse
                horse.rect.x = (screen_size[0] - horse.image.get_width()) / 2
                horse.rect.y = (screen_size[1] -
                                horse.image.get_height()) / 2 + 200

                menu_sprites = pygame.sprite.RenderPlain(horse)
                menu_sprites.draw(screen)

                #draw play button
                play_button.rect.x = (screen_size[0] -
                                      play_button.rect.width) / 2
                play_button.rect.y = (screen_size[1] -
                                      play_button.rect.height) / 2
                play_button.draw(screen)

                #draw menu label
                screen.blit(menu_label, (
                    (screen_size[0] - menu_label.get_width()) / 2,
                    (screen_size[1] - menu_label.get_height()) / 2 - 200,
                ))

                pygame.display.flip()

                # Try to stay at 30 FPS
                self.clock.tick(30)
Example #2
0
class MathHurdler:
    def __init__(self):
        # Set up a clock for managing the frame rate.
        self.clock = pygame.time.Clock()

        self.x = -100
        self.vx = 10

        self.paused = False
        self.direction = -1

        self.circle_size = 150

        self.horse_change_semaphore = 3
        self.horse_change = 0

        self.font = pygame.font.SysFont('monospace', 36)
        self.lg_font = pygame.font.SysFont('monospace', 60)
        self.xlg_font = pygame.font.SysFont('monospace', 90)

        self.hurdle_number = 0

        self.points = 0

        self.question = Question()

        self.question_text_label = self.lg_font.render(
            str(self.question),
            1,
            Color.BLACK
        )

        self.question_label = self.font.render(
            'Hurdle #' + str(self.hurdle_number),
            1,
            Color.BLACK
        )

        self.score_label = self.lg_font.render(
            str(self.points),
            1,
            Color.BLACK
        )

        self.buttons = []

        self.songs = [
            self.get_sound_path('william_tell_overture_intro.wav'),
            self.get_sound_path('william_tell_overture_race.wav')
        ]

        self.death_sfx = pygame.mixer.Sound(self.get_sound_path('sad_trombone.wav'))
        self.jump_sfx = pygame.mixer.Sound(self.get_sound_path('success.wav'))

    def set_paused(self, paused):
        self.paused = paused
        if paused:
            pygame.mixer.music.stop()
        else:
            pygame.mixer.music.play(-1)

    def set_gameover(self, gameover):
        self.gameover = gameover
        if gameover:
            pygame.mixer.music.stop()
            self.death_sfx.play()

    def set_playing(self, playing):
        self.playing = playing
        self.set_paused(False)
        self.set_gameover(False)
        if playing:
            pygame.mixer.music.load(self.songs[1])
            pygame.mixer.music.play(-1)
        else:
            pygame.mixer.music.load(self.songs[0])
            pygame.mixer.music.play(-1)

    def get_image_path(self, asset_name):
        return os.path.join('./assets/images', asset_name)

    def get_sound_path(self, sound_name):
        return os.path.join('./assets/sounds', sound_name)

    # The main game loop.
    def run(self):
        self.running = True
        self.playing = False
        self.gameover = False
        self.paused = False
        self.last_answer = -1
        self.last_answer_index = -1
        question_dirty = True

        display_info = pygame.display.Info()
        background_color = Color.SKYBLUE

        screen = pygame.display.get_surface()
        screen_size = screen.get_size()

        ground = pygame.Surface((screen_size[0], screen_size[1] / 3))
        ground = ground.convert()
        ground.fill(Color.BROWN)

        button_panel = pygame.Surface((screen_size[0]/3, screen_size[1] / 7))

        self.buttons = [
            Button(
                str(self.question.choices[i]),
                self.lg_font,
                Color.BLACK,
                button_panel.get_width() / 2,
                button_panel.get_height() / 2,
                Color.WHITE,
                Color.BLACK,
                -2
            ) for i in range(4)
        ]

        grass = pygame.draw.line(
            ground,
            Color.GREEN,
            (0, 0),
            (ground.get_width(), 0),
            ground.get_height() / 2
        )

        points_label = self.lg_font.render('POINTS', 1, Color.BLACK)

        sun = Sun()
        sun.rect.topleft = (screen_size[0]- sun.image.get_width(),0)

        horse = Horse()
        horse.rect.x = display_info.current_h/3
        horse.rect.y = display_info.current_h - horse.image.get_height() - ground.get_height()

        hurdle = pygame.image.load('./assets/images/hurdle.png')
        hurdle = pygame.transform.scale(hurdle,(hurdle.get_height()/3,hurdle.get_width()/3))

        hurdle_y = display_info.current_h - hurdle.get_height() - (2*ground.get_height()/3)

        question_board = pygame.Surface((screen_size[0]/3, screen_size[1] / 5))
        question_board = question_board.convert()
        question_board.fill(Color.WHITE)

        play_button = Button(
            'Play',
            self.lg_font,
            Color.BLACK,
            200,
            100,
            Color.WHITE,
            Color.BLACK,
            -2
        )

        menu_label = self.xlg_font.render('MATH HURDLER', 1, Color.BLACK)
        gameover_label = self.xlg_font.render('GAME OVER', 1, Color.BLACK)

        pygame.mixer.music.load(self.songs[0])
        pygame.mixer.music.play(-1)

        def reset():
            question_dirty = True

            self.points = 0
            self.hurdle_number = 0
            
            self.x = -100
            self.vx = 0

            self.direction = -1

            horse.set_horse(Horse.BASE)

            set_answer(-1)

        def generate_question():
            self.question.next()

            self.buttons[0].set_text(str(self.question.choices[0]))
            self.buttons[1].set_text(str(self.question.choices[1]))
            self.buttons[2].set_text(str(self.question.choices[2]))
            self.buttons[3].set_text(str(self.question.choices[3]))

            self.buttons[0].set_color(self.buttons[0].color, False)
            self.buttons[1].set_color(self.buttons[0].color, False)
            self.buttons[2].set_color(self.buttons[0].color, False)
            self.buttons[3].set_color(self.buttons[0].color, False)

            self.question_text_label = self.lg_font.render(str(self.question), 1, Color.BLACK)
            self.hurdle_number += 1
            self.score_label = self.lg_font.render(str(self.points),1,Color.BLACK)
            self.question_label = self.font.render("Hurdle #" + str(self.hurdle_number), 1, Color.BLACK)
            question_board.fill(Color.WHITE)

            self.score_label = self.lg_font.render(str(self.points), 1, Color.BLACK)

        def set_answer(answer_index):
            #unselect the previous answer button
            if self.last_answer_index >= 0:
                self.buttons[self.last_answer_index].set_selected(False)
            
            if answer_index >= 0:
                self.last_answer = Fraction(self.buttons[answer_index].text)
                self.buttons[answer_index].set_selected(True)
                self.last_answer_index = answer_index
            else:
                self.last_answer = -1
                self.last_answer_index = -1
            

        def evaluate_answer(answer):
            if self.question.is_answer(answer):
                self.points += 100
                self.score_label = self.lg_font.render(str(self.points), 1, Color.BLACK)
                self.jump_sfx.play()
            else:
                self.set_gameover(True)
                if self.last_answer_index >= 0:
                    self.buttons[self.last_answer_index].set_color(Color.RED, False)
                
            self.buttons[self.question.answer_index].set_color(Color.GREEN, False)

        while self.running:
            if self.playing:
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        return
                    elif event.type == pygame.VIDEORESIZE:
                        pygame.display.set_mode(event.size, pygame.RESIZABLE)
                    elif event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_p:
                            self.paused = not self.paused
                        elif event.key == pygame.K_c:
                            set_answer(self.question.answer_index)
                    elif event.type == pygame.MOUSEBUTTONDOWN:
                        if not self.gameover:
                            for i in range(0, 4):
                                self.buttons[i].mouse_click(
                                    pygame.mouse.get_pos(),
                                    set_answer,
                                    i
                                )

                screen_size = screen.get_size()

                if not self.paused and not self.gameover:

                    #start at vx=5 and accelerate towards vx=10
                    self.vx = 4 + (self.hurdle_number * 6) / (self.hurdle_number + 5)
                    
                    self.x += self.vx * self.direction
                    if self.direction == 1 and self.x > screen.get_width() + 50:
                        self.x = -50
                    elif self.direction == -1 and self.x < -50:
                        self.x = screen.get_width() + 50

                    hurdle_rect = hurdle.get_rect(topleft=(self.x,hurdle_y))

                    if (horse.active_horse == Horse.JUMP) and (not horse.rect.colliderect(hurdle_rect)):
                        horse.set_horse(Horse.BASE)
                    if (self.horse_change == self.horse_change_semaphore):
                        horse.gallop()
                        self.horse_change = 0

                    self.horse_change += 1

                    horse.rect.x = display_info.current_w / 3
                    horse.rect.y = display_info.current_h - hurdle.get_height() - (3*ground.get_height()/4)

                    # Check if hurdle and horse in same spot.
                    if horse.rect.colliderect(hurdle_rect):
                        #evaluate answer on first frame of hurdle collision
                        if not question_dirty:
                            evaluate_answer(self.last_answer)
                            question_dirty = True

                        #if not gameover, jump the hurdle
                        if not self.gameover:
                            horse.set_horse(Horse.JUMP)
                            horse.rect.x = display_info.current_w / 3
                            horse.rect.y = display_info.current_h - horse.image.get_height() - ground.get_height() - 100

                    #if not colliding with hurdle and question still dirty, generate new question
                    elif question_dirty:
                        generate_question()
                        question_dirty = False
                        set_answer(-1)

                if self.gameover:
                    #spin the horse
                    horse.set_horse(Horse.DEAD)

                # Set the "sky" color to blue
                screen.fill(background_color)
                
                sun.rect.topleft = (screen_size[0]- sun.image.get_width(),0)

                screen.blit(question_board, (screen_size[0] / 4, screen_size[1] / 5))
                question_board.blit(self.question_label, (10,10))
                question_board.blit(self.question_text_label, (10,self.question_label.get_height()+10))

                screen.blit(ground, (0, screen_size[1] - ground.get_height()))
                button_panel_x = ground.get_width()/4
                button_panel_y = screen_size[1] - ground.get_height() + ground.get_height() / 3 + 10
                screen.blit(button_panel, (button_panel_x, button_panel_y))

                self.buttons[0].rect.x = button_panel_x
                self.buttons[0].rect.y = button_panel_y
                self.buttons[0].draw(screen)

                self.buttons[1].rect.x = button_panel_x + self.buttons[0].image.get_width()
                self.buttons[1].rect.y = button_panel_y
                self.buttons[1].draw(screen)

                self.buttons[2].rect.x = button_panel_x
                self.buttons[2].rect.y = button_panel_y + self.buttons[0].image.get_height()
                self.buttons[2].draw(screen)

                self.buttons[3].rect.x = button_panel_x + self.buttons[2].image.get_width()
                self.buttons[3].rect.y = button_panel_y + self.buttons[2].image.get_height()
                self.buttons[3].draw(screen)

                screen.blit(hurdle,(self.x,hurdle_y))

                allsprites = pygame.sprite.RenderPlain(sun,horse)
                allsprites.draw(screen)

                screen.blit(
                    self.score_label,
                    (
                        sun.rect.x + sun.image.get_width() / 4,
                        sun.rect.y + sun.image.get_height() / 3
                    )
                )

                screen.blit(
                    points_label,
                    (
                        sun.rect.x + sun.image.get_width() / 4,
                        sun.rect.y + sun.image.get_height() / 3 + self.score_label.get_height()
                    )
                )

                if self.gameover:
                    screen.blit(
                        gameover_label,
                        (
                            (screen_size[0] - gameover_label.get_width()) / 2,
                            (screen_size[1] - gameover_label.get_height()) / 2,
                        )
                    )

                # Draw the frame
                pygame.display.flip()

                if self.gameover:
                    pygame.time.delay(6000)
                    self.set_playing(False)
                    reset()

                # Try to stay at 30 FPS
                self.clock.tick(30)
                
            else:
                def start_game():
                    reset()
                    self.set_playing(True)

                #in the menu
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        pygame.quit()
                        return
                    elif event.type == pygame.VIDEORESIZE:
                        pygame.display.set_mode(event.size, pygame.RESIZABLE)
                    elif event.type == pygame.MOUSEBUTTONDOWN:
                        play_button.mouse_click(
                            pygame.mouse.get_pos(),
                            start_game
                        )

                screen_size = screen.get_size()

                if (self.horse_change == self.horse_change_semaphore):
                    horse.gallop()
                    self.horse_change = 0

                self.horse_change += 1

                #draw rainbow background fill
                screen.fill(
                    (
                        math.floor(math.sin(pygame.time.get_ticks()*.001)*55 + 200),
                        math.floor(math.sin(pygame.time.get_ticks()*.001+math.pi)*55 + 200),
                        math.floor(math.sin(pygame.time.get_ticks()*.001+math.pi*.5)*55 + 200)
                    )
                )

                #draw menu horse
                horse.rect.x = (screen_size[0] - horse.image.get_width()) / 2
                horse.rect.y = (screen_size[1] - horse.image.get_height()) / 2 + 200

                menu_sprites = pygame.sprite.RenderPlain(horse)
                menu_sprites.draw(screen)

                #draw play button
                play_button.rect.x = (screen_size[0] - play_button.rect.width) / 2
                play_button.rect.y = (screen_size[1] - play_button.rect.height) / 2
                play_button.draw(screen)

                #draw menu label
                screen.blit(
                    menu_label,
                    (
                        (screen_size[0] - menu_label.get_width()) / 2,
                        (screen_size[1] - menu_label.get_height()) / 2 - 200,
                    )
                )
                
                
                
                pygame.display.flip()
                
                # Try to stay at 30 FPS
                self.clock.tick(30)