내일배움캠프 2기 🕹파이게임 프로젝트 - Run way (미사일 피하기 게임)

김태인·2022년 4월 27일
0

프로젝트

목록 보기
2/7

프로젝트명 : 파이게임 (Run way)

진행 날짜 : 2022-04-25~04-27
팀원 : 김태인 (개인 프로젝트)

금일 파이게임 개발 3일차를 종료했다
처음부터 기획했던 대로 모든 기능을 다 구현하진 못했지만
그래도 게임을 어떻게 만들어야하는지에 대한 기본적인 겉핥기는 나름의 성공?을 했다고 본다

아쉬웠던점은 class를 활용해서 객체지향적인 게임을 만들지 못했다는 것

해당하는 부분은 금주까지는 확실하게 개념을 익혀야 겠다는 생각을 했다

[초기 기획]

게임명(가제) : Kill the boss

구현하고자 했던 게임 : 가로로 오는 여러개의 미사일을 피해, 메인 캐릭터가 보스를 칼로 쳐서 처치한다

Fun point : 고전게임인 텐가이의 캐릭터를 착안하여 생각했고
수많은 미사일을 피해,
칼로 직접 적을 벨때의 모션과 사운드에서 재미를 느낄 수 있음

[문제점]

게임을 개발하며 구현을 하다보니

어떻게 이걸 설명해야 할지 모르겠는데
세로로 미사일이 날라오는것보다 가로로 미사일이 날라오게 하는 부분이 생각보다 구현이 어려웠고,

보스의 움직임 및 스프라이트를 이용하여 캐릭터의 액션을 연결하는 부분을 잘 쓰기 위해선 class 를 잘 써야만 했으나

아직은 해당부분을 구현하기가 어려워 기획을 변경하게되었다

[변경된 기획]

똥피하기의 업그레이드 버전!

게임명(가제) : run way

구현하고자 하는 점 : 가로로 미사일이 랜덤으로 떨어진다
보스가 랜덤으로 배치되어 미사일을 피하기 조금 더 어렵게 만든다

Fun point : 생각보다 빠른 미사일을 피하는 쾌감,
기괴한 보스의 찌그러진 모습과 신나는 음악의 조화!

[1차 완성 코드]

import pygame
import random

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

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

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

# FPS 설정
clock = pygame.time.Clock()

# 배경 이미지 불러오기
background = pygame.image.load("C:/Users/kti09/Desktop/realproject/image/mainBG.png")

# 배경음악 불러오기
pygame.mixer.music.load("C:/Users/kti09/Desktop/realproject/sounds/bgm.mp3")
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play(-1)

# 캐릭터 (스프라이트) 불러오기
character = pygame.image.load("C:/Users/kti09/Desktop/realproject/image/blueKnight.png")
character = pygame.transform.flip(character, True, 0)  # 캐릭터 이미지 좌우 반전
character = pygame.transform.scale(character, (55, 55))
character_size = character.get_rect().size  # 이미지 크기를 구해옴
character_width = character_size[0]  # 캐릭터의 가로 크기
character_height = character_size[1]  # 캐릭터의 세로 크기
character_x_pos = screen_width / 10 - character_width  # 가로 화면 크기의 10/1 크기의 해당 하는 곳에 위치
character_y_pos = (screen_height / 2) - (character_height / 2)  # 화면 세로 크기 가장 중간에 해당하는 곳 위치

# 적 enemy
enemy = pygame.image.load("C:/Users/kti09/Desktop/realproject/image/enemy.png")
enemy = pygame.transform.scale(enemy, (80, 150))
enemy_size = enemy.get_rect().size  # 이미지 크기를 구해옴
enemy_width = enemy_size[0]  # 적 캐릭터의 가로 크기
enemy_height = enemy_size[1]  # 적 캐릭터의 세로 크기
enemy_x_pos = random.randint(character_x_pos, screen_width - enemy_width)  # 가로 위치 랜덤 생성
enemy_y_pos = random.randint(0, 200)  # 잘 이해하지 못함

# 미사일 리스트 설정
missile_image = ['C:/Users/kti09/Desktop/realproject/image/missile_01.png',
                 'C:/Users/kti09/Desktop/realproject/image/missile_02.png']

# 미사일
missile = pygame.image.load(random.choice(missile_image))  # 리스트 내에 미사일 이미지 랜덤 초이스
missile = pygame.transform.scale(missile, (25, 25))  # 미사일 크기 사이즈 조정
missile_size = missile.get_rect().size  # 미사일의 크기를 구해옴
missile_width = missile_size[0]  # 미사일의 가로 사이즈
missile_height = missile_size[1]  # 미사일의 세로 사이즈
missile_x_pos = random.randint(0, screen_width - missile_width)  # 가로 위치 랜덤 생성
missile_y_pos = -random.randint(missile_height, 200)  # 세로의 -200 위치에서 랜덤 생성

