파이게임으로 게임 만들기
자동차 피하기 게임
목차
- module import
- 변수
- Car 클래스
- 필요 함수
- 
    main함수
module import
import pygame
import random
import sys
- pygame모듈을 이용하여 pygame을 만듭니다. pygame을 무조건 써야죠.
- random모듈은 난수를 생성해주는 모듈입니다. 저희는 다른 자동차들이 랜덤으로 나와야 하기 때문에 무조건 써야하는 모듈입니다.
- sys모듈 : 인터프리터 제어
변수
WINDOW_WIDTH = 550
WINDOW_HEIGHT = 800
- 게임 화면을 설정해줍니다. 여기선 가로 550, 세로 800으로 설정했습니다.
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (150, 150, 150)
- 이 게임에서 사용할 색상 정보를 나타냅니다.
DIRCARS = "cars/"
DIRSOUND = "sound/"
- 소스 디렉토리를 나타냅니다.
STAGE = 1
CAR_COUNT = 5
SCORE = 0
STAGESCORE = 0
PNUMBER = 5
- 기본적으로 설정해주는 변수들입니다.
    - 저희는 1라운드부터 진행하니 STAGE를 1로 설정했습니다.
- CAR_COUNT는 플레이어의 목숨을 표시해주기 위해 쓰는 변수입니다.
- SCORE는 점수입니다. 0부터 시작해야하니 0으로 초기화를 했습니다.
- PNUMBER는 플레이어의 목숨 입니다
 
Car클래스
class Car:
    car_image = [
        'RacingCar01.png', 'RacingCar02.png', 'RacingCar03.png', 'RacingCar04.png', 'RacingCar05.png',
        'RacingCar06.png', 'RacingCar07.png', 'RacingCar08.png', 'RacingCar09.png', 'RacingCar10.png',
        'RacingCar11.png', 'RacingCar12.png', 'RacingCar13.png', 'RacingCar14.png', 'RacingCar15.png',
        'RacingCar16.png', 'RacingCar17.png', 'RacingCar18.png', 'RacingCar19.png', 'RacingCar20.png',
    ]
    def __init__(self, x=0, y=0, dx=0, dy=0):
        self.image = ""
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.rect = ""
    def load_car(self, p=""):
        if p == "p":
            self.image = pygame.image.load(DIRCARS + "RacingCar01.png")
            self.image = pygame.transform.scale(self.image, (40, 102))
            self.rect = self.image.get_rect()
            self.rect.x = self.x
            self.rect.y = self.y
        else:
            self.image = pygame.image.load(DIRCARS + random.choice(self.car_image))
            self.rect = self.image.get_rect()
            if self.rect.width <= 55:
                carwidth = self.rect.width - 15
                carheight = round((self.rect.height * carwidth) / self.rect.width)
            else:
                carwidth = self.rect.width
                carheight = self.rect.height
            self.image = pygame.transform.scale(self.image, (carwidth, carheight))
            self.rect.width = carwidth
            self.rect.height = carheight
            self.rect.x = random.randrange(0, WINDOW_WIDTH - self.rect.width)
            self.rect.y = random.randrange(-150, -50)
            speed = (STAGE*2) + 6
            if speed > 50:
                speed = 50
            self.dy = random.randint(8, speed)
    def draw_car(self):
        SCREEN.blit(self.image, [self.rect.x, self.rect.y])
    def move_x(self):
        self.rect.x += self.dx
    def move_y(self):
        self.rect.y += self.dy
    def check_screen(self):
        if self.rect.right > WINDOW_WIDTH or self.rect.x < 0:
            self.rect.x -= self.dx
        if self.rect.bottom > WINDOW_HEIGHT or self.rect.y < 0:
            self.rect.y -= self.dy
    def check_collision(self, car, distance=0):
        if (
            self.rect.top + distance < car.rect.bottom
            and car.rect.top < self.rect.bottom - distance
            and self.rect.left + distance < car.rect.right
            and car.rect.left < self.rect.right - distance
        ):
            return True
        else:
            return False
- 자동차를 불러오는 것과 자동차 동작들에 관한 클래스 입니다.
- 자동차에 관한 모든 함수가 있다고 생각하면 됩니다.
- load_car함수는 저 위의 자동차 이미지를 게임에 불러오는 겁니다.
필요 함수
def draw_score():
    font_01 = pygame.font.SysFont("FixedSsy", 30, True, False)
    text_score = font_01.render("Score : " + str(SCORE), True, BLACK)
    SCREEN.blit(text_score, [15, 15])
    text_stage = font_01.render("STAGE : " + str(STAGE), True, BLACK)
    text_stage_rect = text_stage.get_rect()
    text_stage_rect.centerx = round(WINDOW_WIDTH / 2)
    SCREEN.blit(text_stage, [text_stage_rect.x, 15])
    for i in range(PNUMBER):
        if i < 5:
            pimage = pygame.image.load(DIRCARS + 'RacingCar01.png')
            pimage = pygame.transform.scale(pimage, (15, 38))
            px = WINDOW_WIDTH - 20 - (i * 30)
            SCREEN.blit(pimage, [px, 15])
        else:
            text_pnumber = font_01.render("+" + str(PNUMBER - 5), True, WHITE)
            text_pnumber_x = WINDOW_WIDTH - 30 - (5 * 30)
            SCREEN.blit(text_pnumber, [text_pnumber_x, 25])
