나를 기록하다
article thumbnail
반응형

환경설정 및 프레임

pygame 설치

pip3 install pygame # pygame 설치

 

frame 설정

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

# pygame 종료
pygame.quit()

 

 

배경

강의에서는 그림판으로 제작하나 나는 unsplash에서 무료 이미지를 다운받았다.

 

다운 받은 사진의 크기를 조절해야 하는데 mac에서 사진 크기를 조절하는 방법은 다음과 같다.

  1. 사진을 미리보기에서 열기
  1. 상단 메뉴에서 "도구 상자"를 클릭
  1. "크기 조정"을 선택
  1. 새로운 크기를 선택하고 "적용"을 클릭
  1. 파일을 저장

 

그리고 다운받은 파일을 게임을 만들고 있는 폴더로 이동시켜준다. 나의 경우에는 pythonworkspace 폴더에 넣고 background.jpg로 이름을 변경하였다.

 

작성 코드

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

    # screen.fill((70,60,25)) # (R, G, B) 값으로 배경 설정
    screen.blit(background, (0, 0))  # 배경 그리기

    pygame.display.update() # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

 

 

 

캐릭터

강의에서는 그림판으로 캐릭터를 그리지만 나는 이번에도 인터넷에서 무료 캐릭터 이미지를 다운받아서 진행했다.

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("Nado Game")  # 게임 이름

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = screen_width / 2  # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, character_x_pos, character_y_pos)  # 캐릭터 그리기

    pygame.display.update()  # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

 

에러 등장 - position 설정 시 ( ) 빼먹지 말 것!

순조로운 느낌이었으나 여기서 에러를 마주했다.

pygame 2.3.0 (SDL 2.24.2, Python 3.9.13)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/3_main_sprite.py", line 33, in <module>
    screen.blit(character, character_x_pos, character_y_pos)  # 캐릭터 그리기
TypeError: invalid destination position for blit

 

이유는 단순했다.

blit 함수를 호출할 때 destination position의 형식이 잘못되었기 때문에 발생했다.

이 문제를 해결하려면 blit 함수에 전달하는 인자의 형식을 확인해야 한다.

보통 blit 함수를 호출할 때 destination position은 하나의 튜플 형태로 (x, y) 좌표값을 전달하는데 따라서 오류 메시지에서 "invalid destination position for blit"는 blit 함수의 destination position이 잘못되었다는 의미이다.

해결 방법으로, 다음과 같은 코드를 사용하여 인자를 수정하면 된다.

screen.blit(character, (character_x_pos, character_y_pos))

이 코드에서는 character_x_poscharacter_y_pos를 하나의 튜플로 묶어 (character_x_pos, character_y_pos) 형태로 전달한다.

이렇게 하면 blit 함수에서 destination position을 올바르게 인식할 수 있게 한다.

 

캐릭터가 하단 중앙에 위치하도록 설정

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = screen_width / 2 - character_width / 2 # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 그리기

    pygame.display.update()  # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

 

현재까지의 배경 + 캐릭터

