import os, time, pygame
from pygame.locals import *

from song import Song

""" Setup """

# Change to project root directory
if 'assets' not in os.listdir():
    os.chdir('../')

pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()
FPS = 120

WIDTH, HEIGHT = 1280, 720 

fullscreen = False
if fullscreen:
    WIDTH, HEIGHT = 1920, 1080
    
SCALE = WIDTH / 1920

font_gravtrac_74 = pygame.font.Font('assets/gravtrac.ttf', int(120 * SCALE))
font_gravtrac_48 = pygame.font.Font('assets/gravtrac.ttf', int(72 * SCALE))

hit_sound = pygame.mixer.Sound("assets/hit.wav")
hit_sound.set_volume(0.5)
hit_miss_sound = pygame.mixer.Sound("assets/hit_miss.wav")
hit_miss_sound.set_volume(0.5)

INDICATOR_SIZE = (int(300 * SCALE), int(300 * SCALE))

indicator_bad = pygame.transform.scale(pygame.image.load('assets/hit_bad.png'), INDICATOR_SIZE)
indicator_good = pygame.transform.scale(pygame.image.load('assets/hit_good.png'), INDICATOR_SIZE)
indicator_perfect = pygame.transform.scale(pygame.image.load('assets/hit_perfect.png'), INDICATOR_SIZE)
indicator_miss = pygame.transform.scale(pygame.image.load('assets/hit_miss.png'), INDICATOR_SIZE)

indicator_pos = (WIDTH / 2 - INDICATOR_SIZE[0] / 2, HEIGHT / 2 - INDICATOR_SIZE[1] / 2)

""" Window """

icon = pygame.image.load('assets/icon.png')
pygame.display.set_caption('Lit Keyz - Early Preview Version')
pygame.display.set_icon(icon)
screen = pygame.display.set_mode((WIDTH, HEIGHT))

class HitObject:
    def __init__(self, letter, when, song_time):
        self.SIZE = 50 * SCALE
        self.surface = pygame.Surface((self.SIZE * 2, self.SIZE * 2))
        self.letter = letter
        self.when = when
        pygame.draw.circle(self.surface, (125, 18, max(min((self.when - song_time) / 10, 255), 0)), (self.SIZE, self.SIZE), self.SIZE)
        if letter != ' ':
            self.letter = letter.upper()
            self.text = font_gravtrac_48.render(self.letter, True, (255, 255, 255))
            text_rect = self.text.get_rect()
            text_rect.center = (self.SIZE, self.SIZE)
            self.surface.blit(self.text, text_rect)
        self.surface.set_colorkey((0, 0, 0))
        
    def render(self, song_time):
        pygame.draw.circle(self.surface, (125, 18, max(min((self.when - song_time) / 10, 255), 0)), (self.SIZE, self.SIZE), self.SIZE)
        if self.letter != ' ':
            self.letter = self.letter.upper()
            self.text = font_gravtrac_48.render(self.letter, True, (255, 255, 255))
            text_rect = self.text.get_rect()
            text_rect.center = (self.SIZE, self.SIZE)
            self.surface.blit(self.text, text_rect)
        self.surface.set_colorkey((0, 0, 0))

