파이게임으로 게임 만들기
자동차 피하기 게임
목차
- 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를 클론해서 해보시기 바랍니다.