【Python講座】Pythonで作るパズルゲーム#4_揃っただんごを消してみよう
こんにちは、koheiです。
Pythonでパズルゲームを作ろうの第4回目です。
動画解説もあります。記事と合わせてどうぞ!
今回のゴール
今回は、3つ以上揃っただんごを消すという処理を作っていきます。
練習素材は以下からダウンロードできますので、ぜひダウンロードしてやってみてください。
だんごを消す処理のイメージ
だんごを消す処理のイメージです。以下の流れで制御していきます。
1.判定用リストを用意し、dangoリストを判定用リスト(checkリスト)にコピーする
2.判定用リスト(checkリスト)を使って、縦、横、斜めにだんごが3つ並んでいるかをチェックし、並んでいる場合は、dangoリストの値を串(値5)に変更する
それを全マスチェックしていく
3.dangoリストの値をチェックし、串(値5)だったら、空(値0)に変更する。
なぜ、判定用リスト(checkリスト)をわざわざ用意するかというと、そのままdangoリストをチェックして値を変更していくと、すでに3つ揃っている箇所は串の値5に変わっているので、4つ以上並んでいる場合の判定できなくなってしまうからです。
実装
それでは、先程のイメージに沿って、だんごが揃ったかどうかの判定処理を作っていきましょう。
pygame_dango_game.pyに以下を実装しましょう。(黄色い部分)
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 |
import pygame import random import sys dango = [] #マス目の配列 check = [] #判定用の配列 for i in range(10): dango.append([0,0,0,0,0,0,0,0]) check.append([0,0,0,0,0,0,0,0]) #団子を表示する関数 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 # 団子が揃ったかをチェックする関数 def check_dango(): for y in range(10): for x in range(8): check[y][x] = dango[y][x] # 盤面をcheckにコピーする 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]: dango[y-1][x] = 5 dango[y][x] = 5 dango[y+1][x] = 5 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]: dango[y][x-1] = 5 dango[y][x] = 5 dango[y][x+1] = 5 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]: dango[y-1][x-1] = 5 dango[y][x] = 5 dango[y+1][x+1] = 5 if check[y+1][x-1] == check[y][x] and check[y-1][x+1] == check[y][x]: dango[y+1][x-1] = 5 dango[y][x] = 5 dango[y-1][x+1] = 5 |
5-9行目は、dangoリストと判定用リスト(check)の初期化処理です。
前回まで暫定で設定していたdangoリストをオール0で初期化しています。appendは、リストの末尾に要素を追加するメソッドです。
29行目からのcheck_dango()処理では、だんごが縦、横、斜めに3つ並んでいるかをチェックする処理です。
34〜40行目が、縦に3つ並んでいるかをチェックする処理、
42〜48行目が、横に3つ並んでいるかをチェックする処理、
50〜61行目が、斜めに3つ並んでいるかチェックする処理となります。3つ揃っていたら、dangoリストの値を串(値:5)に変更しています。
次に、揃っただんごを消す処理を実装しましょう。
以下の関数を追加しましょう。
1 2 3 4 5 6 7 8 9 |
# 揃っただんごを消す関数 def delete_dango(): num = 0 for y in range(10): for x in range(8): if dango[y][x] == 5: dango[y][x] = 0 num = num + 1 return num |
dangoリストの中身をチェックしていき、串の値:5の場合、空白:0に変更します。
また、空白に変更した数を戻り値で返します。
これは、後ほどスコア計算で使用するため、戻り値で消した数を返すようにしています。
さて、これらの関数をメインモジュールからコールするようにします。
以下を追加します。
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 |
#ゲームメイン処理 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) check_dango() #だんごが揃ったか判定 delete_dango() #揃っただんごを消す disp_dango() # だんご表示 disp_score() # スコア表示 screen.blit(cursor,[cursor_x*72+20,cursor_y*72+20]) #カーソル表示 pygame.display.update() clock.tick(10) |
さて、ここまでできたら、ファイルを保存して実行してみましょう。
3つ以上揃っただんごが消えていけば、OKです。
スコア表示処理
続いて、だんごを消した数からスコアを計算し、表示させてみましょう。
まずは、スコア用の変数、文字表示用の色定義を用意します。
変数は、複数の関数で参照するため、グローバル変数で定義します。
※グローバス変数・・・関数の外部で宣言した変数。グローバル変数の値はプログラムが終了するまで値が保持される。
関数内でグローバル変数の値を変更するには、その変数をglobal宣言する必要がある。
以下を実装します。
1 2 3 4 5 6 7 8 9 |
import pygame import random import sys # 色定義 BLUE = (0,0,255) # 変数 score = 0 #スコア用変数 hisc = 1000 #ハイスコアを保持する変数 |
初期化関連の処理内で、pygameのフォント指定処理を追加しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
if __name__ == '__main__': #初期化、画像ロード処理など pygame.init() pygame.display.set_caption("だんごパズル(pygame ver)") screen = pygame.display.set_mode((912,768)) font = pygame.font.Font(None,60) 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() |
スコア表示用の関数、メインモジュール等に以下を実装します。
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 |
# スコア表示 def disp_score(): global score,hisc txt = font.render(str(score),True,BLUE) screen.blit(txt,[650,300]) txt2 = font.render(str(hisc),True,BLUE) screen.blit(txt2,[650,400]) #ゲームメイン処理 def main(): cursor_x=0 cursor_y=0 global score,hisc 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) check_dango() #だんごが揃ったか判定 sc = delete_dango() #揃っただんごを消す score = score + sc*10 if score > hisc: hisc = score disp_dango() # だんご表示 disp_score() # スコア表示 screen.blit(cursor,[cursor_x*72+20,cursor_y*72+20]) #カーソル表示 pygame.display.update() clock.tick(10) |
disp_score()は、スコア表示する関数です。
計算したスコアを文字列に変換し、render()命令で表示文字列を作ります。
blit()命令で画面に文字列を貼り付けます。座標は、スコア表示用の座標を指定しています。
メインモジュールでは、スコアを計算します。
delete_dango()で消しただんごの数をscへ設定し、10倍した値をscore変数に格納します。
33行目の判定は、ハイスコア(hisc)を超えたら、ハイスコアを更新する処理です。
ここまでできたら、ファイルを保存してpython実行してみましょう。
揃っただんごが消えて、スコアが加算されていけばOKです。
最後に
今回は、揃っただんごを消して、スコアを計算する処理を作ってみました。
だんだんゲームらしくなってきました。
次は、ゲームのタイトル画面やゲームオーバー、効果音などを追加してゲームとして完成させたいと思います。
それでは!
スポンサーリンク