지금까지 로또 프로그램, 진법 계산기, 회원가입 프로그램 3가지 과제를 도와줬고 남은 과제
“PyCar 프로젝트에 새로운 기능 추가하기” 과제를 도와주었다.
PyCar 프로젝트
PyCar 프로젝트는 SuanLab 에서 토이 프로젝트로 만든 간단한 게임 프로젝트인데
여기에 독창적인 기능을 추가하는 것이 과제였다.
추가한 기능
- 도로 양 옆에 충돌 감지가 가능한 가로수 추가
- 닉네임을 입력하여 점수 랭킹 시스템
기존에 존재하던 문제점을 해결
- 플레이어의 차량이 랜덤으로 배정되지 않고 고정되게끔 변경
-
랜덤하게 생성되는 장애물 차량들이 겹치는 문제 해결
기존 기능에 맵 어디서든 가로수가 생성되는 기능이 있었는데,
해당 기능을 활용해서 도로 양 옆에 가로수를 1자로 나열하는 기능을 추가하였고
기존에 게임 제목과 스코어 UI를 출력해주는 screen.blit을 활용해서 점수 랭킹 시스템도 구현 하였다.
— 기존의 플레이 방식은 플레이어의 차량이 랜덤으로 배정되지 않고 정해진 차량 이미지로만 게임을 진행할 수 있었다.
이 방식을 랜덤함수를 사용해서 랜덤함수로 뽑아낸 숫자를 차량 이미지 리스트 image_car 에서 인덱스 주소로
갖고 있는 차량 이미지를 플레이어의 차량 이미지로 배정될 수 있도록 수정하였고,
랜덤하게 생성되는 장애물 차량들이 겹치는 오류를 차량 이미지의 크기 값을 고정시키고 겹치지 않게 하여 해결하였다.
PyCar.py
import pygame
import random
from time import sleep
input_rect = pygame.Rect(200, 200, 140, 32)
user_text = ''
#####
WINDOW_WIDTH = 1300
WINDOW_HEIGHT = 800
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (150, 150, 150)
RED = (255, 0, 0)
rank_name=["HwangGiHyeon", "SongDoHun", "Oh Professor"]
rank_score=["1" , "1", "99999"]
class Tree:
image_tree = 'Tree.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
def load_image(self):
self.image = pygame.image.load(self.image_tree)
self.width = self.image.get_rect().size[0]
self.height = self.image.get_rect().size[1]
def draw_image(self):
screen.blit(self.image, [self.x, self.y])
def check_out_of_screen(self):
if self.x+self.width > WINDOW_WIDTH or self.x < 0:
self.x -= self.dx
def check_crash(self,tree):
if (self.x+self.width > tree.x) and (self.x < car.x+tree.width) and (self.y < tree.y+tree.height) and (self.y+self.height > tree.y):
return True
else:
return False
class Car:
image_car = ['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
def load_image(self):
self.image = pygame.image.load(random.choice(self.image_car))
self.width = self.image.get_rect().size[0]
self.height = self.image.get_rect().size[1]
def load_own_image(self):
self.image = pygame.image.load(self.image_car[18])
self.width = self.image.get_rect().size[0]
self.height = self.image.get_rect().size[1]
def draw_image(self):
screen.blit(self.image, [self.x, self.y])
def move_x(self):
self.x += self.dx
def move_y(self):
self.y += self.dy
def check_out_of_screen(self):
if self.x+self.width > WINDOW_WIDTH or self.x < 0:
self.x -= self.dx
elif self.y+self.height > WINDOW_HEIGHT or self.y < 0:
self.y -= self.dy
def check_crash(self,car):
if (self.x+self.width > car.x) and (self.x < car.x+car.width) and (self.y < car.y+car.height) and (self.y+self.height > car.y):
return True
else:
return False
def draw_main_menu():
draw_x = (WINDOW_WIDTH / 2) - 200
draw_y = WINDOW_HEIGHT / 2
image_intro = pygame.image.load('PyCar.Png')
screen.blit(image_intro, [draw_x, draw_y - 280])
font_40 = pygame.font.SysFont("FixedSys", 40, True, False)
font_30 = pygame.font.SysFont("FixedSys", 30, True, False)
text_title = font_40.render("Pycar: Racing Car Game", True, BLACK)
screen.blit(text_title, [draw_x, draw_y])
score_text = font_40.render("Score: " + str(score), True, WHITE)
screen.blit(score_text, [draw_x, draw_y + 70])
text_surface = font_30.render("UserName: " + user_text, True, WHITE)
screen.blit(text_surface, [draw_x, draw_y + 130])
for i in range(len(rank_score)):
text_rank = font_30.render(rank_name[i] + ": " + rank_score[i], True, BLACK)
screen.blit(text_rank, [draw_x, draw_y + (150 + (i * 20))])
text_start = font_30.render("Press Space Key to Start!", True, RED)
screen.blit(text_start, [draw_x, draw_y + 350])
pygame.display.flip()
def draw_score():
font_30 = pygame.font.SysFont("FixedSys", 30, True, False)
txt_score = font_30.render("Score: " +str(score), True, BLACK)
screen.blit(txt_score, [15,15])
if __name__=='__main__':
pygame.init()
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("PyCar: Racing Car Game")
clock = pygame.time.Clock()
## 게임 사운드
pygame.mixer.music.load('race.wav')
sound_crash = pygame.mixer.Sound('crash.wav')
sound_engine = pygame.mixer.Sound('engine.wav')
##사용자 레이싱 카 생성
player = Car(WINDOW_WIDTH / 2, (WINDOW_HEIGHT - 150), 0, 0)
player.load_own_image()
##컴퓨터 레이싱 카 생성
cars = []
car_count = 6
for i in range(car_count):
x = random.randrange(0, WINDOW_WIDTH-55)
y = random.randrange(-150, -50)
car = Car(x, random.randrange(-150, -50), 0, random.randint(5, 10))
car.load_image()
cars.append(car)
##### 왼쪽 나무
left_trees = []
left_trees_count = 9
for i in range(left_trees_count):
x = 0
y = 0
left_tree = Tree(x, y, 0, 10)
left_tree.load_image()
left_trees.append(left_tree)
#####
##### 오른쪽 나무
right_trees = []
right_trees_count = 9
for i in range(right_trees_count):
x = 0
y = 0
right_tree = Tree(x, y, 0, 10)
right_tree.load_image()
right_trees.append(right_tree)
#####
##도로 차선 생성
lanes = []
lane_width = 10
lane_height = 80
lane_margin = 20
lane_count = 30
lane_x = (WINDOW_WIDTH - lane_width) / 2
lane_y = -10
lane_left_x = (WINDOW_WIDTH - lane_width) / 6
lane_left_y = -10
lane_right_x = 995
lane_right_y = -10
for i in range(lane_count):
lanes.append([lane_x, lane_y])
lane_y += lane_height + lane_margin
lanes.append([lane_left_x, lane_left_y])
lane_left_y += lane_height + lane_margin
lanes.append([lane_right_x, lane_right_y])
lane_right_y += lane_height + lane_margin
score = 0
crash = True
game_on = True
while game_on:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_on = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_BACKSPACE:
user_text = user_text[:-1]
else:
user_text += event.unicode
#게임 다시 시작
if crash:
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
if user_text == ' ':
user_text = 'Guest'
rank_name.append(user_text)
crash = False
for i in range(car_count):
cars[i].x = random.randrange(left_trees[i].width-right_trees[i].width, WINDOW_WIDTH-cars[i].width-left_trees[i].width-right_trees[i].width)
cars[i].y = random.randrange(-150, -50)
cars[i].load_image()
#####
for i in range(left_trees_count):
left_trees[i].x = 10
left_trees[i].y = -20 + (i*100)
left_trees[i].load_image()
#####
#####
for i in range(right_trees_count):
right_trees[i].x = 1210
right_trees[i].y = -20 + (i*100)
right_trees[i].load_image()
#####
player.load_own_image()
player.x = WINDOW_WIDTH / 2
player.dx = 0
player.dy = 0
score = 0
pygame.mouse.set_visible(False)
sound_engine.play()
sleep(5)
pygame.mixer.music.play(-1)
if not crash:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
player.dx = 4
elif event.key == pygame.K_LEFT:
player.dx = -4
elif event.key == pygame.K_UP:
player.dy = -4
elif event.key == pygame.K_DOWN:
player.dy = 4
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
player.dx = 0
elif event.key == pygame.K_LEFT:
player.dx = 0
elif event.key == pygame.K_UP:
player.dy = 0
elif event.key == pygame.K_DOWN:
player.dy = 0
#GRAY로 화면 채우기
screen.fill(GRAY)
#게임 화면 출력
if not crash:
#도로 차선 이동
for i in range(lane_count):
pygame.draw.rect(screen, WHITE, [lanes[i][0], lanes[i][1], lane_width, lane_height])
lanes[i][1] += 10 #도로 차선 속도
if lanes[i][1] > WINDOW_HEIGHT:
lanes[i][1] = -40 - lane_height
#사용자 레이싱 카
player.draw_image()
player.move_x()
player.move_y()
player.check_out_of_screen()
#컴퓨터 레이싱 카
for i in range(car_count):
cars[i].draw_image()
cars[i].y += cars[i].dy
if cars[i].y > WINDOW_HEIGHT:
score +=10
cars[i].y = random.randrange(-150, -50)
cars[i].x = random.randrange(left_trees[i].width-right_trees[i].width, WINDOW_WIDTH-cars[i].width-left_trees[i].width-right_trees[i].width)
cars[i].dy = random.randint(4,9)
cars[i].load_image()
#####
for i in range(left_trees_count):
left_trees[i].draw_image()
left_trees[i].y += left_trees[i].dy
if left_trees[i].y > WINDOW_HEIGHT:
left_trees[i].y = 0
left_trees[i].x = 0
left_trees[i].dy = 10
left_trees[i].load_image()
#####
#####
for i in range(right_trees_count):
right_trees[i].draw_image()
right_trees[i].y += right_trees[i].dy
if right_trees[i].y > WINDOW_HEIGHT:
right_trees[i].y = 0
right_trees[i].x = 1210
right_trees[i].dy = 10
right_trees[i].load_image()
#####
#레이싱 카 충돌 사고 체크
for i in range(car_count):
if player.check_crash(cars[i]):
crash = True
pygame.mixer.music.stop()
sound_crash.play()
sleep(2)
pygame.mouse.set_visible(True)
rank_score.append(str(score))
user_text = ''
print(rank_name)
print(rank_score)
break
#draw_score()
#pygame.display.flip()
for i in range(left_trees_count):
if player.check_crash(left_trees[i]):
crash = True
pygame.mixer.music.stop()
sound_crash.play()
sleep(2)
pygame.mouse.set_visible(True)
rank_score.append(str(score))
user_text = ''
print(rank_name)
print(rank_score)
break
for i in range(right_trees_count):
if player.check_crash(right_trees[i]):
crash = True
pygame.mixer.music.stop()
sound_crash.play()
sleep(2)
pygame.mouse.set_visible(True)
rank_score.append(str(score))
user_text = ''
print(rank_name)
print(rank_score)
break
draw_score()
pygame.display.flip()
else:
draw_main_menu()
clock.tick(60)
pygame.quit()