テキストプログラミングコース学習内容

Python学習で作成する主なプログラム

テキストプログラミングコースの授業を通じて作成するプログラム例を紹介します。

テクノロではUnityなどのゲームエンジンは使用せず、プログラミング言語で一から作ることにこだわっています。ゲームエンジンを使えば、プログラミングせず、手軽にゲームが作れます。しかしそれでは真の技術力は身に付きません。

プログラミングを基礎から学び、その上でゲームが作れるようになった人にはかないません。また、アルゴリズムを深く理解することで論理的思考力が鍛えられ、数学力が飛躍的に上がります。

さらにゲーム開発には中学や高校で習う数学の方程式、数理モデルが山のように出てきます。
学校で習った算数や数学を実生活で活かす体験を通じて、算数・数学を武器にして欲しいです。

初級レベル(タートルグラフィックス)

Pythonで記述するコード
from turtle import *
shape("turtle")
col = ["orange","limegreen","gold","plum","tomato"]
for i in range(len(col)):
color(col[i])
circle(80)
left(72)
done()


テキストを見る



入力した頂点の数に応じた図形を描くプログラム
Pythonで記述するコード
n = int(input("正多角形の頂点の数を入力してね。"))
x = int(180-(n-2)*180/n)

from turtle import *
shape("turtle")

for i in range(n):
    forward(100)
    left(x)
    
done()


テキストを見る

初級レベル(CUIで作るゲームシリーズ)

Pythonで記述するコード
問題 = [
"サザエさんの旦那さんの名前は?",
"カツオの妹の名前は?",
"サザエさんが飼っているネコの名前は"]
答え = ["マスオ", "ワカメ", "タマ"]
スコア= 0
for i in range(3):
    print(問題[i])
    回答 = input()
    if 回答 == 答え[i]:
        print("正解です")
        スコア = 1 + スコア 
    else:
        print("不正解です")

print("あなたの得点は",スコア,"点です。")


テキストを見る



Pythonで記述するコード
import random
プレイヤ = 1
CPU = 1
def 盤面():
    print("□"*(プレイヤ-1) + "P" + "□"*(30-プレイヤ)+"ゴール")
    print("□"*(CPU-1) + "C" + "□"*(30-CPU)+"ゴール")

盤面()
print("すごろく、スタート")
while True:
    input("Enterを押すとコマが進みます")
    プレイヤ = プレイヤ + random.randint(1,6)
    if プレイヤ >30:
        プレイヤ = 30
    盤面()
    if プレイヤ == 30:
        print("あなたの勝ちです!")
        break
    input("Enterを押すとコマが進みます")
    CPU = CPU + random.randint(1,6)
    if CPU > 30:
        CPU = 30
    盤面()
    if CPU ==30:
        print("コンピュータの勝ちです!")
        break


テキストを見る



虫食いアルファベットゲームプログラム
Pythonで記述するコード
import random
import datetime
アルファベット = [
"A","B","C","D","E","F","G"
"H","I","J","K","L","M","N"
"O","P","Q","R","S","T","U"
"V","W","X","Y","Z"
    ]
抜けている文字 = random.choice(アルファベット)
文字 = ""
for i in アルファベット:
    if i != 抜けている文字:
        文字 = 文字 + i
print(文字)
時間 = datetime.datetime.now()
答え = input("抜けているアルファベットは?")
if 答え == 抜けている文字:
    print("正解です")
    タイム = datetime.datetime.now()
    print(str((タイム-時間).seconds)+"秒かかりました")
else:
    print("違います")


テキストを見る



中級レベル(GUIで作るゲーム開発)

Pythonで記述するコード
import tkinter
import random

def クリックボタン():
    ラベル["text"]=random.choice(["大吉","中吉","小吉","凶"])
    ラベル.update()

ウィンドウ = tkinter.Tk()
ウィンドウ.title("おみくじゲーム")
ウィンドウ.resizable(False , False)
キャンバス = tkinter.Canvas(ウィンドウ,width = 800 , height = 600)
キャンバス.pack()
画像 = tkinter.PhotoImage(file = "おみくじ.png")
キャンバス.create_image(400 , 300 , image = 画像)
ラベル = tkinter.Label(ウィンドウ,text = "??",font = ("Times New Roman",120),bg = "white")
ラベル.place(x=1,y=1)
ボタン = tkinter.Button(ウィンドウ,text="おみくじを引く",font =("Times New Roman",24),fg="skyblue",command = クリックボタン)
ボタン.place(x=550,y=540)
ウィンドウ.mainloop()


テキストを見る



Pythonで記述するコード
import tkinter

診断結果 = [
"前世がネコだった可能性は極めて薄いです。",
"いたって普通の人間です。",
"特別、おかしなところはありません。",
"やや、ネコっぽいところがあります。",
"ネコに近い性格のようです。",
"ネコにかなり近い性格です。",
"前世はネコだったかもしれません。",
"見た目は人間、中身はネコの可能性があります。"
]

def クリックボタン():
    カウント = 0
    for 結果 in range(7):
        if 判定[結果].get() == True:
            カウント = カウント + 1
    ネコ度 = int(100*カウント/7)
    テキスト入力.delete("1.0",tkinter.END)
    テキスト入力.insert("1.0","<診断結果>\nあなたのネコ度は"+str(ネコ度) + "%です。\n" +診断結果[カウント])