class Game:
    def __init__(self, song_filename):
        """ Song Setup """

        current_song = Song(f'songs/{song_filename}')
        print(current_song.title)
        song_time = 0

        song_background = pygame.transform.scale(pygame.image.load(f'songs/{current_song.background_image}'), (WIDTH, HEIGHT))
        pygame.mixer.music.load(f'songs/{current_song.song_filename}')
        pygame.mixer.music.set_volume(0.4)

        self.n_notes = current_song.n_notes

        """ Game Loop """

        self.SCORE = 0
        self.COMBO = 1
        self.ACCURACY = 0

        polygon = [(973 * SCALE, 412 * SCALE), (1195 * SCALE, 573 * SCALE), (1110 * SCALE, 834 * SCALE), (836 * SCALE, 834 * SCALE), (752 * SCALE, 573 * SCALE)]
        polygon = [(960 * SCALE, 280 * SCALE), (1234 * SCALE, 480 * SCALE), (1128 * SCALE, 800 * SCALE) ,(790 * SCALE, 800 * SCALE), (684 * SCALE, 480 * SCALE)]

        empty_indicator = pygame.Surface((0, 0))
        indicator = empty_indicator
        indicator_timer = 127
           
        isRunning = True

        hitObjects = [None, None, None, None, None]

        for i in range(5):
            tmp = current_song.note_data[i]
            hitObjects[i] = HitObject(tmp[1], tmp[0], song_time)

        currentHitObjectIdx = 0
        canHit = True
        isSongOver = False
        self.cleared = False

        songOverWait = 5000

        final_note_time = current_song.note_data[self.n_notes-1][0]

        # Start the song
        pygame.mixer.music.play()

        while isRunning:
            # Render Song BG
            screen.blit(song_background, (0, 0))
            
            # Render Score
            score_text = font_gravtrac_74.render(str(self.SCORE), True, (247, 37, 133))
            score_text_rect = score_text.get_rect()
            score_text_rect.center = (WIDTH / 2, 60 * SCALE)
            screen.blit(score_text, score_text_rect)
            
            # Render Combo
            combo_text = font_gravtrac_48.render(str(self.COMBO) + ' x', True, (181, 23, 158))
            combo_text_rect = combo_text.get_rect()
            combo_text_rect.center = (WIDTH / 2, 160 * SCALE)
            screen.blit(combo_text, combo_text_rect)
            
            # Render Polygon
            poly_surf = pygame.Surface((WIDTH, HEIGHT))
            pygame.draw.polygon(poly_surf, (55, 55, 55), polygon)
            poly_surf.set_colorkey((0, 0, 0))
            poly_surf.set_alpha(128)
            screen.blit(poly_surf, (0, 0))
            
            if isSongOver:
                songOverWait -= clock.get_time()
                if songOverWait < 0:
                    isRunning = False
            
            # Render HitCircle
            if canHit:
                hitDelta = hitObjects[currentHitObjectIdx % 5].when - song_time
                size_offset = hitObjects[currentHitObjectIdx % 5].SIZE
                hit_time = min(hitDelta / 15, 100)
                if hit_time != 100:
                    pygame.draw.circle(screen, (1, 1, 1), polygon[currentHitObjectIdx % 5], hit_time + size_offset)
                    pygame.draw.circle(screen, (255, 255, 255), polygon[currentHitObjectIdx % 5], hit_time - 5 + size_offset)
            
            # Render HitObjects
            for idx, object in enumerate(hitObjects):
                coords = list(polygon[idx])
                coords[0] -= object.SIZE
                coords[1] -= object.SIZE
                screen.blit(object.surface, coords)
                object.render(song_time)
            
            # Hit Object Cycle
            if hitObjects[currentHitObjectIdx % 5].when <= song_time and not isSongOver:
                if hitObjects[currentHitObjectIdx % 5].when == -1:
                    # print(f"SONG OVER | Score: {self.SCORE} Combo: {self.COMBO}x | Accuracy: {self.ACCURACY / current_song.n_notes * 100}%")
                    isSongOver = True
                    pygame.mixer.music.fadeout(5000)
                    self.cleared = True
                else:
                    if canHit:
                        # Miss
                        # print("MISS")
                        indicator = indicator_miss
                        indicator_timer = 127
                        hit_miss_sound.play()
                        self.COMBO = 1
                    canHit = True
                    if currentHitObjectIdx + 5 < current_song.n_notes:
                        tmp = current_song.note_data[currentHitObjectIdx + 5]
                        hitObjects[currentHitObjectIdx % 5] = HitObject(tmp[1], tmp[0], song_time)
                        currentHitObjectIdx += 1
                    else:
                        hitObjects[currentHitObjectIdx % 5] = HitObject(' ', -1, song_time)
                        currentHitObjectIdx += 1
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    isRunning = False 
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        isRunning = False
                    
                    # Check Hit
                    elif event.key == ord(hitObjects[currentHitObjectIdx % 5].letter.lower()) and canHit and not isSongOver:
                        # Sucessfull hit
                        hitDelta = abs(hitDelta)
                        hit_sound.play()
                        if hitDelta <= 100:
                            # print("PERFECT")
                            indicator = indicator_perfect
                            indicator_timer = 127
                            self.ACCURACY += 1
                            self.SCORE += self.COMBO * 200
                            self.COMBO += 1
                        elif hitDelta <= 200:
                            # print("GOOD")
                            indicator = indicator_good
                            indicator_timer = 127
                            self.ACCURACY += 0.75
                            self.SCORE += self.COMBO * 100
                            self.COMBO += 1
                        elif hitDelta <= 400:
                            # print("BAD")
                            indicator = indicator_bad
                            indicator_timer = 127
                            self.ACCURACY += 0.5
                            self.SCORE += self.COMBO * 50
                            self.COMBO += 1
                        else:
                            # MISS
                            # print("MISS")
                            indicator = indicator_miss
                            indicator_timer = 127
                            self.COMBO = 1
                        canHit = False
                    elif canHit:
                        # print("WRONG KEY")
                        pass
                        
            
            indicator.set_alpha(indicator_timer * 2)
            screen.blit(indicator, indicator_pos)
            indicator_timer -= 1

            remaining_percent = min(song_time / final_note_time, 1)
            
            pygame.draw.rect(screen, (255, 255, 255), pygame.Rect((WIDTH / 2 - 202 * SCALE, HEIGHT - 52 * SCALE), (int(402 * SCALE), 12 * SCALE)))
            pygame.draw.rect(screen, (0, 0, 0), pygame.Rect((WIDTH / 2 - 200 * SCALE, HEIGHT - 50 * SCALE), (int(remaining_percent * 400 * SCALE), 10 * SCALE)))
            
            pygame.display.update()
            song_time += clock.get_time()
            clock.tick(FPS)
        
        pygame.mixer.music.stop()
 
