Pygameを使って迷路内を移動しよう
今回は前回作った迷路を使って、キャラクターが移動するプログラムを作ります。
赤い円を操作して緑のゴールを目指します。
移動できる範囲は白い部分のみで、黒い部分は移動できません。
右下の緑色のマスがゴールとなります。
Pythonスクリプト
今回のスクリプトは、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
### インポート import sys import pygame from pygame.locals import * ### 定数 WIDTH = 320 # 画面横サイズ HEIGHT = 320 # 画面縦サイズ B_SIZE = 40 # 辺長 M_SIZE = 20 # 半径 M_DOT = 40 # 移動ドット W_TIME = 20 # 待ち時間 F_SIZE = 60 # フォントサイズ ### マップ ####### 0 1 2 3 4 5 6 7 ##### MAP = [[1,0,0,0,0,0,0,0], # 0 [1,0,0,1,1,1,1,0], # 1 [1,1,1,1,0,0,1,0], # 2 [0,0,0,0,1,1,1,0], # 3 [0,0,0,0,1,0,0,0], # 4 [0,0,0,0,1,1,1,0], # 5 [0,0,0,0,0,0,1,1], # 6 [0,0,0,0,0,0,0,2]] # 7 ############################ ### メイン関数 ############################ def main(): ### 迷路描画関数呼び出し draw_maze() ### キー操作関数呼び出し input_key() ############################ ### 迷路描画関数 ############################ def draw_maze(): ### 座標初期化 x = 0 y = 0 ### 縦座標 for b1 in MAP: ### 横座標 for b2 in b1: if b2 == 0: # 壁描画 pygame.draw.rect(surface, ( 48, 48, 48), (x*B_SIZE,y*B_SIZE,B_SIZE,B_SIZE), 0) elif b2 == 1: # 通路描画 pygame.draw.rect(surface, (224,224,224), (x*B_SIZE,y*B_SIZE,B_SIZE,B_SIZE), 0) elif b2 == 2: # ゴール描画 pygame.draw.rect(surface, ( 48,176, 96), (x*B_SIZE,y*B_SIZE,B_SIZE,B_SIZE), 0) x += 1 ### 座標更新 else: x = 0 y += 1 ### マップ描画 pygame.display.update() ############################ ### キー操作関数 ############################ def input_key(): ### 座標初期化 row = 0 # リスト縦 col = 0 # リスト横 now_x = M_SIZE # 横座標 now_y = M_SIZE # 縦座標 bak_x = M_SIZE # 横前座標 bak_y = M_SIZE # 縦前座標 e_flag = 0 # 終了フラグ ### イベント待ち while True: ### ゴール確認 if MAP[row][col] == 2: ### 初回のみ if e_flag == 0: pygame.draw.circle(surface, (255, 0, 0), (now_x,now_y), M_SIZE, 0) pygame.draw.circle(surface, (224,224,224), (bak_x,bak_y), M_SIZE, 0) pygame.display.update() pygame.time.wait(100) e_flag = 1 ### テキスト設定 text = font.render("GOAL!", True, (224,224,255)) ### ゴール描画 surface.fill((0,0,0)) surface.blit(text, [93,139]) ### 未ゴール if e_flag == 0: ### 移動キャラクター描画 pygame.draw.circle(surface, (255,0,0), (now_x,now_y), M_SIZE, 0) ### 移動後通路の色に戻す if now_x != bak_x or now_y != bak_y: pygame.draw.circle(surface, (224,224,224), (bak_x,bak_y), M_SIZE, 0) ### 画面再描画 pygame.display.update() pygame.time.wait(W_TIME) ### 位置保存 bak_x = now_x bak_y = now_y ### イベント取得 for event in pygame.event.get(): if event.type == QUIT: exit() if event.type == KEYDOWN: if event.key == K_ESCAPE: exit() if event.key == K_LEFT: if (now_x > 0 + B_SIZE) and (MAP[row][col-1] != 0): col -= 1 now_x -= M_DOT if event.key == K_RIGHT: if (now_x < WIDTH - B_SIZE) and (MAP[row][col+1] != 0): col += 1 now_x += M_DOT if event.key == K_UP: if (now_y > 0 + B_SIZE) and (MAP[row-1][col] != 0): row -= 1 now_y -= M_DOT if event.key == K_DOWN: if (now_y < HEIGHT - B_SIZE) and (MAP[row+1][col] != 0): row += 1 now_y += M_DOT ############################ ### 終了関数 ############################ def exit(): pygame.quit() sys.exit() ############################ ### メイン関数呼び出し ############################ if __name__ == "__main__": ### 画面初期化 pygame.init() surface = pygame.display.set_mode((WIDTH, HEIGHT)) font = pygame.font.Font(None, F_SIZE) ### 処理開始 main() |
スクリプト解説
マップの描画など、前回から変更のない箇所については、前回の記事を参照してください。
86行目
ゴールに到着したかどうかを、現在のMAPリストの要素を見て確認します。
要素が2の場合は、ゴールに到着しています。
89~94行目
最初にゴールした時のみ、100ミリ秒間赤い円をゴール地点に表示します。
97行目
画面に指定した文字列を描画します。
引数の意味は、以下の通りです。
1番目:表示する文字列
2番目:アンチエイリアスをするかどうか
3番目:四角形の色をRGBで表す
101行目
指定した文字列を画面上に描画します。
描画する位置は画面中央になるように設定しています。
Font.size()メソッドで、文字列のサイズを確認できます。
106行目
赤い円を指定した場所に描画します。
109、110行目
移動した場合、移動する前の赤い円を通路の色で上書きします。
117、118行目
110行目の処理を行うために、赤い円が移動する前の座標を保存します。
121~142行目
入力されたキーを取得して、赤い円の移動先を設定します。
MAPリストの要素が0の場合は、移動できないエリアです。