ウィンドウ = tkinter.Tk()
ウィンドウ.title("ネコ度診断ゲーム")
ウィンドウ.resizable(False,False)
キャンバス = tkinter.Canvas(ウィンドウ,width = 800,height = 600)
キャンバス.pack()
画像 = tkinter.PhotoImage(file = "neko.png")
キャンバス.create_image(400, 300,image =画像)
ボタン = tkinter.Button(text = "診断する",font =("Times New Roman",32),bg = "orange",command = クリックボタン)
ボタン.place(x=10 ,y=10)
テキスト入力 = tkinter.Text(width =35,height =5,font =("Times New Roman",16))
テキスト入力.place(x=375 , y=400)

判定 = [None]*7
チェックボックス = [None]*7
アイテム = [
"高いところが好き",
"ボールを見ると転がしたくなる",
"びっくりすると髪の毛が逆立つ",
"ネズミの玩具が気になる",
"匂いに敏感",
"魚の骨をしゃぶりたくなる",
"夜、元気になる"
]

for 結果 in range(7):
    判定[結果] = tkinter.BooleanVar()
    判定[結果].set(False)
    チェックボックス[結果] = tkinter.Checkbutton(text = アイテム[結果],font = ("Time New Roman",12),variable = 判定[結果],bg="orange")
    チェックボックス[結果].place(x=400, y=35+52*結果)

ウィンドウ.mainloop()


テキストを見る



Pythonで記述するコード
import tkinter
import tkinter.messagebox

key =""
def key_down(e):
    global key
    key= e.keysym
def key_up(e):
    global key
    key =""

mx=1
my=1
yuka=0

def main_proc():
    global mx,my,yuka
    if key == "Shift_L" and yuka > 1:
        canvas.delete("PAINT")
        mx=1
        my=1
        yuka=0
        for y in range(7):
            for x in range(10):
                if maze[y][x] ==2:
                    maze[y][x] =0
    if key == "Up" and maze[my-1][mx]==0:
        my = my - 1
    if key == "Down" and maze[my+1][mx]==0:
        my = my + 1
    if key =="Left" and maze[my][mx-1]==0:
        mx = mx - 1
    if key == "Right" and maze[my][mx+1]==0:
        mx = mx + 1
    if maze[my][mx] == 0:
        maze[my][mx]= 2
        yuka = yuka + 1
        canvas.create_rectangle(mx*80,my*80,mx*80+79,my*80+79,fill="pink",width=0,tag="PAINT",)
    canvas.delete("MYCHR")
    canvas.create_image(mx*80+40,my*80+40,image=img,tag="MYCHR")
    if yuka == 30:
        canvas.update()
        tkinter.messagebox.showinfo("おめでとう!","全ての床を塗りました!")
    else:
        root.after(200,main_proc)
    
root=tkinter.Tk()
root.title("床塗りゲーム")
root.bind("",key_down)
root.bind("",key_up)
canvas = tkinter.Canvas(width=800,height=560,bg="white")
canvas.pack() 

maze = [
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,0,0,0,1,0,0,1],
    [1,0,1,1,0,0,1,0,0,1],
    [1,0,0,1,0,0,0,0,0,1],
    [1,0,0,1,1,1,1,1,0,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
    ]

for y in range(7):
    for x in range(10):
        if maze[y][x]==1:
            canvas.create_rectangle(x*80,y*80,x*80+79,y*80+79,fill = "skyblue",width=0)

img = tkinter.PhotoImage(file="mimi_s.png")
canvas.create_image(mx*80+40,my*80+40,image=img,tag="MYCHR")
main_proc()
root.mainloop()



Pythonで記述するコード
import tkinter
import random

index = 0
timer = 0
score = 0
hisc = 1000
difficulty = 0
tugi = 0

cursor_x = 0
cursor_y = 0
mouse_x = 0
mouse_y = 0
mouse_c = 0

def mouse_move(e):
    global mouse_x , mouse_y
    mouse_x = e.x
    mouse_y = e.y

def mouse_press(e):
    global mouse_c
    mouse_c = 1

neko=[]
check=[]
for i in range(10):
    neko.append([0,0,0,0,0,0,0,0])
    check.append([0,0,0,0,0,0,0,0])

def draw_neko():
    cvs.delete("NEKO")
    for y in range(10):
        for x in range(8):
            cvs.create_image(x*72+60,y*72+60,image=img_neko[neko[y][x]],tag="NEKO")


def check_neko():
    for y in range(10):
        for x in range(8):
            check[y][x]=neko[y][x]
            
    for y in range(1,9):
        for x in range(8):
            if check[y][x]>0:
                if check[y-1][x] == check[y][x] and check[y+1][x] == check[y][x]:
                    neko[y-1][x]=7
                    neko[y][x]=7
                    neko[y+1][x]=7

    for y in range(10):
        for x in range(1,7):
            if check[y][x]>0:
                if check[y][x-1] == check[y][x] and check[y][x+1] == check[y][x]:
                    neko[y][x-1]=7
                    neko[y][x]=7
                    neko[y][x+1]=7

    for y in range(1,9):
        for x in range(1,7):
            if check[y][x]>0:
                if check[y-1][x-1] == check[y][x] and check[y+1][x+1] == check[y][x]:
                    neko[y-1][x-1]=7
                    neko[y][x]=7
                    neko[y+1][x+1]=7
                if check[y+1][x-1] == check[y][x] and check[y-1][x+1] == check[y][x]:
                    neko[y+1][x-1]=7
                    neko[y][x]=7
                    neko[y-1][x+1]=7