class MenuSong:
    def __init__(self, title, filename, background_image):
        self.title = title
        self.filename = filename
        self.background_image = background_image
        
def main():
    isGameRunning = True
    
    song_file_list = [x for x in os.listdir('songs/') if x.endswith('.lk')]
    song_list = []
    for song in song_file_list:
        tmp_song = Song(f'songs/{song}')
        song_list.append(MenuSong(tmp_song.title, song, tmp_song.background_image))
    
    n_songs = len(song_list)
    menu_song_selected = 0
    
    while isGameRunning:
        song_image = pygame.transform.scale(pygame.image.load(f'songs/{song_list[menu_song_selected].background_image}'), (WIDTH, HEIGHT))
        screen.blit(song_image, (0, 0))
        
        song_title = font_gravtrac_74.render(song_list[menu_song_selected].title, False, (114, 9, 183))
        song_title_rect = song_title.get_rect()
        song_title_rect.center = (WIDTH/2, 70 * SCALE)
        
        screen.blit(song_title, song_title_rect)
        
        intstructions = font_gravtrac_48.render("Use the arrow keys to select a song. Press Enter to play it!", False, (181, 23, 158))
        intstructions_rect = intstructions.get_rect()
        intstructions_rect.center = (WIDTH/2, HEIGHT - 50 * SCALE)
        
        screen.blit(intstructions, intstructions_rect)
        
        for event in pygame.event.get():
                    if event.type == QUIT:
                        isGameRunning = False 
                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            isGameRunning = False
                        elif event.key == K_RETURN:
                            game = Game(song_list[menu_song_selected].filename)
                            print(f'cleared: {game.cleared} | score: {game.SCORE} | combo: {game.COMBO} x | accuracy: {game.ACCURACY / game.n_notes * 100}%')     
                        elif event.key == K_DOWN:
                            menu_song_selected = (menu_song_selected + 1) % n_songs
                        elif event.key == K_UP:
                            menu_song_selected = (menu_song_selected - 1) % n_songs
                    if event.type == MOUSEBUTTONDOWN:
                        if event.button == 5:
                            menu_song_selected = (menu_song_selected + 1) % n_songs
                        elif event.button == 4:
                            menu_song_selected = (menu_song_selected - 1) % n_songs
                           
        pygame.display.update()
        clock.tick(FPS)
    
    pygame.quit()
    
if __name__ == '__main__':
    main()
import os, time, pygame
from pygame.locals import *

from song import Song

""" Setup """

# Change to project root directory
if 'assets' not in os.listdir():
    os.chdir('../')

pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()
FPS = 120

WIDTH, HEIGHT = 1280, 720 

fullscreen = False
if fullscreen:
    WIDTH, HEIGHT = 1920, 1080
    
