본문 바로가기
DEV/파이썬 이론

파이썬 코딩 :: 파이썬 Pygame, 게임 만들기_똥 피하기

by 올커 2022. 8. 13.

파이썬 Pygame, 게임 만들기_똥 피하기


게임 설명

  - 하늘에서 떨어지는 똥을 피하는 게임

조건 

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

1. 파이게임(Pygame) 기본 프레임

import pygame

# 초기화
pygame.init()

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

# 타이틀
pygame.display.set_caption("Quiz")

# FPS(Frame per second : 초당 프레임수) → 프레임수가 높을수록 화면이 부드러움
clock = pygame.time.Clock()

 

2. 배경화면

background = pygame.image.load("IMG 저장 경로")

3. 캐릭터 생성

# 캐릭터 이미지
character = pygame.image.load("캐릭터 IMG 경로")

# 불러온 캐릭터 이미지 사이즈
character_size = character.get_rect().size                # get_rec.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 = 3

4. Enemy(똥) 생성

import random               # Enemy 이미지 위치의 랜덤 적용을 위해 import

...

# Enemy 이미지
enemy = pygame.image.load("Enemy IMG 경로")

# 불러온 Enemy 이미지 사이즈 
enemy_size = enemy.get_rect().size                  # rec로 이미지의 크기를 구해옴
enemy_width = enemy_size[0]                         # enemy의 가로 크기
enemy_height = enemy_size[1]                        # enemy의 세로 크기

# Enemy 이미지 위치
enemy_x_pos = random.randint(0,screen_width-enemy_width)     # 화면 가로의 절반 크기에 해당하는 곳에 위치
enemy_y_pos = 0                                              # y좌표는 꼭대기에서 떨어지기 때문에 0

# Enemy 이동 속도
enemy_speed = 10

5. 이벤트 루프

  - 프로그램 종료되지 않도록 대기 or 키보드, 마우스의 움직임을 검사

# 이벤트 루프
running = True
while running:
    dt = clock.tick(60)        # FPS 30
    
    # 이벤트 처리 (키보드, 마우스 등)
    for event in pygame.event.get():  # event 발생시 처리
        if event.type == pygame.QUIT:  # x버튼을 눌러서 프로그램을 종료시
            running = False  # running 종료

        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


	# 방향키 조작에 따라 캐릭터 위치 변경
    character_x_pos += to_x * dt  # 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

    enemy_y_pos += enemy_speed       # enemy의 위치가 속도값이 누적되어감에 따라 변화

    # Enemy가 바닥에 도달했을 경우 새롭게 Enemy를 y_pos=0에 생성
    if enemy_y_pos > screen_height:
        enemy_y_pos = 0
        enemy_x_pos = random.randint(0,screen_width-enemy_width)

    # 충돌 처리를 위한 rect 정보 update
    character_rect = character.get_rect()  # character가 가지는 rectangle정보(좌표, width, height)를 가져온다
    character_rect.left = character_x_pos  # character의 실제 위치로 update
    character_rect.top = character_y_pos  # character의 실제 위치로 update

    enemy_rect = enemy.get_rect()  # enemy가 가지는 rectangle정보(좌표, width, height)를 가져온다
    enemy_rect.left = enemy_x_pos  # enemy의 실제 위치로 update
    enemy_rect.top = enemy_y_pos   # enemy의 실제 위치로 update

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

    # 3. 화면에 표시하기
    screen.blit(background, (0, 0))  # (0, 0)좌표에 배경 이미지를 둔다
    screen.blit(character, (character_x_pos, character_y_pos))  # 캐릭터 이미지를 둔다
    screen.blit(enemy, (enemy_x_pos, enemy_y_pos))  # enemy 이미지를 둔다

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

6. 대기 및 종료

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

# pygame 종료
pygame.quit()

 

※ 완성된 파일

quiz.py
0.01MB

 

※ 참고 : Youtube 나도코딩 무료 강의 - https://youtu.be/Dkx8Pl6QKW0

 

반응형

댓글