def sweep_neko():
    num = 0
    for y in range(10):
        for x in range(8):
            if neko[y][x] == 7:
                neko[y][x] = 0
                num = num + 1
    return num

def drop_neko():
    flg = False
    for y in range(8,-1,-1):
        for x in range(8):
            if neko[y][x] != 0 and neko[y+1][x] == 0:
                neko[y+1][x] = neko[y][x]
                neko[y][x] = 0
                flg = True
    return flg

def over_neko():
    for x in range(8):
        if neko[0][x] > 0:
            return True
    return False

def set_neko():
    for x in range(8):
        neko[0][x] = random.randint(0,difficulty)

def draw_txt(txt,x,y,siz,col,tg):
    fnt = ("Times New Roman",siz,"bold")
    cvs.create_text(x+2,y+2,text=txt,fill="black",font=fnt,tag=tg)
    cvs.create_text(x,y,text=txt,fill=col,font=fnt,tag=tg)

def game_main():
    global index,timer,score,hisc,difficulty,tugi
    global cursor_x,cursor_y,mouse_c
    if index == 0:
        draw_txt("ねこねこ",312,240,100,"violet","TITLE")
        cvs.create_rectangle(168,384,456,456,fill="skyblue",width=0,tag="TITLE")
        draw_txt("かんたん",312,420,40,"white","TITLE")
        cvs.create_rectangle(168,528,456,600,fill="lightgreen",width=0,tag="TITLE")
        draw_txt("ふつう",312,564,40,"white","TITLE")
        cvs.create_rectangle(168,672,456,744,fill="orange",width=0,tag="TITLE")
        draw_txt("むずかしい",312,708,40,"white","TITLE")
        
        index = 1
        mouse_c = 0
    elif index == 1:
        difficulty = 0
        if mouse_c == 1:
            if 168 < mouse_x and mouse_x < 456 and 384 < mouse_y and mouse_y < 456:
                difficulty = 4
            if 168 < mouse_x and mouse_x < 456 and 528 < mouse_y and mouse_y < 600:
                difficulty = 5
            if 168 < mouse_x and mouse_x < 456 and 672 < mouse_y and mouse_y < 744:
                difficulty = 6
        if difficulty > 0:
            for y in range(10):
                for x in range(8):
                    neko[y][x]=0
            mouse_c = 0
            score = 0
            tugi = 0
            cursor_x = 0
            cursor_y = 0
            set_neko()
            draw_neko()
            cvs.delete("TITLE")
            index = 2

    elif index == 2:
        if drop_neko() == False:
            index = 3
        draw_neko()

    elif index == 3:
        check_neko()
        draw_neko()
        index = 4
    elif index == 4:
        sc = sweep_neko()
        score = score + sc*difficulty*2
        if score > hisc:
            hisc = score
        if sc > 0:
            index = 2
        else:
            if over_neko() == False:
                tugi = random.randint(1,difficulty)
                index = 5
            else:
                index = 6
                timer = 0
        draw_neko()

    elif index == 5:
        if 24 <= mouse_x and mouse_x < 24+72*8 and 24 <= mouse_y and mouse_y < 24+72*10:
            cursor_x = int((mouse_x-24)/72)
            cursor_y = int((mouse_y-24)/72)
            if mouse_c ==1:
                mouse_c = 0
                set_neko()
                neko[cursor_y][cursor_x] = tugi
                tugi = 0
                index = 2
        cvs.delete("CURSOR")
        cvs.create_image(cursor_x*72+60,cursor_y*72+60,image = cursor,tag = "CURSOR")
        draw_neko()
    elif index == 6:
        timer = timer + 1
        if timer == 1:
            draw_txt("GAME OVER",312,348,60,"red","OVER")
        if timer == 50:
            cvs.delete("OVER")
            index = 0
    cvs.delete("INFO")
    draw_txt("SCORE" + str(score),160,60,32,"blue","INFO")
    draw_txt("HISC" +str(hisc),450,60,32,"yellow","INFO")
    if tugi > 0:
        cvs.create_image(752,128,image = img_neko[tugi],tag="INFO")
    root.after(100,game_main)

root=tkinter.Tk()
root.title("落ち物パズル「ねこねこ」")
root.resizable(False,False)
root.bind("",mouse_move)
root.bind("",mouse_press)
cvs=tkinter.Canvas(root,width=912,height=768)
cvs.pack()

bg = tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko_bg.png")
cursor = tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko_cursor.png")
img_neko=[
    None,
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko1.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko2.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko3.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko4.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko5.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko6.png"),
    tkinter.PhotoImage(file=r"C:\tekunoro\ZZ_Python素材\neko_niku.png")
]

cvs.create_image(456,384,image=bg)
game_main()
root.mainloop()



上級レベル(本格的なゲーム開発)