SCALE = WIDTH / 1920

font_gravtrac_74 = pygame.font.Font('assets/gravtrac.ttf', int(120 * SCALE))
font_gravtrac_48 = pygame.font.Font('assets/gravtrac.ttf', int(72 * SCALE))

hit_sound = pygame.mixer.Sound("assets/hit.wav")
hit_sound.set_volume(0.5)
hit_miss_sound = pygame.mixer.Sound("assets/hit_miss.wav")
hit_miss_sound.set_volume(0.5)

INDICATOR_SIZE = (int(300 * SCALE), int(300 * SCALE))

indicator_bad = pygame.transform.scale(pygame.image.load('assets/hit_bad.png'), INDICATOR_SIZE)
indicator_good = pygame.transform.scale(pygame.image.load('assets/hit_good.png'), INDICATOR_SIZE)
indicator_perfect = pygame.transform.scale(pygame.image.load('assets/hit_perfect.png'), INDICATOR_SIZE)
indicator_miss = pygame.transform.scale(pygame.image.load('assets/hit_miss.png'), INDICATOR_SIZE)

indicator_pos = (WIDTH / 2 - INDICATOR_SIZE[0] / 2, HEIGHT / 2 - INDICATOR_SIZE[1] / 2)

""" Window """

icon = pygame.image.load('assets/icon.png')
pygame.display.set_caption('Lit Keyz - Early Preview Version')
pygame.display.set_icon(icon)
screen = pygame.display.set_mode((WIDTH, HEIGHT))

class HitObject:
    def __init__(self, letter, when, song_time):
        self.SIZE = 50 * SCALE
        self.surface = pygame.Surface((self.SIZE * 2, self.SIZE * 2))
        self.letter = letter
        self.when = when
        pygame.draw.circle(self.surface, (125, 18, max(min((self.when - song_time) / 10, 255), 0)), (self.SIZE, self.SIZE), self.SIZE)
        if letter != ' ':
            self.letter = letter.upper()
            self.text = font_gravtrac_48.render(self.letter, True, (255, 255, 255))
            text_rect = self.text.get_rect()
            text_rect.center = (self.SIZE, self.SIZE)
            self.surface.blit(self.text, text_rect)
        self.surface.set_colorkey((0, 0, 0))
        
    def render(self, song_time):
        pygame.draw.circle(self.surface, (125, 18, max(min((self.when - song_time) / 10, 255), 0)), (self.SIZE, self.SIZE), self.SIZE)
        if self.letter != ' ':
            self.letter = self.letter.upper()
            self.text = font_gravtrac_48.render(self.letter, True, (255, 255, 255))
            text_rect = self.text.get_rect()
            text_rect.center = (self.SIZE, self.SIZE)
            self.surface.blit(self.text, text_rect)
        self.surface.set_colorkey((0, 0, 0))

