파이썬 수업/파이썬 미니프로젝트

[파이썬] 테트리스 만들기

climacus 2023. 10. 21. 11:18

배경음악에 쓰일 mp3 파일을, 파이썬 폴더에 넣어 준 뒤, 파일명을 넣어주어야 배경음악이 작동합니다. 

 

# 배경음악 로드 및 재생
pygame.mixer.init()
bgm = pygame.mixer.Sound('여기에 파일명을 넣어주세요')
bgm.play(-1)  # -1을 지정하면 반복 재생

 

 

import pygame
import random
import sys

# 초기화
pygame.init()

# 화면 설정
screen_width = 300
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("테트리스")

# 색상 정의
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# 테트리스 블록 모양 정의
tetris_shapes = [
    [[1, 1, 1, 1]],
    [[1, 1], [1, 1]],
    [[1, 1, 1], [0, 1, 0]],
    [[1, 1, 1], [1, 0, 0]],
    [[1, 1, 1], [0, 0, 1]],
    [[1, 1, 0], [0, 1, 1]],
    [[0, 1, 1], [1, 1, 0]]
]

# 게임 변수
block_size = 30
current_block = None
current_block_position = [0, 0]
grid = [[0] * (screen_width // block_size) for _ in range(screen_height // block_size)]
game_over = False

# 배경음악 로드 및 재생
pygame.mixer.init()
bgm = pygame.mixer.Sound('BradinskyTetris.mp3')
bgm.play(-1)  # -1을 지정하면 반복 재생
bgm.set_volume(0.3)  # 볼륨 조절

# 게임 함수
def draw_grid():
    for x in range(0, screen_width, block_size):
        pygame.draw.line(screen, WHITE, (x, 0), (x, screen_height))
    for y in range(0, screen_height, block_size):
        pygame.draw.line(screen, WHITE, (0, y), (screen_width, y))

def new_block():
    global current_block, current_block_position
    current_block = random.choice(tetris_shapes)
    current_block_position = [screen_width // 2, 0]

def draw_block(block, position):
    for y, row in enumerate(block):
        for x, value in enumerate(row):
            if value:
                pygame.draw.rect(screen, WHITE, (position[0] + x * block_size, position[1] + y * block_size, block_size, block_size))

def check_collision(block, position):
    for y, row in enumerate(block):
        for x, value in enumerate(row):
            if value:
                if (
                    position[0] + x * block_size < 0
                    or position[0] + x * block_size >= screen_width
                    or position[1] + y * block_size >= screen_height
                    or grid[(position[1] + y * block_size) // block_size][(position[0] + x * block_size) // block_size]
                ):
                    return True
    return False

def place_block():
    for y, row in enumerate(current_block):
        for x, value in enumerate(row):
            if value:
                grid[(current_block_position[1] + y * block_size) // block_size][(current_block_position[0] + x * block_size) // block_size] = 1

def check_lines():
    full_lines = []
    for y in range(len(grid)):
        if all(grid[y]):
            full_lines.append(y)

    for y in full_lines:
        grid.pop(y)
        grid.insert(0, [0] * (screen_width // block_size))

def game_over_screen():
    font = pygame.font.Font(None, 36)
    text = font.render("Game Over", True, WHITE)
    text_rect = text.get_rect(center=(screen_width // 2, screen_height // 2))
    screen.blit(text, text_rect)


# 게임 루프
clock = pygame.time.Clock()
new_block()
running = True
move_speed = 5  # 이동 속도 조절
game_over = False  # 게임 오버 상태 초기화

while running:
    screen.fill(BLACK)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if not game_over:
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            current_block_position[0] -= block_size
            if check_collision(current_block, current_block_position):
                current_block_position[0] += block_size
        if keys[pygame.K_RIGHT]:
            current_block_position[0] += block_size
            if check_collision(current_block, current_block_position):
                current_block_position[0] -= block_size
        if keys[pygame.K_DOWN]:
            current_block_position[1] += block_size
            if check_collision(current_block, current_block_position):
                current_block_position[1] -= block_size
        if keys[pygame.K_SPACE]:
            # 블록을 90도 오른쪽으로 회전
            rotated_block = list(zip(*current_block[::-1]))
            if not check_collision(rotated_block, current_block_position):
                current_block = rotated_block

        if not check_collision(current_block, [current_block_position[0], current_block_position[1] + block_size]):
            current_block_position[1] += block_size
        else:
            place_block()
            check_lines()
            new_block()

        for y, row in enumerate(grid):
            for x, value in enumerate(row):
                if value:
                    pygame.draw.rect(screen, WHITE, (x * block_size, y * block_size, block_size, block_size))

        draw_block(current_block, current_block_position)
        draw_grid()

        # 게임 오버 조건 검사
        if check_collision(current_block, current_block_position):
            game_over = True

    if game_over:
        game_over_screen()
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    # 게임 오버 상태에서 'R' 키를 누르면 게임을 재시작
                    game_over = False
                    grid = [[0] * (screen_width // block_size) for _ in range(screen_height // block_size)]
                    new_block()

    pygame.display.update()  # 디스플레이 업데이트
    clock.tick(move_speed)
반응형