Pythonで記述するコード
import pygame
import sys
import random
from pygame.locals import *

# 色の定義
WHITE = (255, 255, 255)
BLACK = (  0,   0,   0)
RED   = (255,   0,   0)
CYAN  = (  0, 255, 255)
BLINK = [(224,255,255), (192,240,255), (128,224,255), (64,192,255), (128,224,255), (192,240,255)]

# 画像の読み込み
imgTitle = pygame.image.load("image/title.png")
imgWall = pygame.image.load("image/wall.png")
imgWall2 = pygame.image.load("image/wall2.png")
imgDark = pygame.image.load("image/dark.png")
imgPara = pygame.image.load("image/parameter.png")
imgBtlBG = pygame.image.load("image/btlbg.png")
imgEnemy = pygame.image.load("image/enemy0.png")
imgItem = [
    pygame.image.load("image/potion.png"),
    pygame.image.load("image/blaze_gem.png"),
    pygame.image.load("image/spoiled.png"),
    pygame.image.load("image/apple.png"),
    pygame.image.load("image/meat.png")
]
imgFloor = [
    pygame.image.load("image/floor.png"),
    pygame.image.load("image/tbox.png"),
    pygame.image.load("image/cocoon.png"),
    pygame.image.load("image/stairs.png")
]
imgPlayer = [
    pygame.image.load("image/mychr0.png"),
    pygame.image.load("image/mychr1.png"),
    pygame.image.load("image/mychr2.png"),
    pygame.image.load("image/mychr3.png"),
    pygame.image.load("image/mychr4.png"),
    pygame.image.load("image/mychr5.png"),
    pygame.image.load("image/mychr6.png"),
    pygame.image.load("image/mychr7.png"),
    pygame.image.load("image/mychr8.png")
]
imgEffect = [
    pygame.image.load("image/effect_a.png"),
    pygame.image.load("image/effect_b.png")
]

# 変数の宣言
speed = 1
idx = 0
tmr = 0
floor = 0
fl_max = 1
welcome = 0

pl_x = 0
pl_y = 0
pl_d = 0
pl_a = 0
pl_lifemax = 0
pl_life = 0
pl_str = 0
food = 0
potion = 0
blazegem = 0
treasure = 0

emy_name = ""
emy_lifemax = 0
emy_life = 0
emy_str = 0
emy_x = 0
emy_y = 0
emy_step = 0
emy_blink = 0

dmg_eff = 0
btl_cmd = 0

COMMAND = ["[A]ttack", "[P]otion", "[B]laze gem", "[R]un"]
TRE_NAME = ["Potion", "Blaze gem", "Food spoiled.", "Food +20", "Food +100"]
EMY_NAME = [
    "Green slime", "Red slime", "Axe beast", "Ogre", "Sword man",
    "Death hornet", "Signal slime", "Devil plant", "Twin killer", "Hell"
    ]

MAZE_W = 11
MAZE_H = 9
maze = []
for y in range(MAZE_H):
    maze.append([0]*MAZE_W)

DUNGEON_W = MAZE_W*3
DUNGEON_H = MAZE_H*3
dungeon = []
for y in range(DUNGEON_H):
    dungeon.append([0]*DUNGEON_W)

def make_dungeon(): # ダンジョンの自動生成
    XP = [ 0, 1, 0,-1]
    YP = [-1, 0, 1, 0]
    #周りの壁
    for x in range(MAZE_W):
        maze[0][x] = 1
        maze[MAZE_H-1][x] = 1
    for y in range(1, MAZE_H-1):
        maze[y][0] = 1
        maze[y][MAZE_W-1] = 1
    #中を何もない状態に
    for y in range(1, MAZE_H-1):
        for x in range(1, MAZE_W-1):
            maze[y][x] = 0
    #柱
    for y in range(2, MAZE_H-2, 2):
        for x in range(2, MAZE_W-2, 2):
            maze[y][x] = 1
    #柱から上下左右に壁を作る
    for y in range(2, MAZE_H-2, 2):
        for x in range(2, MAZE_W-2, 2):
         d = random.randint(0, 3)
         if x > 2: # 二列目からは左に壁を作らない
             d = random.randint(0, 2)
         maze[y+YP[d]][x+XP[d]] = 1

    # 迷路からダンジョンを作る
    #全体を壁にする
    for y in range(DUNGEON_H):
        for x in range(DUNGEON_W):
            dungeon[y][x] = 9
    #部屋と通路の配置
    for y in range(1, MAZE_H-1):
        for x in range(1, MAZE_W-1):
            dx = x*3+1
            dy = y*3+1
            if maze[y][x] == 0:
                if random.randint(0, 99) < 20: # 部屋を作る
                    for ry in range(-1, 2):
                        for rx in range(-1, 2):
                            dungeon[dy+ry][dx+rx] = 0
                else: # 通路を作る
                    dungeon[dy][dx] = 0
                    if maze[y-1][x] == 0: dungeon[dy-1][dx] = 0
                    if maze[y+1][x] == 0: dungeon[dy+1][dx] = 0
                    if maze[y][x-1] == 0: dungeon[dy][dx-1] = 0
                    if maze[y][x+1] == 0: dungeon[dy][dx+1] = 0

