Menu
CoddyTech

시작할 때 불러오기

Coddy Pygame 여정의 게임 규칙 섹션에 포함된 레슨. 29개 중 21번째.

기록이 저장되었습니다. 이제 게임이 시작될 때 다시 읽어 오세요. int(file.read())는 파일의 텍스트를 숫자로 바꿉니다. 처음 실행할 때는 파일이 없으므로 open이 FileNotFoundError를 발생시켜 프로그램을 중단합니다.

try와 except는 이 오류를 처리하고 대신 다른 작업을 수행합니다.

def load_best():
    try:
        with open("highscore.txt") as file:
            return int(file.read())
    except FileNotFoundError:
        return 0


best = load_best()

Python은 try 블록을 실행합니다. open이 FileNotFoundError를 발생시키면 except 블록으로 이동해 0을 반환합니다. 다른 오류가 발생하면 여전히 프로그램이 중단됩니다. 그렇게 되는 것이 맞습니다. 실제 버그이기 때문입니다.

모드를 지정하지 않고 open("highscore.txt")를 호출하면 파일을 읽기 모드로 엽니다.

데스크톱에서는 게임을 종료한 다음 다시 실행하면, 첫 번째 게임 오버 화면에 지난번 최고 기록이 표시됩니다. 브라우저에서는 페이지를 새로고침할 때까지 Play를 누를 때마다 똑같이 표시됩니다.

challenge icon

챌린지

중급
  1. load_best()를 작성하세요. 이 함수는 highscore.txt에 있는 숫자를 반환하며, 해당 파일이 없으면 0을 반환합니다.
  2. best = 0 대신 best = load_best()를 설정하세요.

직접 해보기

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2


def reset():
    global player, rocks, score, lives
    player = pygame.Rect(220, 300, 40, 40)
    rocks = []
    score = 0
    lives = 3
    pygame.time.set_timer(POINT, 1000)
    pygame.time.set_timer(SPAWN, 800)


def draw_menu():
    screen.fill((30, 30, 46))
    title = big_font.render("Meteor Dodge", True, WHITE)
    title_rect = title.get_rect(center=(240, 140))
    pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
    screen.blit(title, title_rect)
    hint = font.render("Press Enter to play", True, WHITE)
    screen.blit(hint, hint.get_rect(center=(240, 200)))


def draw_game():
    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (255, 196, 0), player)
    for rock in rocks:
        pygame.draw.rect(screen, (235, 80, 80), rock)
    score_text = font.render(f"{score:05}", True, WHITE)
    score_rect = score_text.get_rect(topright=(470, 10))
    pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
    screen.blit(score_text, score_rect)
    for i in range(3):
        if i < lives:
            screen.blit(heart, (10 + i * 40, 10))
        else:
            screen.blit(heart_empty, (10 + i * 40, 10))


def play_frame():
    global rocks, lives, state, best
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        player.x -= 6
    if keys[pygame.K_RIGHT]:
        player.x += 6
    player.clamp_ip(screen.get_rect())

    kept = []
    for rock in rocks:
        rock.y += 3
        if rock.colliderect(player):
            lives -= 1
        elif rock.top <= 360:
            kept.append(rock)
    rocks = kept
    if lives <= 0:
        state = "over"
        best = max(best, score)
        with open("highscore.txt", "w") as file:
            file.write(str(best))
    draw_game()


def draw_over():
    draw_game()
    message = big_font.render("Game over", True, WHITE)
    screen.blit(message, message.get_rect(center=(240, 160)))
    hint = font.render("Press R to play again", True, WHITE)
    screen.blit(hint, hint.get_rect(center=(240, 200)))
    best_text = font.render(f"Best: {best}", True, WHITE)
    screen.blit(best_text, best_text.get_rect(center=(240, 240)))


reset()
state = "menu"
best = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == POINT and state == "play":
            score += 1
        if event.type == SPAWN and state == "play":
            rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RETURN and state == "menu":
                reset()
                state = "play"
            elif event.key == pygame.K_r and state == "over":
                reset()
                state = "play"

    if state == "menu":
        draw_menu()
    elif state == "play":
        play_frame()
    else:
        draw_over()
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

게임 규칙의 모든 레슨

직접 연습해 보세요: Pygame 플레이그라운드