class Game:
    def __init__(self, song_filename):
        """ Song Setup """

        current_song = Song(f'songs/{song_filename}')
        print(current_song.title)
        song_time = 0

        song_background = pygame.transform.scale(pygame.image.load(f'songs/{current_song.background_image}'), (WIDTH, HEIGHT))
        pygame.mixer.music.load(f'songs/{current_song.song_filename}')
        pygame.mixer.music.set_volume(0.4)

        self.n_notes = current_song.n_notes

        """ Game Loop """

        self.SCORE = 0
        self.COMBO = 1
        self.ACCURACY = 0

        polygon = [(973 * SCALE, 412 * SCALE), (1195 * SCALE, 573 * SCALE), (1110 * SCALE, 834 * SCALE), (836 * SCALE, 834 * SCALE), (752 * SCALE, 573 * SCALE)]
        polygon = [(960 * SCALE, 280 * SCALE), (1234 * SCALE, 480 * SCALE), (1128 * SCALE, 800 * SCALE) ,(790 * SCALE, 800 * SCALE), (684 * SCALE, 480 * SCALE)]

        empty_indicator = pygame.Surface((0, 0))
        indicator = empty_indicator
        indicator_timer = 127
           
        isRunning = True

        hitObjects = [None, None, None, None, None]

        for i in range(5):
            tmp = current_song.note_data[i]
            hitObjects[i] = HitObject(tmp[1], tmp[0], song_time)

        currentHitObjectIdx = 0
        canHit = True
        isSongOver = False
        self.cleared = False

        songOverWait = 5000

        final_note_time = current_song.note_data[self.n_notes-1][0]

        # Start the song
        pygame.mixer.music.play()

        while isRunning:
            # Render Song BG
            screen.blit(song_background, (0, 0))
            
            # Render Score
            score_text = font_gravtrac_74.render(str(self.SCORE), True, (247, 37, 133))
            score_text_rect = score_text.get_rect()
            score_text_rect.center = (WIDTH / 2, 60 * SCALE)
            screen.blit(score_text, score_text_rect)
            
            # Render Combo
            combo_text = font_gravtrac_48.render(str(self.COMBO) + ' x', True, (181, 23, 158))
            combo_text_rect = combo_text.get_rect()
            combo_text_rect.center = (WIDTH / 2, 160 * SCALE)
            screen.blit(combo_text, combo_text_rect)
            
            # Render Polygon
            poly_surf = pygame.Surface((WIDTH, HEIGHT))
            pygame.draw.polygon(poly_surf, (55, 55, 55), polygon)
            poly_surf.set_colorkey((0, 0, 0))
            poly_surf.set_alpha(128)
            screen.blit(poly_surf, (0, 0))
            
            if isSongOver:
                songOverWait -= clock.get_time()
                if songOverWait < 0:
                    isRunning = False
            
            # Render HitCircle
            if canHit:
                hitDelta = hitObjects[currentHitObjectIdx % 5].when - song_time
                size_offset = hitObjects[currentHitObjectIdx % 5].SIZE
                hit_time = min(hitDelta / 15, 100)
                if hit_time != 100:
                    pygame.draw.circle(screen, (1, 1, 1), polygon[currentHitObjectIdx % 5], hit_time + size_offset)
                    pygame.draw.circle(screen, (255, 255, 255), polygon[currentHitObjectIdx % 5], hit_time - 5 + size_offset)
            
            # Render HitObjects
            for idx, object in enumerate(hitObjects):
                coords = list(polygon[idx])
                coords[0] -= object.SIZE
                coords[1] -= object.SIZE
                screen.blit(object.surface, coords)
                object.render(song_time)
            
            # Hit Object Cycle
            if hitObjects[currentHitObjectIdx % 5].when <= song_time and not isSongOver:
                if hitObjects[currentHitObjectIdx % 5].when == -1:
                    # print(f"SONG OVER | Score: {self.SCORE} Combo: {self.COMBO}x | Accuracy: {self.ACCURACY / current_song.n_notes * 100}%")
                    isSongOver = True
                    pygame.mixer.music.fadeout(5000)
                    self.cleared = True
                else:
                    if canHit:
                        # Miss
                        # print("MISS")
                        indicator = indicator_miss
                        indicator_timer = 127
                        hit_miss_sound.play()
                        self.COMBO = 1
                    canHit = True
                    if currentHitObjectIdx + 5 < current_song.n_notes:
                        tmp = current_song.note_data[currentHitObjectIdx + 5]
                        hitObjects[currentHitObjectIdx % 5] = HitObject(tmp[1], tmp[0], song_time)
                        currentHitObjectIdx += 1
                    else:
                        hitObjects[currentHitObjectIdx % 5] = HitObject(' ', -1, song_time)
                        currentHitObjectIdx += 1
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    isRunning = False 
                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        isRunning = False
                    
                    # Check Hit
                    elif event.key == ord(hitObjects[currentHitObjectIdx % 5].letter.lower()) and canHit and not isSongOver:
                        # Sucessfull hit
                        hitDelta = abs(hitDelta)
                        hit_sound.play()
                        if hitDelta <= 100:
                            # print("PERFECT")
                            indicator = indicator_perfect
                            indicator_timer = 127
                            self.ACCURACY += 1
                            self.SCORE += self.COMBO * 200
                            self.COMBO += 1
                        elif hitDelta <= 200:
                            # print("GOOD")
                            indicator = indicator_good
                            indicator_timer = 127
                            self.ACCURACY += 0.75
                            self.SCORE += self.COMBO * 100
                            self.COMBO += 1
                        elif hitDelta <= 400:
                            # print("BAD")
                            indicator = indicator_bad
                            indicator_timer = 127
                            self.ACCURACY += 0.5
                            self.SCORE += self.COMBO * 50
                            self.COMBO += 1
                        else:
                            # MISS
                            # print("MISS")
                            indicator = indicator_miss
                            indicator_timer = 127
                            self.COMBO = 1
                        canHit = False
                    elif canHit:
                        # print("WRONG KEY")
                        pass
                        
            
            indicator.set_alpha(indicator_timer * 2)
            screen.blit(indicator, indicator_pos)
            indicator_timer -= 1

            remaining_percent = min(song_time / final_note_time, 1)
            
            pygame.draw.rect(screen, (255, 255, 255), pygame.Rect((WIDTH / 2 - 202 * SCALE, HEIGHT - 52 * SCALE), (int(402 * SCALE), 12 * SCALE)))
            pygame.draw.rect(screen, (0, 0, 0), pygame.Rect((WIDTH / 2 - 200 * SCALE, HEIGHT - 50 * SCALE), (int(remaining_percent * 400 * SCALE), 10 * SCALE)))
            
            pygame.display.update()
            song_time += clock.get_time()
            clock.tick(FPS)
        
        pygame.mixer.music.stop()
 