def draw_dungeon(bg, fnt): # ダンジョンを描画する
    bg.fill(BLACK)
    for y in range(-4, 6):
        for x in range(-5, 6):
            X = (x+5)*80
            Y = (y+4)*80
            dx = pl_x + x
            dy = pl_y + y
            if 0 <= dx and dx < DUNGEON_W and 0 <= dy and dy < DUNGEON_H:
                if dungeon[dy][dx] <= 3:
                    bg.blit(imgFloor[dungeon[dy][dx]], [X, Y])
                if dungeon[dy][dx] == 9:
                    bg.blit(imgWall, [X, Y-40])
                    if dy >= 1 and dungeon[dy-1][dx] == 9:
                        bg.blit(imgWall2, [X, Y-80])
            if x == 0 and y == 0: # 主人公キャラの表示
                bg.blit(imgPlayer[pl_a], [X, Y-40])
    bg.blit(imgDark, [0, 0]) # 四隅が暗闇の画像を重ねる
    draw_para(bg, fnt) # 主人公の能力を表示

def put_event(): # 床にイベントを配置する
    global pl_x, pl_y, pl_d, pl_a
    # 階段の配置
    while True:
        x = random.randint(3, DUNGEON_W-4)
        y = random.randint(3, DUNGEON_H-4)
        if(dungeon[y][x] == 0):
            for ry in range(-1, 2): # 階段の周囲を床にする
                for rx in range(-1, 2):
                    dungeon[y+ry][x+rx] = 0
            dungeon[y][x] = 3
            break
    # 宝箱と繭の配置
    for i in range(60):
        x = random.randint(3, DUNGEON_W-4)
        y = random.randint(3, DUNGEON_H-4)
        if(dungeon[y][x] == 0):
            dungeon[y][x] = random.choice([1,2,2,2,2])
    # プレイヤーの初期位置
    while True:
        pl_x = random.randint(3, DUNGEON_W-4)
        pl_y = random.randint(3, DUNGEON_H-4)
        if(dungeon[pl_y][pl_x] == 0):
            break
    pl_d = 1
    pl_a = 2
                
def move_player(key): # 主人公の移動
    global idx, tmr, pl_x, pl_y, pl_d, pl_a, pl_life, food, potion, blazegem, treasure

    if dungeon[pl_y][pl_x] == 1: # 宝箱に載った
        dungeon[pl_y][pl_x] = 0
        treasure = random.choice([0,0,0,1,1,1,1,1,1,2])
        if treasure == 0:
            potion = potion + 1
        if treasure == 1:
            blazegem = blazegem + 1
        if treasure == 2:
            food = int(food/2)
        idx = 3
        tmr = 0
        return
    if dungeon[pl_y][pl_x] == 2: # 繭に載った
        dungeon[pl_y][pl_x] = 0
        r = random.randint(0, 99)
        if r < 40: # 食料
            treasure = random.choice([3,3,3,4])
            if treasure == 3: food = food + 20
            if treasure == 4: food = food + 100
            idx = 3
            tmr = 0
        else: # 敵出現
            idx = 10
            tmr = 0
        return
    if dungeon[pl_y][pl_x] == 3: # 階段に載った
        idx = 2
        tmr = 0
        return

    # 方向キーで上下左右に移動
    x = pl_x
    y = pl_y
    if key[K_UP] == 1:
        pl_d = 0
        if dungeon[pl_y-1][pl_x] != 9:
            pl_y = pl_y - 1
    if key[K_DOWN] == 1:
        pl_d = 1
        if dungeon[pl_y+1][pl_x] != 9:
            pl_y = pl_y + 1
    if key[K_LEFT] == 1:
        pl_d = 2
        if dungeon[pl_y][pl_x-1] != 9:
            pl_x = pl_x - 1
    if key[K_RIGHT] == 1:
        pl_d = 3
        if dungeon[pl_y][pl_x+1] != 9:
            pl_x = pl_x + 1
    pl_a = pl_d*2
    if pl_x != x or pl_y != y: # 移動したら食料の量と体力を計算
        pl_a = pl_a + tmr%2 # 移動したら足踏みのアニメーション
        if food > 0:
            food = food - 1
            if pl_life < pl_lifemax:
                pl_life = pl_life + 1
        else:
            pl_life = pl_life - 5
            if pl_life <= 0:
                pl_life = 0
                pygame.mixer.music.stop()
                idx = 9
                tmr = 0

def draw_text(bg, txt, x, y, fnt, col): # 影付き文字の表示
    sur = fnt.render(txt, True, BLACK)
    bg.blit(sur, [x+1, y+2])
    sur = fnt.render(txt, True, col)
    bg.blit(sur, [x, y])

def draw_para(bg, fnt): # 主人公の能力を表示
    X = 30
    Y = 600
    bg.blit(imgPara, [X, Y])
    col = WHITE
    if pl_life < 10 and tmr%2 == 0: col = RED
    draw_text(bg, "{}/{}".format(pl_life, pl_lifemax), X+128, Y+6, fnt, col)
    draw_text(bg, str(pl_str), X+128, Y+33, fnt, WHITE)
    col = WHITE
    if food == 0 and tmr%2 == 0: col = RED
    draw_text(bg, str(food), X+128, Y+60, fnt, col)
    draw_text(bg, str(potion), X+266, Y+6, fnt, WHITE)
    draw_text(bg, str(blazegem), X+266, Y+33, fnt, WHITE)

