ロボット研究開発、ソフトウェア開発、コンテンツ制作配信

【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に以下を実装しましょう。(黄色い部分)

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)に変更しています。

次に、揃っただんごを消す処理を実装しましょう。
以下の関数を追加しましょう。

# 揃っただんごを消す関数
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に変更します。
また、空白に変更した数を戻り値で返します。
これは、後ほどスコア計算で使用するため、戻り値で消した数を返すようにしています。

さて、これらの関数をメインモジュールからコールするようにします。
以下を追加します。

#ゲームメイン処理
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です。

$python pygame_dango_game.py

スコア表示処理

続いて、だんごを消した数からスコアを計算し、表示させてみましょう。

まずは、スコア用の変数、文字表示用の色定義を用意します。
変数は、複数の関数で参照するため、グローバル変数で定義します。
※グローバス変数・・・関数の外部で宣言した変数。グローバル変数の値はプログラムが終了するまで値が保持される。
関数内でグローバル変数の値を変更するには、その変数をglobal宣言する必要がある。

以下を実装します。

import pygame
import random
import sys

# 色定義
BLUE = (0,0,255)
# 変数
score = 0   #スコア用変数
hisc = 1000 #ハイスコアを保持する変数

初期化関連の処理内で、pygameのフォント指定処理を追加しておきます。

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()

スコア表示用の関数、メインモジュール等に以下を実装します。

# スコア表示
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です。

$python pygame_dango_game.py

最後に

今回は、揃っただんごを消して、スコアを計算する処理を作ってみました。
だんだんゲームらしくなってきました。
次は、ゲームのタイトル画面やゲームオーバー、効果音などを追加してゲームとして完成させたいと思います。
それでは!

関連記事(一部広告含む)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


ページトップボタン