# 이동할 좌표
character_to_x_LEFT = 0
character_to_x_RIGHT = 0
character_to_y_UP = 0
character_to_y_DOWN = 0

# 캐릭터 스피드
character_speed = 6.5

# 미사일 스피드
missile_speed = 12

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

# 시간 시간 정보
start_ticks = pygame.time.get_ticks()  # 현재 틱을 받아옴

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

    # 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:  # 캐릭터를 왼쪽으로
                character_to_x_LEFT -= character_speed  # to_x = to_x - 5
            elif event.key == pygame.K_RIGHT:  # 캐릭터를 오른쪽으로
                character_to_x_RIGHT += character_speed
            elif event.key == pygame.K_UP:  # 캐릭터를 위쪽으로
                character_to_y_UP -= character_speed
            elif event.key == pygame.K_DOWN:  # 캐릭터를 아래쪽으로
                character_to_y_DOWN += character_speed
            elif event.key == pygame.K_ESCAPE:
                pygame.quit()

        if event.type == pygame.KEYUP:  # 방향키에서 손을 떼면 멈춤
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    character_to_x_LEFT = 0
                elif event.key == pygame.K_RIGHT:
                    character_to_x_RIGHT = 0
                elif event.key == pygame.K_UP:
                    character_to_y_UP = 0
                elif event.key == pygame.K_DOWN:
                    character_to_y_DOWN = 0

    character_x_pos += character_to_x_LEFT + character_to_x_RIGHT
    character_y_pos += character_to_y_UP + character_to_y_DOWN

    # 미사일 떨어지게 설정
    missile_y_pos += missile_speed
    if missile_y_pos > screen_height - missile_height:
        missile_x_pos = random.randint(0, screen_width - missile_width)
        missile_y_pos = -random.randint(missile_height, 200)

    # 가로 경계값 처리
    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.x = character_x_pos
    character_rect.y = character_y_pos

    enemy_rect = enemy.get_rect()
    enemy_rect.x = enemy_x_pos
    enemy_rect.y = enemy_y_pos

    missile_rect = missile.get_rect()
    missile_rect.x = missile_x_pos
    missile_rect.y = missile_y_pos

    # 충돌 체크
    if character_rect.colliderect(missile_rect):
        game_result = ("Boom!!!")
        running = False

    if character_rect.colliderect(enemy_rect):
        game_result = ("Boom!!!")
        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))  # 적 캐릭터 그리기
    screen.blit(missile, (missile_x_pos, missile_y_pos))  # 미사일 그리기

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

    timer = game_font.render(str(int(total_time - elapsed_time)), True, (255, 255, 255))
    # 출력할 글자(시간), True, 글자 색상 (RGB 형태로 지정)
    screen.blit(timer, (10, 10))

    # 만약 시간이 0 이하 이면 게임 승리
    if total_time - elapsed_time <= 0:
        print("총알 피하기 성공!")
        game_result = "You SAFE!"
        running = False

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

msg = game_font.render(game_result, True, (255, 255, 0))
msg_rect = msg.get_rect(center=(int(screen_width / 2), int(screen_height / 2)))
screen.blit(msg, msg_rect)
pygame.display.update()

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

# pygame 종료
pygame.quit()

개발 이슈 및 처리과정

핵심 개발

  1. 키보드의 움직임 (좌우위아래 키 씹힘) -> 각각의 키를 독립적으로 설정하여 합침

  2. 캐릭터의 위치 -> 화면 분할을 통해 활용

  3. 보스의 위치 (랜덤) -> random.randint 활용

  4. 미사일의 위치 (랜덤) -> random.randint 활용

  5. 미사일의 개수 증가 -> 다중for문을 통해 구현은 했으나
    미사일과 충돌 후 running = False 부분을 제대로 실현하지 못해서
    다음기회로 미뤘다 (다중 for문도 사실 직접 짯다고 보기도 어려워서...)

느낀점

생각보다 게임개발은 쉬운일이 아니였다
앞으로 익혀가야 할 부분이 정말 많아서
기대가 되기도 한다

다만 제대로 개념을 이해한 후 개발에 들어갔으면 좋겠는데
워낙 부트캠프가 짧은시간에 빨리 많은것들을 이해해야 하는터라
그부분은 너무나도 아쉽다

그래도 어제보단 오늘의 내가 더 많은것들을 익혔으니
그것으로 위안을 삼는다

내일은 더 정진!

profile
코딩이 취미가 되는 그날까지

0개의 댓글