def init_battle(): # 戦闘に入る準備をする
    global imgEnemy, emy_name, emy_lifemax, emy_life, emy_str, emy_x, emy_y
    typ = random.randint(0, floor)
    if floor >= 10:
        typ = random.randint(0, 9)
    lev = random.randint(1, floor)
    imgEnemy = pygame.image.load("image/enemy"+str(typ)+".png")
    emy_name = EMY_NAME[typ] + " LV" + str(lev)
    emy_lifemax = 60*(typ+1) + (lev-1)*10
    emy_life = emy_lifemax
    emy_str = int(emy_lifemax/8)
    emy_x = 440-imgEnemy.get_width()/2
    emy_y = 560-imgEnemy.get_height()

def draw_bar(bg, x, y, w, h, val, max): # 敵の体力を表示するバー
    pygame.draw.rect(bg, WHITE, [x-2, y-2, w+4, h+4])
    pygame.draw.rect(bg, BLACK, [x, y, w, h])
    if val > 0:
        pygame.draw.rect(bg, (0,128,255), [x, y, w*val/max, h])

def draw_battle(bg, fnt): # 戦闘画面の描画
    global emy_blink, dmg_eff
    bx = 0
    by = 0
    if dmg_eff > 0:
        dmg_eff = dmg_eff - 1
        bx = random.randint(-20, 20)
        by = random.randint(-10, 10)
    bg.blit(imgBtlBG, [bx, by])
    if emy_life > 0 and emy_blink%2 == 0:
        bg.blit(imgEnemy, [emy_x, emy_y+emy_step])
    draw_bar(bg, 340, 580, 200, 10, emy_life, emy_lifemax)
    if emy_blink > 0:
        emy_blink = emy_blink - 1
    for i in range(10): # 戦闘メッセージの表示
        draw_text(bg, message[i], 600, 100+i*50, fnt, WHITE)
    draw_para(bg, fnt) # 主人公の能力を表示

def battle_command(bg, fnt, key): # コマンドの入力と表示
    global btl_cmd
    ent = False
    if key[K_a]: # Aキー
        btl_cmd = 0
        ent = True
    if key[K_p]: # Pキー
        btl_cmd = 1
        ent = True
    if key[K_b]: # Bキー
        btl_cmd = 2
        ent = True
    if key[K_r]: # Rキー
        btl_cmd = 3
        ent = True
    if key[K_UP] and btl_cmd > 0: #↑キー
        btl_cmd -= 1
    if key[K_DOWN] and btl_cmd < 3: #↓キー
        btl_cmd += 1
    if key[K_SPACE] or key[K_RETURN]:
        ent = True
    for i in range(4):
        c = WHITE
        if btl_cmd == i: c = BLINK[tmr%6]
        draw_text(bg, COMMAND[i], 20, 360+i*60, fnt, c)
    return ent

# 戦闘メッセージの表示処理
message = [""]*10
def init_message():
    for i in range(10):
        message[i] = ""
    
def set_message(msg):
    for i in range(10):
        if message[i] == "":
            message[i] = msg
            return
    for i in range(9):
        message[i] = message[i+1]
    message[9] = msg

