import pygame
import sys
import math
import random
from pygame.locals import *
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 224, 0)
GREEN = (0, 255, 0) # 색 정의(초록색)
idx = 0 # 인덱스 변수
tmr = 0
se_crash = None
DATA_LR = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
3, 2, 1, 0, 2, 4, 2, 4, 2, 0, 0, 0, -2, -2,
-4, -4, -2, -1, 0, 0, 0, 0, 0, 0, 0]
DATA_UD = [0, 0, 1, 2, 3, 2, 1, 0, -2, -4, -4, 0, 0,
0, 0, 0, -1, -2, -3, -4, -3, -2, -1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, -3, 3, 0, -6, 6, 0]
CLEN = len(DATA_LR)
BOARD = 120
CMAX = BOARD * CLEN
curve = [0] * CMAX
updown = [0] * CMAX
object_left = [0] * CMAX
object_right = [0] * CMAX
CAR = 30
car_x = [0] * CAR
car_y = [0] * CAR
car_lr = [0] * CAR
car_spd = [0] * CAR
PLCAR_Y = 10
def make_course():
for i in range(CLEN):
lr1 = DATA_LR[i]
lr2 = DATA_LR[(i + 1) % CLEN]
ud1 = DATA_UD[i]
ud2 = DATA_UD[(i + 1) % CLEN]
for j in range(BOARD):
pos = j + BOARD * i
curve[pos] = lr1 * (BOARD - j) / BOARD + lr2 * j / BOARD
updown[pos] = ud1 * (BOARD - j) / BOARD + ud2 * j / BOARD
if j == 60:
object_right[pos] = 1
if i % 8 < 7:
if j % 12 == 0:
object_left[pos] = 2
else:
if j % 20 == 0:
object_left[pos] = 3
if j % 12 == 6:
object_left[pos] = 9
def draw_obj(bg, img, x, y, sc):
img_rz = pygame.transform.rotozoom(img, 0, sc)
w = img_rz.get_width()
h = img_rz.get_height()
bg.blit(img_rz, [x - w / 2, y - h])
def draw_shadow(bg, x, y, siz):
shadow = pygame.Surface([siz, siz / 4])
shadow.fill(RED)
shadow.set_colorkey(RED)
shadow.set_alpha(128)
pygame.draw.ellipse(shadow, BLACK, [0, 0, siz, siz / 4])
bg.blit(shadow, [x - siz / 2, y - siz / 4])
def init_car():
for i in range(1, CAR):
car_x[i] = random.randint(50, 750)
car_y[i] = random.randint(200, CMAX - 200)
car_lr[i] = 0
car_spd[i] = random.randint(100, 200)
car_x[0] = 400
car_y[i] = 0
car_lr[0] = 0
car_spd[0] = 0
def drive_car(key):
global idx, tmr # 전역 변수 선언
if key[K_LEFT] == 1:
if car_lr[0] > -3:
car_lr[0] -= 1
car_x[0] = car_x[0] + (car_lr[0] - 3) * car_spd[0] / 100 - 5
elif key[K_RIGHT] == 1:
if car_lr[0] < 3:
car_lr[0] += 1
car_x[0] = car_x[0] + (car_lr[0] + 3) * car_spd[0] / 100 + 5
else:
car_lr[0] = int(car_lr[0] * 0.9)
if key[K_a] == 1:
car_spd[0] += 3
elif key[K_z] == 1:
car_spd[0] -= 10
else:
car_spd[0] -= 0.25
if car_spd[0] < 0:
car_spd[0] = 0
if car_spd[0] > 320:
car_spd[0] = 320
car_x[0] -= car_spd[0] * curve[int(car_y[0] + PLCAR_Y) % CMAX] / 50
if car_x[0] < 0:
car_x[0] = 0
car_spd[0] *= 0.9
if car_x[0] > 800:
car_x[0] = 800
car_spd[0] *= 0.9
car_y[0] = car_y[0] + car_spd[0] / 100
if car_y[0] > CMAX - 1:
car_y[0] -= CMAX
idx = 3 # idx에 3 대입
tmr = 0 # tmr에 0 대입
def move_car(cs):
for i in range(cs, CAR):
if car_spd[i] < 100:
car_spd[i] += 3
if i == tmr % 120:
car_lr[i] += random.choice([-1, 0, 1])
if car_lr[i] < -3: car_lr[i] = -3
if car_lr[i] > 3: car_lr[i] = 3
car_x[i] = car_x[i] + car_lr[i] * car_spd[i] / 100
if car_x[i] < 50:
car_x[i] = 50
car_lr[i] = int(car_lr[i] * 0.9)
if car_x[i] > 750:
car_x[i] = 750
car_lr[i] = int(car_lr[i] * 0.9)
car_y[i] += car_spd[i] / 100
if car_y[i] > CMAX - 1:
car_y[i] -= CMAX
if idx == 2: # 레이스 중이면 히트 체크
cx = car_x[i] - car_x[0]
cy = car_y[i] - (car_y[0] + PLCAR_Y) % CMAX
if -100 <= cx and cx <= 100 and -10 <= cy and cy <= 10:
car_x[0] -= cx / 4
car_x[i] += cx / 4
car_spd[0], car_spd[i] = car_spd[i] * 0.3, car_spd[0] * 0.3
se_crash.play()
def draw_text(scrn, txt, x, y, col, fnt):
sur = fnt.render(txt, True, BLACK)
x -= sur.get_width() / 2
y -= sur.get_height() / 2
scrn.blit(sur, [x + 2, y + 2])
sur = fnt.render(txt, True, col)
scrn.blit(sur, [x, y])
def main():
global idx, tmr, se_crash # 전역 변수 선언
pygame.init()
pygame.display.set_caption("Python Racer")
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
fnt_s = pygame.font.Font(None, 40) # 폰트 객체 생성, 작은 크기 문자
fnt_m = pygame.font.Font(None, 50)
fnt_l = pygame.font.Font(None, 120) # 폰트 객체 생성, 큰 크기 문자
img_title = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/title.png').convert_alpha() # 타이틀 로고 이미지 로딩 변수
img_bg = pygame.image.load("Python_workspace/python_game/Chapter11/image_pr/bg.png").convert()
img_sea = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/sea.png').convert_alpha()
img_obj = [
None,
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/board.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yashi.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yacht.png').convert_alpha()
]
img_car = [
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car00.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car01.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car02.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car03.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car04.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car05.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car06.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car10.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car11.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car12.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car13.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car14.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car15.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car16.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car20.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car21.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car22.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car23.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car24.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car25.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car26.png').convert_alpha()
]
se_crash = pygame.mixer.Sound('Python_workspace/python_game/Chapter11/sound_pr/crash.ogg')
# 도로 판의 기본 형태 계산
BOARD_W = [0] * BOARD
BOARD_H = [0] * BOARD
BOARD_UD = [0] * BOARD
for i in range(BOARD):
BOARD_W[i] = 10 + (BOARD - i) * (BOARD - i) / 12
BOARD_H[i] = 3.4 * (BOARD - i) / BOARD
BOARD_UD[i] = 2 * math.sin(math.radians(i * 1.5))
make_course()
init_car()
vertical = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_F1:
screen = pygame.display.set_mode((800, 600), FULLSCREEN)
if event.key == K_F2 or event.key == K_ESCAPE:
screen = pygame.display.set_mode((800, 600))
tmr += 1
# 화면에 그릴 도로 X 좌표와 높낮이 계산
di = 0
ud = 0
board_x = [0] * BOARD
board_ud = [0] * BOARD
for i in range(BOARD):
di += curve[int(car_y[0] + i) % CMAX]
ud += updown[int(car_y[0] + i) % CMAX]
board_x[i] = 400 - BOARD_W[i] * car_x[0] / 800 + di / 2
board_ud[i] = ud / 30
horizon = 400 + int(ud / 3)
sy = horizon
vertical = vertical - int(car_spd[0] * di / 8000)
if vertical < 0:
vertical += 800
if vertical >= 800:
vertical -= 800
# 필드 그리기
screen.fill((0, 56, 255))
screen.blit(img_bg, [vertical - 800, horizon - 400])
screen.blit(img_bg, [vertical, horizon - 400])
screen.blit(img_sea, [board_x[BOARD - 1] - 780, sy])
# 그리기 데이터를 기초로 도로 그리기
for i in range(BOARD - 1, 0, -1):
ux = board_x[i]
uy = sy - BOARD_UD[i] * board_ud[i]
uw = BOARD_W[i]
sy = sy + BOARD_H[i] * (600 - horizon) / 200
bx = board_x[i - 1]
by = sy - BOARD_UD[i - 1] * board_ud[i - 1]
bw = BOARD_W[i - 1]
col = (160, 160, 160)
if int(car_y[0] + i) % CMAX == PLCAR_Y + 10: # 골 위치라면
col = (192, 0, 0) # 빨간색 선 값 대입
pygame.draw.polygon(screen, col, [[ux, uy], [ux + uw, uy], [bx + bw, by], [bx, by]])
if int(car_y[0] + i) % 10 <= 4:
pygame.draw.polygon(screen, YELLOW, [[ux, uy], [ux + uw * 0.02, uy], [bx + bw * 0.02, by], [bx, by]])
pygame.draw.polygon(screen, YELLOW, [[ux + uw * 0.98, uy], [ux + uw, uy], [bx + bw, by], [bx + bw * 0.98, by]])
if int(car_y[0] + i) % 20 <= 10:
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.24, uy], [ux + uw * 0.26, uy], [bx + bw * 0.26, by], [bx + bw * 0.24, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.49, uy], [ux + uw * 0.51, uy], [bx + bw * 0.51, by], [bx + bw * 0.49, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.74, uy], [ux + uw * 0.76, uy], [bx + bw * 0.76, by], [bx + bw * 0.74, by]])
scale = 1.5 * BOARD_W[i] / BOARD_W[0]
obj_l = object_left[int(car_y[0] + i) % CMAX]
if obj_l == 2:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.05, uy, scale)
if obj_l == 3:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.5, uy, scale)
if obj_l == 9:
screen.blit(img_sea, [ux - uw * 0.5 - 780, uy])
obj_r = object_right[int(car_y[0] + i) % CMAX]
if obj_r == 1:
draw_obj(screen, img_obj[obj_r], ux + uw * 1.3, uy, scale)
for c in range(1, CAR):
if int(car_y[c]) % CMAX == int(car_y[0] + i) % CMAX:
lr = int(4 * (car_x[0] - car_x[c]) / 800)
if lr < -3: lr = -3
if lr > 3: lr = 3
draw_obj(screen, img_car[(c % 3) * 7 + 3 + lr], ux + car_x[c] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0])
if i == PLCAR_Y:
draw_shadow(screen, ux + car_x[0] * BOARD_W[i] / 800, uy, 200 * BOARD_W[i] / BOARD_W[0])
draw_obj(screen, img_car[3 + car_lr[0]], ux + car_x[0] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0])
draw_text(screen, str(int(car_spd[0])) + 'km/h', 680, 30, RED, fnt_m)
key = pygame.key.get_pressed()
if idx == 0: # 타이틀 화면
screen.blit(img_title, [120, 120]) # 타이틀 로고 표시
draw_text(screen, '[A] Start game', 400, 320, WHITE, fnt_m)
move_car(0) # 모든 차량 이동
if key[K_a] != 0: # [A] 키를 눌렀다면
init_car() # 모든 차량 초기 위치로
idx = 1
tmr = 0
if idx == 1: # 카운트 다운
n = 3 - int(tmr / 60) # 카운트 다운 수 계산 대입
draw_text(screen, str(n), 400, 240, YELLOW, fnt_l) # 해당 수 표시
if tmr == 179: # tmr이 179가 되면
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/bgm.ogg') # BGM 로딩
pygame.mixer.music.play(-1) # 무한 반복 출력
idx = 2
tmr = 0
if idx == 2: # 레이싱 중
if tmr < 60: # 60 프레임 이내
draw_text(screen, 'Go!', 400, 240, RED, fnt_l) # GO! 표시
drive_car(key) # 플레이어 차량 조작
move_car(1) # COM 차량 이동
if idx == 3: # 골
if tmr == 1: # tmr 값이 1이면
pygame.mixer.music.stop() # BGM 중지
if tmr == 30: # tmr 값이 30이면
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/goal.ogg') # 징글 로딩
pygame.mixer.music.play(0) # 징글 1회 출력
draw_text(screen, 'GOAL!', 400, 240, GREEN, fnt_l) # GOAL! 표시
car_spd[0] = car_spd[0] * 0.96 # 플레이어 차량 속도 감속
car_y[0] = car_y[0] + car_spd[0] / 100 # 코스 위를 이동
move_car(1) # COM 차량 이동
if tmr > 60 * 8: # 8초가 경과하면 타이틀 화면으로 이동
idx = 0
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
타이틀 화면이 나오고 [A] 키를 누르면 카운트 다운을 하고 출발해서 한바퀴 돌아서 골로 들어오는 것으로 게임이 끝난다.
각 인덱스 값에 따른 처리는 다음과 같다.
idx 값 | 처리 |
---|---|
0 | 타이틀 화면 - [A] 키를 누르면 차량 관리 리스트 초기값 대입 후 idx에 1 대입 |
1 | 시작 전 카운트다운 수행 화면 - 3, 2, 1을 표시한 뒤, idx에 2 대입 |
2 | 레이스 중 화면(게임 플레이 중 화면) - 최초 2초간 'GO!' 표시 - 플레이어 차량을 움직이는 함수로 골인지 판단 후, 골이면 idx에 3 대입 |
3 | 골 화면 - 'GOAL!' 표시 - 약 8초간 대기한 후, idx에 0 대입, 타이틀 화면으로 복귀 |
col = (160, 160, 160)
if int(car_y[0] + i) % CMAX == PLCAR_Y + 10: # 골 위치라면
col = (192, 0, 0) # 빨간색 선 값 대입
pygame.draw.polygon(screen, col, [[ux, uy], [ux + uw, uy], [bx + bw, by], [bx, by]])
골 지점을 쉽게 알 수 있도록 그 위치에 빨간색 가로 선을 그리는 부분이다.
조건식에서 int(car_y[0] + i) % CMAX는 플레이어가 보는 도로를 구성하는 판의 번호이다. 도로는 끝점과 시작점을 연결해서 반복하고 있으므로 % CMAX를 이용한다. int(car_y[0] + i) % CMAX 값과 PLCAR_Y + 10번 판을 빨간색으로 함으로써 골 라인을 그릴 수 있다. PLCAR_Y + 10의 실제 값은 20이다.
import pygame
import sys
import math
import random
from pygame.locals import *
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 224, 0)
GREEN = (0, 255, 0)
idx = 0
tmr = 0
laps = 0 # 주행 바퀴 관리 변수
rec = 0 # 주행 시간 측정 변수
recbk = 0 # 랩 타임 계산용 변수
se_crash = None
DATA_LR = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
3, 2, 1, 0, 2, 4, 2, 4, 2, 0, 0, 0, -2, -2,
-4, -4, -2, -1, 0, 0, 0, 0, 0, 0, 0]
DATA_UD = [0, 0, 1, 2, 3, 2, 1, 0, -2, -4, -4, 0, 0,
0, 0, 0, -1, -2, -3, -4, -3, -2, -1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, -3, 3, 0, -6, 6, 0]
CLEN = len(DATA_LR)
BOARD = 120
CMAX = BOARD * CLEN
curve = [0] * CMAX
updown = [0] * CMAX
object_left = [0] * CMAX
object_right = [0] * CMAX
CAR = 30
car_x = [0] * CAR
car_y = [0] * CAR
car_lr = [0] * CAR
car_spd = [0] * CAR
PLCAR_Y = 10
LAPS = 3 # 골까지의 바퀴 수
laptime = ["0'00.00"] * LAPS # 랩 타임 표시용 리스트
def make_course():
for i in range(CLEN):
lr1 = DATA_LR[i]
lr2 = DATA_LR[(i + 1) % CLEN]
ud1 = DATA_UD[i]
ud2 = DATA_UD[(i + 1) % CLEN]
for j in range(BOARD):
pos = j + BOARD * i
curve[pos] = lr1 * (BOARD - j) / BOARD + lr2 * j / BOARD
updown[pos] = ud1 * (BOARD - j) / BOARD + ud2 * j / BOARD
if j == 60:
object_right[pos] = 1
if i % 8 < 7:
if j % 12 == 0:
object_left[pos] = 2
else:
if j % 20 == 0:
object_left[pos] = 3
if j % 12 == 6:
object_left[pos] = 9
def time_str(val): # **'**.** 시간 문자 생성 함수
sec = int(val) # 인수를 초 단위 정수로 변환해 sec에 대입
ms = int((val - sec) * 100) # 소수점 이하 값을 ms에 대입
mi = int(sec / 60) # 분을 mi에 대입
return "{}'{:02}.{:02}".format(mi, sec % 60, ms) # **'**.** 문자열 반환
def draw_obj(bg, img, x, y, sc):
img_rz = pygame.transform.rotozoom(img, 0, sc)
w = img_rz.get_width()
h = img_rz.get_height()
bg.blit(img_rz, [x - w / 2, y - h])
def draw_shadow(bg, x, y, siz):
shadow = pygame.Surface([siz, siz / 4])
shadow.fill(RED)
shadow.set_colorkey(RED)
shadow.set_alpha(128)
pygame.draw.ellipse(shadow, BLACK, [0, 0, siz, siz / 4])
bg.blit(shadow, [x - siz / 2, y - siz / 4])
def init_car():
for i in range(1, CAR):
car_x[i] = random.randint(50, 750)
car_y[i] = random.randint(200, CMAX - 200)
car_lr[i] = 0
car_spd[i] = random.randint(100, 200)
car_x[0] = 400
car_y[i] = 0
car_lr[0] = 0
car_spd[0] = 0
def drive_car(key):
global idx, tmr, laps, recbk # 전역 변수 선언
if key[K_LEFT] == 1:
if car_lr[0] > -3:
car_lr[0] -= 1
car_x[0] = car_x[0] + (car_lr[0] - 3) * car_spd[0] / 100 - 5
elif key[K_RIGHT] == 1:
if car_lr[0] < 3:
car_lr[0] += 1
car_x[0] = car_x[0] + (car_lr[0] + 3) * car_spd[0] / 100 + 5
else:
car_lr[0] = int(car_lr[0] * 0.9)
if key[K_a] == 1:
car_spd[0] += 3
elif key[K_z] == 1:
car_spd[0] -= 10
else:
car_spd[0] -= 0.25
if car_spd[0] < 0:
car_spd[0] = 0
if car_spd[0] > 320:
car_spd[0] = 320
car_x[0] -= car_spd[0] * curve[int(car_y[0] + PLCAR_Y) % CMAX] / 50
if car_x[0] < 0:
car_x[0] = 0
car_spd[0] *= 0.9
if car_x[0] > 800:
car_x[0] = 800
car_spd[0] *= 0.9
car_y[0] = car_y[0] + car_spd[0] / 100
if car_y[0] > CMAX - 1:
car_y[0] -= CMAX
laptime[laps] = time_str(rec - recbk) # 랩 타임 계산 후 대입
recbk = rec # 현재 타임 저장
laps += 1 # 완주 횟수 1 증가
if laps == LAPS: # 완주 횟수가 LAPS와 같다면
idx = 3 # idx에 3 대입
tmr = 0 # tmr에 0 대입
def move_car(cs):
for i in range(cs, CAR):
if car_spd[i] < 100:
car_spd[i] += 3
if i == tmr % 120:
car_lr[i] += random.choice([-1, 0, 1])
if car_lr[i] < -3: car_lr[i] = -3
if car_lr[i] > 3: car_lr[i] = 3
car_x[i] = car_x[i] + car_lr[i] * car_spd[i] / 100
if car_x[i] < 50:
car_x[i] = 50
car_lr[i] = int(car_lr[i] * 0.9)
if car_x[i] > 750:
car_x[i] = 750
car_lr[i] = int(car_lr[i] * 0.9)
car_y[i] += car_spd[i] / 100
if car_y[i] > CMAX - 1:
car_y[i] -= CMAX
if idx == 2:
cx = car_x[i] - car_x[0]
cy = car_y[i] - (car_y[0] + PLCAR_Y) % CMAX
if -100 <= cx and cx <= 100 and -10 <= cy and cy <= 10:
car_x[0] -= cx / 4
car_x[i] += cx / 4
car_spd[0], car_spd[i] = car_spd[i] * 0.3, car_spd[0] * 0.3
se_crash.play()
def draw_text(scrn, txt, x, y, col, fnt):
sur = fnt.render(txt, True, BLACK)
x -= sur.get_width() / 2
y -= sur.get_height() / 2
scrn.blit(sur, [x + 2, y + 2])
sur = fnt.render(txt, True, col)
scrn.blit(sur, [x, y])
def main():
global idx, tmr, laps, rec, recbk, se_crash # 전역 변수 선언
pygame.init()
pygame.display.set_caption("Python Racer")
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
fnt_s = pygame.font.Font(None, 40)
fnt_m = pygame.font.Font(None, 50)
fnt_l = pygame.font.Font(None, 120)
img_title = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/title.png').convert_alpha()
img_bg = pygame.image.load("Python_workspace/python_game/Chapter11/image_pr/bg.png").convert()
img_sea = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/sea.png').convert_alpha()
img_obj = [
None,
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/board.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yashi.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yacht.png').convert_alpha()
]
img_car = [
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car00.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car01.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car02.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car03.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car04.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car05.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car06.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car10.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car11.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car12.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car13.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car14.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car15.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car16.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car20.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car21.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car22.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car23.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car24.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car25.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car26.png').convert_alpha()
]
se_crash = pygame.mixer.Sound('Python_workspace/python_game/Chapter11/sound_pr/crash.ogg')
# 도로 판의 기본 형태 계산
BOARD_W = [0] * BOARD
BOARD_H = [0] * BOARD
BOARD_UD = [0] * BOARD
for i in range(BOARD):
BOARD_W[i] = 10 + (BOARD - i) * (BOARD - i) / 12
BOARD_H[i] = 3.4 * (BOARD - i) / BOARD
BOARD_UD[i] = 2 * math.sin(math.radians(i * 1.5))
make_course()
init_car()
vertical = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_F1:
screen = pygame.display.set_mode((800, 600), FULLSCREEN)
if event.key == K_F2 or event.key == K_ESCAPE:
screen = pygame.display.set_mode((800, 600))
tmr += 1
# 화면에 그릴 도로 X 좌표와 높낮이 계산
di = 0
ud = 0
board_x = [0] * BOARD
board_ud = [0] * BOARD
for i in range(BOARD):
di += curve[int(car_y[0] + i) % CMAX]
ud += updown[int(car_y[0] + i) % CMAX]
board_x[i] = 400 - BOARD_W[i] * car_x[0] / 800 + di / 2
board_ud[i] = ud / 30
horizon = 400 + int(ud / 3)
sy = horizon
vertical = vertical - int(car_spd[0] * di / 8000)
if vertical < 0:
vertical += 800
if vertical >= 800:
vertical -= 800
# 필드 그리기
screen.fill((0, 56, 255))
screen.blit(img_bg, [vertical - 800, horizon - 400])
screen.blit(img_bg, [vertical, horizon - 400])
screen.blit(img_sea, [board_x[BOARD - 1] - 780, sy])
# 그리기 데이터를 기초로 도로 그리기
for i in range(BOARD - 1, 0, -1):
ux = board_x[i]
uy = sy - BOARD_UD[i] * board_ud[i]
uw = BOARD_W[i]
sy = sy + BOARD_H[i] * (600 - horizon) / 200
bx = board_x[i - 1]
by = sy - BOARD_UD[i - 1] * board_ud[i - 1]
bw = BOARD_W[i - 1]
col = (160, 160, 160)
if int(car_y[0] + i) % CMAX == PLCAR_Y + 10:
col = (192, 0, 0)
pygame.draw.polygon(screen, col, [[ux, uy], [ux + uw, uy], [bx + bw, by], [bx, by]])
if int(car_y[0] + i) % 10 <= 4:
pygame.draw.polygon(screen, YELLOW, [[ux, uy], [ux + uw * 0.02, uy], [bx + bw * 0.02, by], [bx, by]])
pygame.draw.polygon(screen, YELLOW, [[ux + uw * 0.98, uy], [ux + uw, uy], [bx + bw, by], [bx + bw * 0.98, by]])
if int(car_y[0] + i) % 20 <= 10:
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.24, uy], [ux + uw * 0.26, uy], [bx + bw * 0.26, by], [bx + bw * 0.24, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.49, uy], [ux + uw * 0.51, uy], [bx + bw * 0.51, by], [bx + bw * 0.49, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.74, uy], [ux + uw * 0.76, uy], [bx + bw * 0.76, by], [bx + bw * 0.74, by]])
scale = 1.5 * BOARD_W[i] / BOARD_W[0]
obj_l = object_left[int(car_y[0] + i) % CMAX]
if obj_l == 2:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.05, uy, scale)
if obj_l == 3:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.5, uy, scale)
if obj_l == 9:
screen.blit(img_sea, [ux - uw * 0.5 - 780, uy])
obj_r = object_right[int(car_y[0] + i) % CMAX]
if obj_r == 1:
draw_obj(screen, img_obj[obj_r], ux + uw * 1.3, uy, scale)
for c in range(1, CAR):
if int(car_y[c]) % CMAX == int(car_y[0] + i) % CMAX:
lr = int(4 * (car_x[0] - car_x[c]) / 800)
if lr < -3: lr = -3
if lr > 3: lr = 3
draw_obj(screen, img_car[(c % 3) * 7 + 3 + lr], ux + car_x[c] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0])
if i == PLCAR_Y:
draw_shadow(screen, ux + car_x[0] * BOARD_W[i] / 800, uy, 200 * BOARD_W[i] / BOARD_W[0])
draw_obj(screen, img_car[3 + car_lr[0]], ux + car_x[0] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0])
draw_text(screen, str(int(car_spd[0])) + 'km/h', 680, 30, RED, fnt_m)
draw_text(screen, 'lap {}/{}'.format(laps, LAPS), 100, 30, WHITE, fnt_m) # 주행 횟수 표시
draw_text(screen, 'time ' + time_str(rec), 100, 80, GREEN, fnt_s) # 시간 표시
for i in range(LAPS):
draw_text(screen, laptime[i], 80, 130 + 40 * i, YELLOW, fnt_s) # 랩 타임 표시
key = pygame.key.get_pressed()
if idx == 0: # 타이틀 화면
screen.blit(img_title, [120, 120])
draw_text(screen, '[A] Start game', 400, 320, WHITE, fnt_m)
move_car(0)
if key[K_a] != 0:
init_car()
idx = 1
tmr = 0
laps = 0 # 주행 횟수에 0 대입
rec = 0 # 주행 시간에 0 대입
recbk = 0 # 랩 타임 계산 변수 0 대입
for i in range(LAPS):
laptime[i] = "0'00.00" # 랩 타임 "0'00.00" 초기화
if idx == 1: # 카운트 다운
n = 3 - int(tmr / 60)
draw_text(screen, str(n), 400, 240, YELLOW, fnt_l)
if tmr == 179:
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/bgm.ogg')
pygame.mixer.music.play(-1)
idx = 2
tmr = 0
if idx == 2: # 레이싱 중
if tmr < 60:
draw_text(screen, 'Go!', 400, 240, RED, fnt_l)
rec = rec + 1 / 60 # 주행 시간 카운트
drive_car(key)
move_car(1)
if idx == 3: # 골
if tmr == 1:
pygame.mixer.music.stop()
if tmr == 30:
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/goal.ogg')
pygame.mixer.music.play(0)
draw_text(screen, 'GOAL!', 400, 240, GREEN, fnt_l)
car_spd[0] = car_spd[0] * 0.96
car_y[0] = car_y[0] + car_spd[0] / 100
move_car(1)
if tmr > 60 * 8:
idx = 0
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
화면 왼쪽 위에 랩 수, 현재 시간, 랩 타임을 표시한다.
def time_str(val): # **'**.** 시간 문자 생성 함수
sec = int(val) # 인수를 초 단위 정수로 변환해 sec에 대입
ms = int((val - sec) * 100) # 소수점 이하 값을 ms에 대입
mi = int(sec / 60) # 분을 mi에 대입
return "{}'{:02}.{:02}".format(mi, sec % 60, ms) # **'**.** 문자열 반환
time_str() 함수는 시간 값에서 문자열을 만드는 함수다. 초를 정수 부분과 소수 부분으로 나눠(변수 sec와 ms에 대입) 초를 분 값(변수 mi에 대입)으로 계산한 뒤 문자열을 반환한다.
시간 측정은 변수 rec, recbk로 수행하고, 리스트 laptime으로 랩 타임을 관리한다.
rec = rec + 1 / 60 # 주행 시간 카운트
이 프로그램은 초당 60프레임을 처리하므로 1/60초를 더하는 것이다.
if car_y[0] > CMAX - 1:
car_y[0] -= CMAX
laptime[laps] = time_str(rec - recbk) # 랩 타임 계산 후 대입
recbk = rec # 현재 타임 저장
laps += 1 # 완주 횟수 1 증가
if laps == LAPS: # 완주 횟수가 LAPS와 같다면
idx = 3 # idx에 3 대입
tmr = 0 # tmr에 0 대입
drive_car() 함수의 일부다. 플레이어 차량은 한 바퀴를 돌 때마다 랩 타임을 기록하고 세 바퀴를 돌면 완주하도록 한다.
플레이어 차량의 코스 상 위치를 시작저믕로 되돌리는 타이밍에서 laptime[laps] = time_str(rec - recbk)를 계산해 그 바퀴의 랩 타임을 리스트에 대입한다. 그리고 다음 랩 타임을 측정하기 위해 recbk = rec으로 recbk에 해당 시간을 대입한다. 이렇게 한 바퀴를 돌 때마다 시간을 측정한다. 또한, 몇 바퀴를 주행했는지 센 뒤, 세 바퀴를 돌았다면 완주 처리를 실행한다.
import pygame
import sys
import math
import random
from pygame.locals import *
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 224, 0)
GREEN = (0, 255, 0)
idx = 0
tmr = 0
laps = 0
rec = 0
recbk = 0
se_crash = None
mycar = 0 # 차종 선택 관리 변수
DATA_LR = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
3, 2, 1, 0, 2, 4, 2, 4, 2, 0, 0, 0, -2, -2,
-4, -4, -2, -1, 0, 0, 0, 0, 0, 0, 0]
DATA_UD = [0, 0, 1, 2, 3, 2, 1, 0, -2, -4, -4, 0, 0,
0, 0, 0, -1, -2, -3, -4, -3, -2, -1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, -3, 3, 0, -6, 6, 0]
CLEN = len(DATA_LR)
BOARD = 120
CMAX = BOARD * CLEN
curve = [0] * CMAX
updown = [0] * CMAX
object_left = [0] * CMAX
object_right = [0] * CMAX
CAR = 30
car_x = [0] * CAR
car_y = [0] * CAR
car_lr = [0] * CAR
car_spd = [0] * CAR
PLCAR_Y = 10
LAPS = 3
laptime = ["0'00.00"] * LAPS
def make_course():
for i in range(CLEN):
lr1 = DATA_LR[i]
lr2 = DATA_LR[(i + 1) % CLEN]
ud1 = DATA_UD[i]
ud2 = DATA_UD[(i + 1) % CLEN]
for j in range(BOARD):
pos = j + BOARD * i
curve[pos] = lr1 * (BOARD - j) / BOARD + lr2 * j / BOARD
updown[pos] = ud1 * (BOARD - j) / BOARD + ud2 * j / BOARD
if j == 60:
object_right[pos] = 1
if i % 8 < 7:
if j % 12 == 0:
object_left[pos] = 2
else:
if j % 20 == 0:
object_left[pos] = 3
if j % 12 == 6:
object_left[pos] = 9
def time_str(val):
sec = int(val)
ms = int((val - sec) * 100)
mi = int(sec / 60)
return "{}'{:02}.{:02}".format(mi, sec % 60, ms)
def draw_obj(bg, img, x, y, sc):
img_rz = pygame.transform.rotozoom(img, 0, sc)
w = img_rz.get_width()
h = img_rz.get_height()
bg.blit(img_rz, [x - w / 2, y - h])
def draw_shadow(bg, x, y, siz):
shadow = pygame.Surface([siz, siz / 4])
shadow.fill(RED)
shadow.set_colorkey(RED)
shadow.set_alpha(128)
pygame.draw.ellipse(shadow, BLACK, [0, 0, siz, siz / 4])
bg.blit(shadow, [x - siz / 2, y - siz / 4])
def init_car():
for i in range(1, CAR):
car_x[i] = random.randint(50, 750)
car_y[i] = random.randint(200, CMAX - 200)
car_lr[i] = 0
car_spd[i] = random.randint(100, 200)
car_x[0] = 400
car_y[i] = 0
car_lr[0] = 0
car_spd[0] = 0
def drive_car(key):
global idx, tmr, laps, recbk
if key[K_LEFT] == 1:
if car_lr[0] > -3:
car_lr[0] -= 1
car_x[0] = car_x[0] + (car_lr[0] - 3) * car_spd[0] / 100 - 5
elif key[K_RIGHT] == 1:
if car_lr[0] < 3:
car_lr[0] += 1
car_x[0] = car_x[0] + (car_lr[0] + 3) * car_spd[0] / 100 + 5
else:
car_lr[0] = int(car_lr[0] * 0.9)
if key[K_a] == 1:
car_spd[0] += 3
elif key[K_z] == 1:
car_spd[0] -= 10
else:
car_spd[0] -= 0.25
if car_spd[0] < 0:
car_spd[0] = 0
if car_spd[0] > 320:
car_spd[0] = 320
car_x[0] -= car_spd[0] * curve[int(car_y[0] + PLCAR_Y) % CMAX] / 50
if car_x[0] < 0:
car_x[0] = 0
car_spd[0] *= 0.9
if car_x[0] > 800:
car_x[0] = 800
car_spd[0] *= 0.9
car_y[0] = car_y[0] + car_spd[0] / 100
if car_y[0] > CMAX - 1:
car_y[0] -= CMAX
laptime[laps] = time_str(rec - recbk)
recbk = rec
laps += 1
if laps == LAPS:
idx = 3
tmr = 0
def move_car(cs):
for i in range(cs, CAR):
if car_spd[i] < 100:
car_spd[i] += 3
if i == tmr % 120:
car_lr[i] += random.choice([-1, 0, 1])
if car_lr[i] < -3: car_lr[i] = -3
if car_lr[i] > 3: car_lr[i] = 3
car_x[i] = car_x[i] + car_lr[i] * car_spd[i] / 100
if car_x[i] < 50:
car_x[i] = 50
car_lr[i] = int(car_lr[i] * 0.9)
if car_x[i] > 750:
car_x[i] = 750
car_lr[i] = int(car_lr[i] * 0.9)
car_y[i] += car_spd[i] / 100
if car_y[i] > CMAX - 1:
car_y[i] -= CMAX
if idx == 2:
cx = car_x[i] - car_x[0]
cy = car_y[i] - (car_y[0] + PLCAR_Y) % CMAX
if -100 <= cx and cx <= 100 and -10 <= cy and cy <= 10:
car_x[0] -= cx / 4
car_x[i] += cx / 4
car_spd[0], car_spd[i] = car_spd[i] * 0.3, car_spd[0] * 0.3
se_crash.play()
def draw_text(scrn, txt, x, y, col, fnt):
sur = fnt.render(txt, True, BLACK)
x -= sur.get_width() / 2
y -= sur.get_height() / 2
scrn.blit(sur, [x + 2, y + 2])
sur = fnt.render(txt, True, col)
scrn.blit(sur, [x, y])
def main():
global idx, tmr, laps, rec, recbk, se_crash, mycar # 전역 변수 선언
pygame.init()
pygame.display.set_caption("Python Racer")
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
fnt_s = pygame.font.Font(None, 40)
fnt_m = pygame.font.Font(None, 50)
fnt_l = pygame.font.Font(None, 120)
img_title = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/title.png').convert_alpha()
img_bg = pygame.image.load("Python_workspace/python_game/Chapter11/image_pr/bg.png").convert()
img_sea = pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/sea.png').convert_alpha()
img_obj = [
None,
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/board.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yashi.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/yacht.png').convert_alpha()
]
img_car = [
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car00.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car01.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car02.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car03.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car04.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car05.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car06.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car10.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car11.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car12.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car13.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car14.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car15.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car16.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car20.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car21.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car22.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car23.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car24.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car25.png').convert_alpha(),
pygame.image.load('Python_workspace/python_game/Chapter11/image_pr/car26.png').convert_alpha()
]
se_crash = pygame.mixer.Sound('Python_workspace/python_game/Chapter11/sound_pr/crash.ogg')
# 도로 판의 기본 형태 계산
BOARD_W = [0] * BOARD
BOARD_H = [0] * BOARD
BOARD_UD = [0] * BOARD
for i in range(BOARD):
BOARD_W[i] = 10 + (BOARD - i) * (BOARD - i) / 12
BOARD_H[i] = 3.4 * (BOARD - i) / BOARD
BOARD_UD[i] = 2 * math.sin(math.radians(i * 1.5))
make_course()
init_car()
vertical = 0
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_F1:
screen = pygame.display.set_mode((800, 600), FULLSCREEN)
if event.key == K_F2 or event.key == K_ESCAPE:
screen = pygame.display.set_mode((800, 600))
tmr += 1
# 화면에 그릴 도로 X 좌표와 높낮이 계산
di = 0
ud = 0
board_x = [0] * BOARD
board_ud = [0] * BOARD
for i in range(BOARD):
di += curve[int(car_y[0] + i) % CMAX]
ud += updown[int(car_y[0] + i) % CMAX]
board_x[i] = 400 - BOARD_W[i] * car_x[0] / 800 + di / 2
board_ud[i] = ud / 30
horizon = 400 + int(ud / 3)
sy = horizon
vertical = vertical - int(car_spd[0] * di / 8000)
if vertical < 0:
vertical += 800
if vertical >= 800:
vertical -= 800
# 필드 그리기
screen.fill((0, 56, 255))
screen.blit(img_bg, [vertical - 800, horizon - 400])
screen.blit(img_bg, [vertical, horizon - 400])
screen.blit(img_sea, [board_x[BOARD - 1] - 780, sy])
# 그리기 데이터를 기초로 도로 그리기
for i in range(BOARD - 1, 0, -1):
ux = board_x[i]
uy = sy - BOARD_UD[i] * board_ud[i]
uw = BOARD_W[i]
sy = sy + BOARD_H[i] * (600 - horizon) / 200
bx = board_x[i - 1]
by = sy - BOARD_UD[i - 1] * board_ud[i - 1]
bw = BOARD_W[i - 1]
col = (160, 160, 160)
if int(car_y[0] + i) % CMAX == PLCAR_Y + 10:
col = (192, 0, 0)
pygame.draw.polygon(screen, col, [[ux, uy], [ux + uw, uy], [bx + bw, by], [bx, by]])
if int(car_y[0] + i) % 10 <= 4:
pygame.draw.polygon(screen, YELLOW, [[ux, uy], [ux + uw * 0.02, uy], [bx + bw * 0.02, by], [bx, by]])
pygame.draw.polygon(screen, YELLOW, [[ux + uw * 0.98, uy], [ux + uw, uy], [bx + bw, by], [bx + bw * 0.98, by]])
if int(car_y[0] + i) % 20 <= 10:
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.24, uy], [ux + uw * 0.26, uy], [bx + bw * 0.26, by], [bx + bw * 0.24, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.49, uy], [ux + uw * 0.51, uy], [bx + bw * 0.51, by], [bx + bw * 0.49, by]])
pygame.draw.polygon(screen, WHITE, [[ux + uw * 0.74, uy], [ux + uw * 0.76, uy], [bx + bw * 0.76, by], [bx + bw * 0.74, by]])
scale = 1.5 * BOARD_W[i] / BOARD_W[0]
obj_l = object_left[int(car_y[0] + i) % CMAX]
if obj_l == 2:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.05, uy, scale)
if obj_l == 3:
draw_obj(screen, img_obj[obj_l], ux - uw * 0.5, uy, scale)
if obj_l == 9:
screen.blit(img_sea, [ux - uw * 0.5 - 780, uy])
obj_r = object_right[int(car_y[0] + i) % CMAX]
if obj_r == 1:
draw_obj(screen, img_obj[obj_r], ux + uw * 1.3, uy, scale)
for c in range(1, CAR):
if int(car_y[c]) % CMAX == int(car_y[0] + i) % CMAX:
lr = int(4 * (car_x[0] - car_x[c]) / 800)
if lr < -3: lr = -3
if lr > 3: lr = 3
draw_obj(screen, img_car[(c % 3) * 7 + 3 + lr], ux + car_x[c] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0])
if i == PLCAR_Y:
draw_shadow(screen, ux + car_x[0] * BOARD_W[i] / 800, uy, 200 * BOARD_W[i] / BOARD_W[0])
draw_obj(screen, img_car[3 + car_lr[0] + mycar * 7], ux + car_x[0] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0]) # 플레이어 차량 그리기
draw_text(screen, str(int(car_spd[0])) + 'km/h', 680, 30, RED, fnt_m)
draw_text(screen, 'lap {}/{}'.format(laps, LAPS), 100, 30, WHITE, fnt_m)
draw_text(screen, 'time ' + time_str(rec), 100, 80, GREEN, fnt_s)
for i in range(LAPS):
draw_text(screen, laptime[i], 80, 130 + 40 * i, YELLOW, fnt_s)
key = pygame.key.get_pressed()
if idx == 0: # 타이틀 화면
screen.blit(img_title, [120, 120])
draw_text(screen, '[A] Start game', 400, 320, WHITE, fnt_m)
draw_text(screen, '[S] Select your car', 400, 400, WHITE, fnt_m) # [S] Select your car 표시
move_car(0)
if key[K_a] != 0:
init_car()
idx = 1
tmr = 0
laps = 0
rec = 0
recbk = 0
for i in range(LAPS):
laptime[i] = "0'00.00"
if key[K_s] != 0: # [S] 키를 눌렀다면
idx = 4 # idx에 4 대입, 차종 선택
if idx == 1: # 카운트 다운
n = 3 - int(tmr / 60)
draw_text(screen, str(n), 400, 240, YELLOW, fnt_l)
if tmr == 179:
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/bgm.ogg')
pygame.mixer.music.play(-1)
idx = 2
tmr = 0
if idx == 2: # 레이싱 중
if tmr < 60:
draw_text(screen, 'Go!', 400, 240, RED, fnt_l)
rec = rec + 1 / 60
drive_car(key)
move_car(1)
if idx == 3: # 골
if tmr == 1:
pygame.mixer.music.stop()
if tmr == 30:
pygame.mixer.music.load('Python_workspace/python_game/Chapter11/sound_pr/goal.ogg')
pygame.mixer.music.play(0)
draw_text(screen, 'GOAL!', 400, 240, GREEN, fnt_l)
car_spd[0] = car_spd[0] * 0.96
car_y[0] = car_y[0] + car_spd[0] / 100
move_car(1)
if tmr > 60 * 8:
idx = 0
if idx == 4: # 차종 선택
move_car(0) # 모든 차량 이동
draw_text(screen, 'Select your car', 400, 160, WHITE, fnt_m) # 'Select your car' 표시
for i in range(3):
x = 160 + 240 * i # 선택용 사각형 X 좌표 대입
y = 300 # 선택용 사각형 Y 좌표 대입
col = BLACK # col에 검은색 대입
if i == mycar: # 선택한 차량이라면
col = (0, 128, 255) # col에 밝은 파란색 대입
pygame.draw.rect(screen, col, [x - 100, y - 80, 200, 160]) # 사각형 테두리 색상 그림
draw_text(screen, '[' + str(i + 1) + ']', x, y - 50, WHITE, fnt_m) # [n]의 문자 표시
screen.blit(img_car[3 + i * 7], [x - 100, y - 20]) # 차량 표시
draw_text(screen, '[Enter] OK!', 400, 440, GREEN, fnt_m) # [Enter] OK! 출력
if key[K_1] == 1: # [1] 키를 눌렀다면
mycar = 0 # mycar에 0 대입(빨간색 차)
if key[K_2] == 1: # [2] 키를 눌렀다면
mycar = 1 # mycar에 1 대입(파란색 차)
if key[K_3] == 1: # [3] 키를 눌렀다면
mycar = 2 # mycar에 2 대입(노란색 차)
if key[K_RETURN] == 1: # [Enter] 키를 눌렀다면
idx = 0 # idx에 0 대입, 타이틀 화면 복귀
pygame.display.update()
clock.tick(60)
if __name__ == '__main__':
main()
차량 선택은 main() 함수내에서 처리한다.
if idx == 4: # 차종 선택
move_car(0) # 모든 차량 이동
draw_text(screen, 'Select your car', 400, 160, WHITE, fnt_m) # 'Select your car' 표시
for i in range(3):
x = 160 + 240 * i # 선택용 사각형 X 좌표 대입
y = 300 # 선택용 사각형 Y 좌표 대입
col = BLACK # col에 검은색 대입
if i == mycar: # 선택한 차량이라면
col = (0, 128, 255) # col에 밝은 파란색 대입
pygame.draw.rect(screen, col, [x - 100, y - 80, 200, 160]) # 사각형 테두리 색상 그림
draw_text(screen, '[' + str(i + 1) + ']', x, y - 50, WHITE, fnt_m) # [n]의 문자 표시
screen.blit(img_car[3 + i * 7], [x - 100, y - 20]) # 차량 표시
draw_text(screen, '[Enter] OK!', 400, 440, GREEN, fnt_m) # [Enter] OK! 출력
if key[K_1] == 1: # [1] 키를 눌렀다면
mycar = 0 # mycar에 0 대입(빨간색 차)
if key[K_2] == 1: # [2] 키를 눌렀다면
mycar = 1 # mycar에 1 대입(파란색 차)
if key[K_3] == 1: # [3] 키를 눌렀다면
mycar = 2 # mycar에 2 대입(노란색 차)
if key[K_RETURN] == 1: # [Enter] 키를 눌렀다면
idx = 0 # idx에 0 대입, 타이틀 화면 복귀
[1], [2], [3]키를 누르면 mycar 값이 변경된다.
draw_obj(screen, img_car[3 + car_lr[0] + mycar * 7], ux + car_x[0] * BOARD_W[i] / 800, uy, 0.05 + BOARD_W[i] / BOARD_W[0]) # 플레이어 차량 그리기
플레이어 차량은 이와 같이 mycar 값을 사용해 차 이미지 번호를 바꾸어서 차량 종류를 변경한다.