def increase_score():
    global SCORE, STAGE, STAGESCORE
    SCORE += 10 + STAGE - 1
    if SCORE >= STAGESCORE + 1000:
        STAGE += 1
        STAGESCORE += 1000
        
        # 3스테이지마다 CAR_COUNT를 2 증가
        if STAGE % 3 == 0:
            #최대 20대 까지만 증가하게
            global CAR_COUNT
            CAR_COUNT = min(CAR_COUNT + 2, 20)
            
            for _ in range(CAR_COUNT - len(CARS)):
                car = Car(0, 0, 0, 0)
                car.load_car()
                CARS.append(car)
def show_start_screen():
    global SCORE, STAGE, STAGESCORE, PNUMBER, CARS
    SCORE = 0
    STAGE = 1
    STAGESCORE = 0
    PNUMBER = 5
    CARS = []
    start_screen = True
    while start_screen:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    start_screen = False
        SCREEN.fill(WHITE)
        font = pygame.font.SysFont("FixedSsy", 50, True, False)
        text = font.render("Press Enter to Start", True, BLACK)
        text_rect = text.get_rect(center=(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
        SCREEN.blit(text, text_rect)
        pygame.display.flip()
def show_end_screen():
    global SCORE, STAGE, STAGESCORE, PNUMBER, CARS
    end_screen = True
    while end_screen:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    end_screen = False
                elif event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                elif event.key == pygame.K_r:
                    return True
                  
        SCREEN.fill(WHITE)
        font = pygame.font.SysFont("FixedSsy", 50, True, False)
        text = font.render("Game Over", True, BLACK)
        text_rect = text.get_rect(center=(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 3))
        SCREEN.blit(text, text_rect)
        score_text = font.render("Final Score: " + str(SCORE), True, BLACK)
        score_rect = score_text.get_rect(center=(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2))
        SCREEN.blit(score_text, score_rect)
        restart_text = font.render("Press R to Restart", True, BLACK)
        restart_rect = restart_text.get_rect(center=(WINDOW_WIDTH / 2, 2 * WINDOW_HEIGHT / 3))
        SCREEN.blit(restart_text, restart_rect)
        exit_text = font.render("Press ESC to Exit", True, BLACK)
        exit_rect = exit_text.get_rect(center=(WINDOW_WIDTH / 2, 5 * WINDOW_HEIGHT / 6))
        SCREEN.blit(exit_text, exit_rect)
        pygame.display.flip()
    return False
- 게임 진행에 있어 필요한 함수들이다.
- 점수 표시, 점수 올리기, 시작화면, 끝 화면을 구현한 함수들이다.
- 종료화면의 경우 R을 누르면 다시시작 기능이 구현되어 있다.
### 메인함수
 def main():
    global SCREEN, CAR_COUNT, WINDOW_WIDTH, WINDOW_HEIGHT, PNUMBER, SCORE, STAGE, STAGESCORE
    pygame.init()
    SCREEN = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE)
    pygame.display.set_caption("Racing Car Game")
    windowicon = pygame.image.load(DIRCARS + 'PyCar.png').convert_alpha()
    pygame.display.set_icon(windowicon)
    while True:
        show_start_screen()
        clock = pygame.time.Clock()
        pygame.mixer.music.load(DIRSOUND + 'background.ogg')
        sound_crash = pygame.mixer.Sound(DIRSOUND + 'crash.ogg')
        pygame.mixer.music.play(-1)
        player = Car(round(WINDOW_WIDTH / 2), round(WINDOW_HEIGHT - 150), 0, 0)
        player.load_car("p")
        
        for i in range(CAR_COUNT):
            car = Car(0, 0, 0, 0)
            car.load_car()
            CARS.append(car)
        playing = True
        while playing and PNUMBER > 0:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    playing = False
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_RIGHT:
                        player.dx = 5
                    elif event.key == pygame.K_LEFT:
                        player.dx = -5
                    if event.key == pygame.K_DOWN:
                        player.dy = 5
                    elif event.key == pygame.K_UP:
                        player.dy = -5
                    if event.key == pygame.K_ESCAPE:
                        return
                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_RIGHT:
                        player.dx = 0
                    elif event.key == pygame.K_LEFT:
                        player.dx = 0
                    if event.key == pygame.K_DOWN:
                        player.dy = 0
                    elif event.key == pygame.K_UP:
                        player.dy = 0
            SCREEN.fill(GRAY)
            player.draw_car()
            player.move_x()
            player.move_y()
            player.check_screen()
            for i in range(CAR_COUNT):
                CARS[i].draw_car()
                CARS[i].rect.y += CARS[i].dy
                if CARS[i].rect.y > WINDOW_HEIGHT:
                    increase_score()
                    CARS[i].load_car()
            for i in range(CAR_COUNT):
                if player.check_collision(CARS[i], 5):
                    PNUMBER -= 1
                    sound_crash.play()
                    if player.rect.x > CARS[i].rect.x:
                        CARS[i].rect.x -= CARS[i].rect.width + 10
                    else:
                        CARS[i].rect.x += CARS[i].rect.width + 10
                    if player.rect.y > CARS[i].rect.y:
                        CARS[i].rect.y -= 30
                    else:
                        CARS[i].rect.y += 30
            draw_score()
            pygame.display.flip()
            clock.tick(60)
        if not show_end_screen():
            break
if __name__ == '__main__':
    main()
- 게임을 실제로 진행시키는 메인함수입니다.
- 앞에 나와있는 클래스나 함수들을 바탕으로 실제로 게임을 진행시키는 역할을 합니다.
여기까진 게임 코드 입니다. 혹시 실제로 플레이하고 싶으시면 avoid_car를 클론해서 해보시기 바랍니다.