def main(): # メイン処理
    global speed, idx, tmr, floor, fl_max, welcome
    global pl_a, pl_lifemax, pl_life, pl_str, food, potion, blazegem
    global emy_life, emy_step, emy_blink, dmg_eff
    dmg = 0
    lif_p = 0
    str_p = 0

    pygame.init()
    pygame.display.set_caption("One hour Dungeon")
    screen = pygame.display.set_mode((880, 720))
    clock = pygame.time.Clock()
    font = pygame.font.Font(None, 40)
    fontS = pygame.font.Font(None, 30)

    se = [ # 効果音とジングル
        pygame.mixer.Sound("sound/ohd_se_attack.ogg"),
        pygame.mixer.Sound("sound/ohd_se_blaze.ogg"),
        pygame.mixer.Sound("sound/ohd_se_potion.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_gameover.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_levup.ogg"),
        pygame.mixer.Sound("sound/ohd_jin_win.ogg")
    ]

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_s:
                    speed = speed + 1
                    if speed == 4:
                        speed = 1

        tmr = tmr + 1
        key = pygame.key.get_pressed()

        if idx == 0: # タイトル画面
            if tmr == 1:
                pygame.mixer.music.load("sound/ohd_bgm_title.ogg")
                pygame.mixer.music.play(-1)
            screen.fill(BLACK)
            screen.blit(imgTitle, [40, 60])
            if fl_max >= 2:
                draw_text(screen, "You reached floor {}.".format(fl_max), 300, 460, font, CYAN)
            draw_text(screen, "Press space key", 320, 560, font, BLINK[tmr%6])
            if key[K_SPACE] == 1:
                make_dungeon()
                put_event()
                floor = 1
                welcome = 15
                pl_lifemax = 300
                pl_life = pl_lifemax
                pl_str = 100
                food = 300
                potion = 0
                blazegem = 0
                idx = 1
                pygame.mixer.music.load("sound/ohd_bgm_field.ogg")
                pygame.mixer.music.play(-1)

        elif idx == 1: # プレイヤーの移動
            move_player(key)
            draw_dungeon(screen, fontS)
            draw_text(screen, "floor {} ({},{})".format(floor, pl_x, pl_y), 60, 40, fontS, WHITE)
            if welcome > 0:
                welcome = welcome - 1
                draw_text(screen, "Welcome to floor {}.".format(floor), 300, 180, font, CYAN)

        elif idx == 2: # 画面切り替え
            draw_dungeon(screen, fontS)
            if 1 <= tmr and tmr <= 5:
                h = 80*tmr
                pygame.draw.rect(screen, BLACK, [0, 0, 880, h])
                pygame.draw.rect(screen, BLACK, [0, 720-h, 880, h])
            if tmr == 5:
                floor = floor + 1
                if floor > fl_max:
                    fl_max = floor
                welcome = 15
                make_dungeon()
                put_event()
            if 6 <= tmr and tmr <= 9:
                h = 80*(10-tmr)
                pygame.draw.rect(screen, BLACK, [0, 0, 880, h])
                pygame.draw.rect(screen, BLACK, [0, 720-h, 880, h])
            if tmr == 10:
                idx = 1

        elif idx == 3: # アイテム入手もしくはトラップ
            draw_dungeon(screen, fontS)
            screen.blit(imgItem[treasure], [320, 220])
            draw_text(screen, TRE_NAME[treasure], 380, 240, font, WHITE)
            if tmr == 10:
                idx = 1

        elif idx == 9: # ゲームオーバー
            if tmr <= 30:
                PL_TURN = [2, 4, 0, 6]
                pl_a = PL_TURN[tmr%4]
                if tmr == 30: pl_a = 8 # 倒れた絵
                draw_dungeon(screen, fontS)
            elif tmr == 31:
                se[3].play()
                draw_text(screen, "You died.", 360, 240, font, RED)
                draw_text(screen, "Game over.", 360, 380, font, RED)
            elif tmr == 100:
                idx = 0
                tmr = 0

        elif idx == 10: # 戦闘開始
            if tmr == 1:
                pygame.mixer.music.load("sound/ohd_bgm_battle.ogg")
                pygame.mixer.music.play(-1)
                init_battle()
                init_message()
            elif tmr <= 4:
                bx = (4-tmr)*220
                by = 0
                screen.blit(imgBtlBG, [bx, by])
                draw_text(screen, "Encounter!", 350, 200, font, WHITE)
            elif tmr <= 16:
                draw_battle(screen, fontS)
                draw_text(screen, emy_name+" appear!", 300, 200, font, WHITE)
            else:
                idx = 11
                tmr = 0

        elif idx == 11: # プレイヤーのターン(入力待ち)
            draw_battle(screen, fontS)
            if tmr == 1: set_message("Your turn.")
            if battle_command(screen, font, key) == True:
                if btl_cmd == 0:
                    idx = 12
                    tmr = 0
                if btl_cmd == 1 and potion > 0:
                    idx = 20
                    tmr = 0
                if btl_cmd == 2 and blazegem > 0:
                    idx = 21
                    tmr = 0
                if btl_cmd == 3:
                    idx = 14
                    tmr = 0

        elif idx == 12: # プレイヤーの攻撃
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("You attack!")
                se[0].play()
                dmg = pl_str + random.randint(0, 9)
            if 2 <= tmr and tmr <= 4:
                screen.blit(imgEffect[0], [700-tmr*120, -100+tmr*120])
            if tmr == 5:
                emy_blink = 5
                set_message(str(dmg)+"pts of damage!")
            if tmr == 11:
                emy_life = emy_life - dmg
                if emy_life <= 0:
                    emy_life = 0
                    idx = 16
                    tmr = 0
            if tmr == 16:
                idx = 13
                tmr = 0

        elif idx == 13: # 敵のターン、敵の攻撃
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("Enemy turn.")
            if tmr == 5:
                set_message(emy_name + " attack!")
                se[0].play()
                emy_step = 30
            if tmr == 9:
                dmg = emy_str + random.randint(0, 9)
                set_message(str(dmg)+"pts of damage!")
                dmg_eff = 5
                emy_step = 0
            if tmr == 15:
                pl_life = pl_life - dmg
                if pl_life < 0:
                    pl_life = 0
                    idx = 15
                    tmr = 0
            if tmr == 20:
                idx = 11
                tmr = 0

        elif idx == 14: # 逃げられる?
            draw_battle(screen, fontS)
            if tmr == 1: set_message("...")
            if tmr == 2: set_message("......")
            if tmr == 3: set_message(".........")
            if tmr == 4: set_message("............")
            if tmr == 5:
                if random.randint(0, 99) < 60:
                    idx = 22
                else:
                    set_message("You failed to flee.")
            if tmr == 10:
                idx = 13
                tmr = 0
             
        elif idx == 15: # 敗北
            draw_battle(screen, fontS)
            if tmr == 1:
                pygame.mixer.music.stop()
                set_message("You lose.")
            if tmr == 11:
                idx = 9
                tmr = 29

        elif idx == 16: # 勝利
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("You win!")
                pygame.mixer.music.stop()
                se[5].play()
            if tmr == 28:
                idx = 22
                if random.randint(0, emy_lifemax) > random.randint(0, pl_lifemax):
                    idx = 17
                    tmr = 0

        elif idx == 17: # レベルアップ
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("Level up!")
                se[4].play()
                lif_p = random.randint(10, 20)
                str_p = random.randint(5, 10)
            if tmr == 21:
                set_message("Max life + "+str(lif_p))
                pl_lifemax = pl_lifemax + lif_p
            if tmr == 26:
                set_message("Str + "+str(str_p))
                pl_str = pl_str + str_p
            if tmr == 50:
                idx = 22

        elif idx == 20: # Potion
            draw_battle(screen, fontS)
            if tmr == 1:
                set_message("Potion!")
                se[2].play()
            if tmr == 6:
                pl_life = pl_lifemax
                potion = potion - 1
            if tmr == 11:
                idx = 13
                tmr = 0

        elif idx == 21: # Blaze gem
            draw_battle(screen, fontS)
            img_rz = pygame.transform.rotozoom(imgEffect[1], 30*tmr, (12-tmr)/8)
            X = 440-img_rz.get_width()/2
            Y = 360-img_rz.get_height()/2
            screen.blit(img_rz, [X, Y])
            if tmr == 1:
                set_message("Blaze gem!")
                se[1].play()
            if tmr == 6:
                blazegem = blazegem - 1
            if tmr == 11:
                dmg = 1000
                idx = 12
                tmr = 4

        elif idx == 22: # 戦闘終了
            pygame.mixer.music.load("sound/ohd_bgm_field.ogg")
            pygame.mixer.music.play(-1)
            idx = 1

        draw_text(screen, "[S]peed "+str(speed), 740, 40, fontS, WHITE)

        pygame.display.update()
        clock.tick(4+2*speed)

