레이싱 게임

GitHub 소스 바로가기

import sys
import pygame
import random

# 게임 화면 크기
WINDOW_WIDTH = 550
WINDOW_HEIGHT = 800

# 색상
BLACK = (0,0,0)
WHITE = (255,255,255)
GRAY = (150, 150, 150)

# 소스 디렉토리

DIRCARS = "assets/assets/"

DIRSOUND = "assets/sounds/"

# 기본 변수
STAGE = 1
CAR_COUNT = 5
SCORE = 0
STAGESCORE = 0
STAGESTAIR = 1000

# 플레이어 Life 갯수
PNUMBER = 5

# 자동차 오브젝트를 저장할 List
CARS = []


def draw_score():
    # 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])

    # STAGE 기록
    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])

    # 플레이어 Life 기록
    for i in range(PNUMBER):
        # 5개는 그림으로
        if i < 5:
            pimage = pygame.image.load(DIRCARS + 'Player.png')
            pimage = pygame.transform.scale(pimage, (15, 38))
            px = WINDOW_WIDTH - 20 - (i * 30)
            SCREEN.blit(pimage, [px, 15])
        # 5개가 넘으면 숫자로 표현해준다.
        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

    # 점수 10점 추가

    SCORE += 10

    # STAGE별 증가율을 위한 stair 값 설정
    if STAGE == 1:
        stair = STAGESTAIR
    else:
        stair = (STAGE - 1) * STAGESTAIR

    # 스테이지 별 증가율에 따른 STAGE 증가
    if SCORE >= STAGESCORE + stair:
        STAGE += 1
        STAGESCORE = STAGESCORE + stair

class Car:
    car_image = ['Car01.png', 'Car02.png', 'Car03.png', 'Car04.png', 'Car05.png', \
                 'Car06.png', 'Car07.png', 'Car08.png', 'Car09.png', 'Car10.png', \
                 'Car11.png', 'Car12.png', 'Car13.png', 'Car14.png', 'Car15.png', \
                 'Car16.png', 'Car17.png', 'Car18.png', 'Car19.png', 'Car20.png', \
                 'Car21.png', 'Car22.png', 'Car23.png', 'Car24.png', 'Car25.png', \
                 'Car26.png', 'Car27.png', 'Car28.png', 'Car29.png', 'Car30.png', \
                 'Car31.png', 'Car32.png', 'Car33.png', 'Car34.png', 'Car35.png', \
                 'Car36.png', 'Car37.png', 'Car38.png', 'Car39.png', 'Car40.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, player=None):

        if player == 'my':
            # 플레이어 차량
            self.image = pygame.image.load(DIRCARS + "Player.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:
            # 상대방 자동차

            # 40개의 이미지중에서 랜덤으로 선택한다.
            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

            # 생성 위치 - 스크린 크기 안에서 랜덤으로 x 좌표 생성. y 좌표는 스크린 밖 위에 생성
            self.rect.x = random.randrange(0, WINDOW_WIDTH - self.rect.width)
            self.rect.y = random.randrange(-150, -50)

            # STAGE에 따른 속도 변화, STAGE가 높아짐에 따라 자동차의 속도도 빨라진다.

            # 다양한 속도차이를 위해 5 ~ speed 사이에세 랜덤으로 속도를 선택하게 한다.
            speed = STAGE + 5
            if speed > 15:
                speed = 15
            self.dy = random.randint(5, speed)

    # 자동차를 스크린에 그리기

    def draw_car(self):
        SCREEN.blit(self.image, [self.rect.x, self.rect.y])

    # x 좌표 이동 - 플레이어 자동차의 움직임 제어할 때 필요

    def move_x(self):
        self.rect.x += self.dx

    # y 좌표 이동 - 플레이어 자동차의 움직임 제어할 때 필요,

    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

    # 차량 충돌 감지
    # distance : 오른쪽, 왼쪽, 아래쪽, 위쪽 이미지의 간격 설정
    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




def main():
    global SCREEN, CAR_COUNT, WINDOW_WIDTH, WINDOW_HEIGHT, PNUMBER

    # pygame 초기화 및 스크린 생성

    pygame.init()
    SCREEN = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT),
                                     pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.RESIZABLE)
    pygame.display.set_caption("Racing Car Game")
    # 투명 아이콘은 32 x 32 로 해야 적용 됨
    windowicon = pygame.image.load(DIRCARS + 'icon.png').convert_alpha()
    pygame.display.set_icon(windowicon)

    clock = pygame.time.Clock()

    # 배경음악 지정. wav, mp3, ogg 가능
    pygame.mixer.music.load(DIRSOUND + 'background.ogg')

    # 충돌 사운드 지정. wav, 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("my")

    # 설정한 수 만큼 자동차 오브젝트 생성하여 CARS 리스트에 넣기

    for i in range(CAR_COUNT):
        car = Car(0, 0, 0, 0)
        car.load_car()
        CARS.append(car)

    playing = True

    while playing:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                playing = False
                pygame.quit()
                sys.exit()

            # 화살표 키를 이용해서 플레이어의 움직임 거리를 조정해준다.
            # 키를 떼면 움직임 거리를 0으로 한다.
            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.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

        # 상대 자동차들끼리 충돌 감지, 각 자동차들을 순서대로 서로 비교
        for i in range(CAR_COUNT):
            for j in range(i + 1, CAR_COUNT):
                # 충돌 후 서로 팅겨 나가게 함.
                if CARS[i].check_collision(CARS[j]):
                    # 왼쪽에 있는 차는 왼쪽으로 오른쪽 차는 오른쪽으로 튕김
                    if CARS[i].rect.x > CARS[j].rect.x:
                        CARS[i].rect.x += 4
                        CARS[j].rect.x -= 4
                    else:
                        CARS[i].rect.x -= 4
                        CARS[j].rect.x += 4

                    # 위쪽 차는 위로, 아래쪽차는 아래로 튕김
                    if CARS[i].rect.y > CARS[j].rect.y:
                        CARS[i].rect.y += CARS[i].dy
                        CARS[j].rect.y -= CARS[j].dy
                    else:
                        CARS[i].rect.y -= CARS[i].dy
                        CARS[j].rect.y += CARS[j].dy

        ''' 게임 코드 끝 '''
        draw_score()
        pygame.display.flip()

        # 초당 프레임 설정
        clock.tick(60)


if __name__ == '__main__':
    main()

Table of contents 목차

평점을 남겨주세요
평점 : 5.0
총 투표수 : 1