class MenuSong:
    def __init__(self, title, filename, background_image):
        self.title = title
        self.filename = filename
        self.background_image = background_image
        
def main():
    isGameRunning = True
    
    song_file_list = [x for x in os.listdir('songs/') if x.endswith('.lk')]
    song_list = []
    for song in song_file_list:
        tmp_song = Song(f'songs/{song}')
        song_list.append(MenuSong(tmp_song.title, song, tmp_song.background_image))
    
    n_songs = len(song_list)
    menu_song_selected = 0
    
    while isGameRunning:
        song_image = pygame.transform.scale(pygame.image.load(f'songs/{song_list[menu_song_selected].background_image}'), (WIDTH, HEIGHT))
        screen.blit(song_image, (0, 0))
        
        song_title = font_gravtrac_74.render(song_list[menu_song_selected].title, False, (114, 9, 183))
        song_title_rect = song_title.get_rect()
        song_title_rect.center = (WIDTH/2, 70 * SCALE)
        
        screen.blit(song_title, song_title_rect)
        
        intstructions = font_gravtrac_48.render("Use the arrow keys to select a song. Press Enter to play it!", False, (181, 23, 158))
        intstructions_rect = intstructions.get_rect()
        intstructions_rect.center = (WIDTH/2, HEIGHT - 50 * SCALE)
        
        screen.blit(intstructions, intstructions_rect)
        
        for event in pygame.event.get():
                    if event.type == QUIT:
                        isGameRunning = False 
                    if event.type == KEYDOWN:
                        if event.key == K_ESCAPE:
                            isGameRunning = False
                        elif event.key == K_RETURN:
                            game = Game(song_list[menu_song_selected].filename)
                            print(f'cleared: {game.cleared} | score: {game.SCORE} | combo: {game.COMBO} x | accuracy: {game.ACCURACY / game.n_notes * 100}%')     
                        elif event.key == K_DOWN:
                            menu_song_selected = (menu_song_selected + 1) % n_songs
                        elif event.key == K_UP:
                            menu_song_selected = (menu_song_selected - 1) % n_songs
                    if event.type == MOUSEBUTTONDOWN:
                        if event.button == 5:
                            menu_song_selected = (menu_song_selected + 1) % n_songs
                        elif event.button == 4:
                            menu_song_selected = (menu_song_selected - 1) % n_songs
                           
        pygame.display.update()
        clock.tick(FPS)
    
    pygame.quit()
    
if __name__ == '__main__':
    main()
Setup # Change to project root directory Window Song Setup Game Loop # Start the song # Render Song BG # Render Score # Render Combo # Render Polygon # Render HitCircle # Render HitObjects # Hit Object Cycle # print(f"SONG OVER | Score: {self.SCORE} Combo: {self.COMBO}x | Accuracy: {self.ACCURACY / current_song.n_notes * 100}%") # Miss # print("MISS") # Check Hit # Sucessfull hit # print("PERFECT") # print("GOOD") # print("BAD") # MISS # print("MISS") # print("WRONG KEY")