if __name__ == '__main__':
    main()



Pythonで記述するコード
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,-2, 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 # プレイヤーの車の表示位置 道路一番手前(画面下)が0

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) # Surfaceの透過色を設定
    shadow.set_alpha(128) # Surfaceの透明度を設定
    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[0] = 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): # COMカーの制御
    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("image_pr/title.png").convert_alpha()
    img_bg = pygame.image.load("image_pr/bg.png").convert()
    img_sea = pygame.image.load("image_pr/sea.png").convert_alpha()
    img_obj = [
        None,
        pygame.image.load("image_pr/board.png").convert_alpha(),
        pygame.image.load("image_pr/yashi.png").convert_alpha(),
        pygame.image.load("image_pr/yacht.png").convert_alpha()
    ]
    img_car = [
        pygame.image.load("image_pr/car00.png").convert_alpha(),
        pygame.image.load("image_pr/car01.png").convert_alpha(),
        pygame.image.load("image_pr/car02.png").convert_alpha(),
        pygame.image.load("image_pr/car03.png").convert_alpha(),
        pygame.image.load("image_pr/car04.png").convert_alpha(),
        pygame.image.load("image_pr/car05.png").convert_alpha(),
        pygame.image.load("image_pr/car06.png").convert_alpha(),
        pygame.image.load("image_pr/car10.png").convert_alpha(),
        pygame.image.load("image_pr/car11.png").convert_alpha(),
        pygame.image.load("image_pr/car12.png").convert_alpha(),
        pygame.image.load("image_pr/car13.png").convert_alpha(),
        pygame.image.load("image_pr/car14.png").convert_alpha(),
        pygame.image.load("image_pr/car15.png").convert_alpha(),
        pygame.image.load("image_pr/car16.png").convert_alpha(),
        pygame.image.load("image_pr/car20.png").convert_alpha(),
        pygame.image.load("image_pr/car21.png").convert_alpha(),
        pygame.image.load("image_pr/car22.png").convert_alpha(),
        pygame.image.load("image_pr/car23.png").convert_alpha(),
        pygame.image.load("image_pr/car24.png").convert_alpha(),
        pygame.image.load("image_pr/car25.png").convert_alpha(),
        pygame.image.load("image_pr/car26.png").convert_alpha()
    ]

    se_crash = pygame.mixer.Sound("sound_pr/crash.ogg") # SEの読み込み

    # 道路の板の基本形状を計算
    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): # COMカー
                if int(car_y[c])%CMAX == int(car_y[0]+i)%CMAX:
                    lr = int(4*(car_x[0]-car_x[c])/800) # プレイヤーから見たCOMカーの向き
                    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: # PLAYERカー
                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)
            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:
                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("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("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)
            for i in range(3):
                x = 160+240*i
                y = 300
                col = BLACK
                if i == mycar:
                    col = (0,128,255)
                pygame.draw.rect(screen, col, [x-100, y-80, 200, 160])
                draw_text(screen, "["+str(i+1)+"]", x, y-50, WHITE, fnt_m)
                screen.blit(img_car[3+i*7], [x-100, y-20])
            draw_text(screen, "[Enter] OK!", 400, 440, GREEN, fnt_m)
            if key[K_1] == 1:
                mycar = 0
            if key[K_2] == 1:
                mycar = 1
            if key[K_3] == 1:
                mycar = 2
            if key[K_RETURN] == 1:
                idx = 0

        pygame.display.update()
        clock.tick(60)

if __name__ == '__main__':
    main()