【Python講座】Pythonで作るパズルゲーム#3_だんごを落下させよう

こんにちは、koheiです。
Pythonでパズルゲームを作ろうの第3回目です。
動画解説もあります。記事と合わせてどうぞ!
目次
今回のゴール
今回は、だんごの落下処理を実装していきます。
練習素材は以下からダウンロードできますので、ぜひダウンロードしてやってみてください。
だんご落下処理イメージ
だんごを落下させる処理を実装していきましょう。
イメージは、だんごが配置されているマスの一つ下のマスが空白ならだんごを一つ下のマスへ移動し、もとのマスは空白にします。

これをマス上1つ1つチェックして処理していきます。
チェックは、Y座標の下から順にチェックしていきます。(一番下のマスはこれ以上下に移動できないので、チェックしません)
※上から順にチェックしてしまうと、下に移動させただんごをまたチェックしてしまい、一気に下まで落ちてしまうので、下からチェックしましょう。

だんご落下処理実装
では先程説明したイメージで処理を実装していきましょう。
pygame_dango_game.pyに以下を追加します。
#団子を表示する関数
def disp_dango():
screen.blit(bg,[0,0]) #背景画像描画
for y in range(10):
for x in range(8):
if dango[y][x] > 0:
screen.blit(img_dango[dango[y][x]],[x*72+20, y*72+20])
# だんごを落下させる関数
def drop_dango():
for y in range(8,-1,-1):
for x in range(8):
if dango[y][x] !=0 and dango[y+1][x] == 0:
dango[y+1][x] = dango[y][x]
dango[y][x] = 0
先程説明したように、y座標は、下からチェックしていきますので、rangeは、8から-1まで(※実際は0までループします)とします。(※11行目)
x座標は、0から7までチェックしていきます。
13行目のif文は、チェックするマスが0ではなく、一つしたのマスが0(空白)だった場合、チェックしているマスの数値を一つしたのマスへ格納し、チェックしているマスは0に設定します。
これを下から全マスチェックしていきます。
続いて、drop_dango()関数をmain処理内で呼び出します。
pygame_dango_game.pyに以下を追加します。
#ゲームメイン処理
def main():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
drop_dango() # だんご落下させる
disp_dango() # だんご表示
pygame.display.update()
clock.tick(10)
だんご落下処理(drop_dango())とだんご表示関数(disp_dango())を10msec毎に呼び出すことでだんごを下へ落下させていきます。
さて、ここまで実装できたら、早速実行してみましょう。
だんごが落下してきたらOKです。
クリックしたマスにだんごを置いてみる
続いて、マス上のクリックした位置にだんごを配置する処理を作っていきます。
カーソル画像をロードする
まずは、カーソル画像をロードする処理を実装しましょう。
以下のように実装します。
if __name__ == '__main__':
#初期化、画像ロード処理など
pygame.init()
pygame.display.set_caption("だんごパズル(pygame ver)")
screen = pygame.display.set_mode((912,768))
clock = pygame.time.Clock()
bg = pygame.image.load("dango_back.png") #背景画像をロード
cursor = pygame.image.load("cursor.png") #カーソル画像をロード
img_dango = [ #だんご画像をロード
None,
pygame.image.load("dango1.png"),
pygame.image.load("dango2.png"),
pygame.image.load("dango3.png"),
pygame.image.load("dango4.png"),
pygame.image.load("dango_kushi.png")
]
#ゲームメイン処理
main()
マウス位置とクリック状態を取得
クリックした位置にだんごを配置するため、マウスの位置とクリックしたかどうかの状態を取得します。
以下のように実装します。
#ゲームメイン処理
def main():
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
mouse_x,mouse_y = pygame.mouse.get_pos() #マウス位置
mouse_click = pygame.mouse.get_pressed() #マウスクリック
mouse_c = mouse_click[0] #マウス左クリック状態を設定
drop_dango() # だんご落下させる
disp_dango() # だんご表示
screen.blit(cursor,[cursor_x*72+60-40,cursor_y*72+60-40]) #カーソル表示
pygame.display.update()
clock.tick(10)
8行目のpygame.mouse.get_pos()でマウスポインタのXY座標を取得して、それをmouse_x,mouse_yに代入します。
9行目のpygame.mouse.get_pressed()でマウスクリック状態がmouse_clickリストに格納されます。それの0番目の要素が左クリックの状態なので、それをmouse_cに代入します。
クリックしただんごをランダムに配置する
続いて、マス上のクリックした位置にだんごをランダムに配置する処理を実装します。
以下のように実装します。
#ゲームメイン処理
def main():
cursor_x=0
cursor_y=0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
mouse_x,mouse_y = pygame.mouse.get_pos() #マウス位置
mouse_click = pygame.mouse.get_pressed() #マウスクリック
mouse_c = mouse_click[0] #マウス左クリック状態を設定
drop_dango() # だんご落下させる
# マウスが盤上内であれば
if 20 <= mouse_x and mouse_x < 20+72*8 and 20 <= mouse_y and mouse_y < 20+72*10:
cursor_x = int((mouse_x-20)/72)
cursor_y = int((mouse_y-20)/72)
if mouse_c == True and dango[cursor_y][cursor_x] == 0:
mouse_c = False
dango[cursor_y][cursor_x] = random.randint(1,4)
disp_dango() # だんご表示
screen.blit(cursor,[cursor_x*72+20,cursor_y*72+20]) #カーソル表示
pygame.display.update()
clock.tick(10)
まず、3,4行目でマウスカーソル位置用の変数を初期化します。(あとで、マウス位置からカーソル位置に変換した値を代入します)
マウス位置がマス上の範囲内であれば、if文の中が処理されます。(15行目)
取得したマウス座標は、ピクセル上の位置なので、これをカーソル位置に変換します。
1マスサイズが72ピクセルなので、オフセット分引いた各座標を72で割った値を整数型にキャストします。これで、cursor_xが0〜7,cursor_yが0〜9になります。(16行目、17行目)
次に、クリック状態がTrue、かつクリックした位置にだんごがない場合、クリックした位置のリストdangoに1〜4のランダムの数値を代入します。
これで、ランダムにだんごが代入されることになります。(18行目〜20行目)
最後にクリックした位置にロードしたおいたカーソル画像を表示させています。(22行目)
ここまでできたら、実行してみましょう。
クリックしたマス上にだんごが表示され、
だんごが落下していけばOKです。
最後に
以上、今回はだんごを落下させたり、クリックした位置にだんごを置く処理を実装してみました。
次回は揃っただんごを消す処理を作っていきます。
それでは、次回もお楽しみに!