키보드 이벤트

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = (screen_width / 2) - (character_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이동할 좌표
to_x = 0
to_y = 0

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

        if event.type == pygame.KEYDOWN:  # 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:  # 캐릭터를 왼쪽으로 이동
                to_x -= 5
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로 이동
                to_x += 5
            elif event.key == pygame.K_UP:  # 캐릭터를 위로 이동
                to_y -= 5
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래로 이동
                to_y += 5
        if event.type == pygame.KEYUP:  # 방향키를 떼면 멈춤
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    character_x_pos += to_x
    character_y_pos += to_y

    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width

    if character_y_pos < 0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 그리기

    pygame.display.update()  # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

키보드의 입력에 따라 움직이게 설정했다.

컴퓨터의 이미지는

이런 식으로 그려진다. 따라서 x축은 원래대로 오른쪽이면 +, 왼쪽이면 -를 하면 된다.

하지만 y축은 반대로 해야한다. 위의 방향이면 -, 아래 방향이면 +를 해야한다.

 

여기에 더하여 화면 밖으로 캐릭터가 벗어나지 못하도록 if문에 조건을 추가하였다.

 

캐릭터의 이동 관련해서 코드에 대한 분석

    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

        if event.type == pygame.KEYDOWN:  # 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:  # 캐릭터를 왼쪽으로 이동
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로 이동
                to_x += character_speed
            elif event.key == pygame.K_UP:  # 캐릭터를 위로 이동
                to_y -= character_speed
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래로 이동
                to_y += character_speed
        if event.type == pygame.KEYUP:  # 방향키를 떼면 멈춤
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
  1. for event in pygame.event.get(): - 이벤트 루프에서 발생한 모든 이벤트를 가져옵니다.
  1. if event.type == pygame.QUIT: - 사용자가 게임 창을 닫으려고 할 때 발생하는 이벤트입니다. 이 경우, running 변수를 False로 설정하여 게임 루프를 종료합니다.
  1. if event.type == pygame.KEYDOWN: - 키보드 키가 눌린 경우를 처리합니다.
    • if event.key == pygame.K_LEFT: - 왼쪽 방향키가 눌린 경우, 캐릭터의 이동 속도(character_speed)만큼 왼쪽으로 이동하도록 설정합니다. 이를 위해 to_x 변수에서 character_speed 값을 뺍니다.
    • elif event.key == pygame.K_RIGHT: - 오른쪽 방향키가 눌린 경우, 캐릭터의 이동 속도(character_speed)만큼 오른쪽으로 이동하도록 설정합니다. 이를 위해 to_x 변수에 character_speed 값을 더합니다.
  1. if event.type == pygame.KEYUP: - 키보드 키가 눌렸다가 떼어진 경우를 처리합니다.
    • if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: - 왼쪽 또는 오른쪽 방향키에서 손을 떼면, 캐릭터의 가로 이동을 멈추도록 설정합니다. 이를 위해 to_x 변수를 0으로 설정합니다.

 

 

 

FPS

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# FPS
clock = pygame.time.Clock()

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = (screen_width / 2) - (character_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도
character_speed = 0.6

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    dt = clock.tick(60)  # 게임 화면의 초당 프레임 수를 결정

# 캐릭터가 100 만큼 이동해야 함
# 10 fps : 1초 동안에 10번 동작 -> 1번에 몇 만큼 이동? 10만큼! 10 * 10 = 100
# 20 fps : 1초 동안에 20번 동작 -> 1번에 몇 만큼 이동? 5만큼 !  5 * 20 = 100



    print("fps : " + str(clock.get_fps()))

    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

        if event.type == pygame.KEYDOWN:  # 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:  # 캐릭터를 왼쪽으로 이동
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로 이동
                to_x += character_speed
            elif event.key == pygame.K_UP:  # 캐릭터를 위로 이동
                to_y -= character_speed
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래로 이동
                to_y += character_speed
        if event.type == pygame.KEYUP:  # 방향키를 떼면 멈춤
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width

    if character_y_pos < 0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 그리기

    pygame.display.update()  # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

fps와 character_x_pos, character_y_pos 를 이용하여 시간당 움직임을 설정한다.

 

 

 

충돌 처리

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# FPS
clock = pygame.time.Clock()

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = (screen_width / 2) - (character_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도
character_speed = 0.6

# 적 enemy 캐릭터
# 캐릭터(스프라이트) 불러오기
enemy = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/enemy.png")
enemy_size = enemy.get_rect().size  # 이미지의 크기를 구해옴
enemy_width = enemy_size[0]  # 캐릭터의 가로 크기
enemy_height = enemy_size[1]  # 캐릭터의 새로 크기
enemy_x_pos = (screen_width / 2) - (enemy_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
enemy_y_pos = (screen_height / 2) - (enemy_height / 2)  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    dt = clock.tick(60)  # 게임 화면의 초당 프레임 수를 결정

    # 캐릭터가 100 만큼 이동해야 함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 몇 만큼 이동? 10만큼! 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 몇 만큼 이동? 5만큼 !  5 * 20 = 100

    # print("fps : " + str(clock.get_fps())) # fps 출력

    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

        if event.type == pygame.KEYDOWN:  # 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:  # 캐릭터를 왼쪽으로 이동
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로 이동
                to_x += character_speed
            elif event.key == pygame.K_UP:  # 캐릭터를 위로 이동
                to_y -= character_speed
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래로 이동
                to_y += character_speed
        if event.type == pygame.KEYUP:  # 방향키를 떼면 멈춤
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    # 가로 경계값 처리
    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width

    # 세로 경계값 처리
    if character_y_pos < 0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height

    # 충돌 처리를 위한 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos

    enemy_rect = enemy.get_rect()
    enemy_rect.left = enemy_x_pos
    enemy_rect.top = enemy_y_pos

    # 충돌 체크
    if character_rect.colliderect(enemy_rect):
        print("충돌")
        running = False

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 그리기

    screen.blit(enemy, (enemy_x_pos, enemy_y_pos))

    pygame.display.update()  # 게임 화면을 다시 그리기
# pygame 종료
pygame.quit()

enemy를 만들고 character의 이미지처럼 다운받은 이미지의 사이즈를 70*70으로 맞춰서 첨부하였다.

그리고 충돌처리를 위한 rect 정보 업데이트, 충돌 체크를 위한 colliderect를 사용하여 충돌 시 게임이 종료되도록 구현하였다.

 

텍스트

import pygame

pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("prao Game")  # 게임 이름

# FPS
clock = pygame.time.Clock()

# 배경 이미지 불러오기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터(스프라이트) 불러오기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size  # 이미지의 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 새로 크기
character_x_pos = (screen_width / 2) - (character_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
character_y_pos = screen_height - character_height  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 이동할 좌표
to_x = 0
to_y = 0

# 이동 속도
character_speed = 0.6

# 적 enemy 캐릭터
# 캐릭터(스프라이트) 불러오기
enemy = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/enemy.png")
enemy_size = enemy.get_rect().size  # 이미지의 크기를 구해옴
enemy_width = enemy_size[0]  # 캐릭터의 가로 크기
enemy_height = enemy_size[1]  # 캐릭터의 새로 크기
enemy_x_pos = (screen_width / 2) - (enemy_width / 2)  # 화면 가로의 절반 크기에 해당하는 곳에 위치
enemy_y_pos = (screen_height / 2) - (enemy_height / 2)  # 화면 세로 크기의 가장 아래에 해당하는 곳에 위치

# 폰트 정의
game_font = pygame.font.Font(None, 40)  # 폰트 객체 생성 (폰트, 크기)

# 총 시간
total_time = 10

# 시작 시간
start_ticks = pygame.time.get_ticks()  # 시작 tick 을 받아옴

# 이벤트 루프
running = True  # 게임이 진행 중인지 확인
while running:
    dt = clock.tick(60)  # 게임 화면의 초당 프레임 수를 결정

    # 캐릭터가 100 만큼 이동해야 함
    # 10 fps : 1초 동안에 10번 동작 -> 1번에 몇 만큼 이동? 10만큼! 10 * 10 = 100
    # 20 fps : 1초 동안에 20번 동작 -> 1번에 몇 만큼 이동? 5만큼 !  5 * 20 = 100

    # print("fps : " + str(clock.get_fps())) # fps 출력

    for event in pygame.event.get():  # 어떤 이벤트가 발생하였는가?
        if event.type == pygame.QUIT:  # 창이 닫히는 이벤트가 발생하였는가?
            running = False  # 게임이 진행 중이 아님

        if event.type == pygame.KEYDOWN:  # 키가 눌러졌는지 확인
            if event.key == pygame.K_LEFT:  # 캐릭터를 왼쪽으로 이동
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로 이동
                to_x += character_speed
            elif event.key == pygame.K_UP:  # 캐릭터를 위로 이동
                to_y -= character_speed
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래로 이동
                to_y += character_speed
        if event.type == pygame.KEYUP:  # 방향키를 떼면 멈춤
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                to_y = 0

    character_x_pos += to_x * dt
    character_y_pos += to_y * dt

    # 가로 경계값 처리
    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width

    # 세로 경계값 처리
    if character_y_pos < 0:
        character_y_pos = 0
    elif character_y_pos > screen_height - character_height:
        character_y_pos = screen_height - character_height

    # 충돌 처리를 위한 rect 정보 업데이트
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos

    enemy_rect = enemy.get_rect()
    enemy_rect.left = enemy_x_pos
    enemy_rect.top = enemy_y_pos

    # 충돌 체크
    if character_rect.colliderect(enemy_rect):
        print("충돌")
        running = False

    screen.blit(background, (0, 0))  # 배경 그리기

    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 그리기

    screen.blit(enemy, (enemy_x_pos, enemy_y_pos))

    # 타이머 집어 넣기
    # 경과 시간 계산
    elapsed_time = (pygame.time.get_ticks() - start_ticks) / 1000
    # 경과 시간(ms)을 1000으로 나누어서 초 단위로 표시

    timer = game_font.render(str(int(total_time - elapsed_time)), True, (255, 255, 255))
    # 출력할 글자, True, 글자 색상
    screen.blit(timer, (10, 10))

    # 만약 시간이 0 이하이면 게임 종료
    if total_time - elapsed_time <= 0:
        print("타임아웃")
        running = False

    pygame.display.update()  # 게임 화면을 다시 그리기

# 잠시 대기
pygame.time.delay(2000)  # 2초 정도 대기(ms)

# pygame 종료
pygame.quit()

get_ticks를 이용하여 시작시간(start_ticks)을 구하고,

경과시간(elapsed_time) = (현재시간(pygame.time.get_ticks())-시작시간(start_ticks)) / 1000

타이머는 설정해둔 전체시간(total_time)-경과시간(elapsed_time)을 표시한다.

 

screen.blit()이 무엇인가

screen.blit()은 Pygame 라이브러리에서 제공하는 함수 중 하나, 이 함수는 주어진 이미지를 지정된 위치에 그리는 역할을 한다.

일반적으로 게임 개발에서는 Pygame에서제공하는 Surface 객체를 이용하여 화면을 구성한다. 이때 blit() 함수를 사용하여 Surface 객체에 그릴 이미지를 넣고, 화면에 보여주고자 하는 위치에 해당하는 좌표값을 지정한다.

예를 들어, 아래와 같이 코드를 작성하면 이미지 파일 "image.png"를 (100, 200) 위치에 그릴 수 있다.

import pygame

pygame.init()

# 화면 설정
screen = pygame.display.set_mode((800, 600))

# 이미지 불러오기
image = pygame.image.load("image.png")

# 이미지 그리기
screen.blit(image, (100, 200))

# 화면 업데이트
pygame.display.flip()

# 게임 종료
pygame.quit()

따라서, screen.blit() 함수는 Pygame에서 게임 화면에 이미지를 그리는데 사용되는 함수이다.

 

 

게임 개발 프레임

import pygame

"""======================================================================="""
"""기본 초기화 (반드시 해야하는 것들)"""
pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("게임 이름")  # 게임 이름

# FPS
clock = pygame.time.Clock()
"""======================================================================="""
"""1. 사용자 게임 초기화 (배경화면, 게임 이미지, 좌표, 속도, 폰트 등)"""
ㄴ
running = True
while running:
    dt = clock.tick(60)

    """2. 이벤트 처리"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    """3. 게임 캐릭터 위치 정의"""

    """4. 충돌 처리"""

    """5. 화면에 그리기"""

    pygame.display.update()

pygame.quit()

게임 개발을 할 때 필수적으로 필요한 프레임들을 남겼다.

퀴즈

문제

하늘에서 떨어지는 똥 피하기 게임을 만드시오.

[게임 조건]
1. 캐릭터는 화면 가장 아래에 위치, 좌우로만 이동 가능
2. 똥은 화면 가장 위에서 떨어짐. x 좌표는 매번 랜덤으로 설정
3. 캐릭터가 똥을 피하면 다음 똥이 다시 떨어짐
4. 캐릭터가 똥과 충돌하면 게임 종료
5. FPS는 30으로 고정

[게임 이미지]
1. 배경 : 640 * 480 (세로 / 가로) - background.png
2. 캐릭터 : 70 * 70 - character.png
3. 똥 : 70 * 70 - enemy.png

 

풀이

import random
import pygame

"""======================================================================="""
"""기본 초기화 (반드시 해야하는 것들)"""
pygame.init()  # 초기화 (반드시 필요)

# 화면 크기 설정
screen_width = 480  # 가로 크기
screen_height = 680  # 세로 크기
screen = pygame.display.set_mode((screen_width, screen_height))

# 화면 타이틀 설정
pygame.display.set_caption("게임 이름")  # 게임 이름

# FPS
clock = pygame.time.Clock()
"""======================================================================="""
"""1. 사용자 게임 초기화 (배경화면, 게임 이미지, 좌표, 속도, 폰트 등)"""
# 배경 만들기
background = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/background.jpg")

# 캐릭터 만들기
character = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/character.png")
character_size = character.get_rect().size
character_width = character_size[0]
character_height = character_size[1]
character_x_pos = (screen_width / 2) - (character_width / 2)
character_y_pos = screen_height - character_height

# 이동 위치
to_x = 0
character_speed = 0.7

# 똥 만들기
ddong = pygame.image.load("/Users/prao/Desktop/DEV.PRAO/pythonworkspace/pygame_basic/enemy.png")
ddong_size = ddong.get_rect().size
ddong_width = ddong_size[0]
ddong_height = ddong_size[1]
ddong_x_pos = random.randint(0, screen_width - ddong_width)
ddong_y_pos = 0
ddong_speed = 5

running = True
while running:
    dt = clock.tick(60)

    """2. 이벤트 처리"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                to_x -= character_speed
            elif event.key == pygame.K_RIGHT:
                to_x += character_speed

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                to_x = 0
    """3. 게임 캐릭터 위치 정의"""
    character_x_pos += to_x * dt

    if character_x_pos < 0:
        character_x_pos = 0
    elif character_x_pos > screen_width - character_width:
        character_x_pos = screen_width - character_width

    ddong_y_pos += ddong_speed

    if ddong_y_pos > screen_height:
        ddong_y_pos = 0
        ddong_x_pos = random.randint(0, screen_width - ddong_width)

    """4. 충돌 처리"""
    character_rect = character.get_rect()
    character_rect.left = character_x_pos
    character_rect.top = character_y_pos

    ddong_rect = ddong.get_rect()
    ddong_rect.left = ddong_x_pos
    ddong_rect.top = ddong_y_pos

    if character_rect.colliderect(ddong_rect):
        print("충돌")
        running = False

    """5. 화면에 그리기"""
    screen.blit(background, (0, 0))
    screen.blit(character, (character_x_pos, character_y_pos))
    screen.blit(ddong, (ddong_x_pos, ddong_y_pos))

    pygame.display.update()

pygame.quit()

 

똥 사진은 넣기 귀찮아서 이렇게 완성했다.

그리고 노트북 램이 16GB인데 왜 버벅거리는지 모르겠다…

맥북 m1 프로 램 16 사용 중인데 컴퓨터 문젠가? 메모리 사용률이 70퍼 정도 나오긴 한다. 문제 원인 아는 분 있으면 댓글로 알려주시면 감사하겠습니다:)

 

 

반응형
profile

나를 기록하다

@prao

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...