タピオカパズル

講師から一言
パズルゲームの定番、ぷよぷよの世界観が出ていて懐かしい気持ちになります。矢印キーでタピオカミルクティーを移動させながらパズルを消していく点がおもしろいと思います。隣合うタピオカミルクティーの座標を入れ替えるロジックがよくできています。そもそも、タピオカミルクティーを使うという発想が秀逸です。


Pythonで記述したコード
import tkinter
import random
import pygame

#変数と定数の設定
index = 0
timer = 0
score = 0
cursor_x = 0
cursor_y = 0
mouse_x = 0
mouse_y = 0
mouse_c = 0
key = ""
#マウス移動の関数
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
#二次元リスト
tapioka=[]
check=[]

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

def draw_tapioka():
    cvs.delete("tapioka")
    for y in range(10):
        for x in range(8):
            cvs.create_image(x*55.5+46,y*55.5+46,image=タピオカブロック[tapioka[y][x]]
                             ,tag="tapioka")

def check_tapioka():
    for y in range(10):
        for x in range(8):
            check[y][x]=tapioka[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]:
                    tapioka[y-1][x]=5
                    tapioka[y][x]=5
                    tapioka[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]:
                    tapioka[y][x-1]=5
                    tapioka[y][x]=5
                    tapioka[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]:
                    tapioka[y-1][x-1]=5
                    tapioka[y][x]=5
                    tapioka[y+1][x+1]=5
                if check[y+1][x-1] == check[y][x] and check[y-1][x+1] == check[y][x]:
                    tapioka[y+1][x-1]=5
                    tapioka[y][x]=5
                    tapioka[y-1][x+1]=5
#タピオカを消す
def sweep_tapioka():
    num = 0
    for y in range(10):
        for x in range(8):
            if tapioka[y][x] == 5:
                tapioka[y][x] = 0
                magic_spell.play()
                num = num + 1
    return num

#タピオカを落下させる関数
def drop_tapioka():
    flg = False
    for y in range(8,-1,-1):
        for x in range(8):
            if tapioka[y][x] !=0 and tapioka[y+1][x] ==0:
                tapioka[y+1][x] = tapioka[y][x]
                tapioka[y][x] = 0
                flg = True
    return flg


#最上段に達したかを調べる関数
def over_tapioka():
    for x in range(8):
        if tapioka[0][x]>0:
            return True
    return False

#最上段にタピオカをセットする関数
def set_tapioka():
    for x in range(8):
        tapioka[0][x]= random.randint(1,4)

#影付きの文字列を表示する関数
def draw_txt(txt,x,y,siz,col,tg):
    fnt = ("HG丸ゴシックM-PRO",siz,"bold")
    cvs.create_text(x+2,y+2,text= txt,fill="black",fon=fnt,tag=tg)#影の部分
    cvs.create_text(x,y,text=txt,fill=col,font=fnt,tag=tg)#文字の部分

#キーの操作
def key_down(e):
    global key
    key = e.keysym

def BGM():
    bgm.play(-1)

#メインの処理
def game_main():
    global index,timer,score
    global cursor_x,cursor_y,mouse_c,key
    if index == 0:
        draw_txt("タピオカパズル",240,240,45,"violet","TITLE")
        draw_txt("クリックしてスタート",212,550,30,"orange","TITLE")
        index = 1
        mouse_c = 0
    elif index == 1:
        if mouse_c == 1:
            for y in range(10):
                for x in range(8):
                    tapioka[y][x]= 0
            mouse_c = 0
            score = 0
            cursor_x = 0
            cursor_y = 0
            set_tapioka
            draw_tapioka()
            cvs.delete("TITLE")
            index = 2
    elif index == 2:
        if drop_tapioka() == False:
            index = 3
        draw_tapioka()
    elif index == 3:
        check_tapioka()
        draw_tapioka()
        index = 4
    elif index == 4:
        sc = sweep_tapioka()
        score = score + sc*10
        if sc>0:
            index = 2
        else:
            if over_tapioka() == False:
                index = 5
            else:
                index = 6
                timer = 0
        draw_tapioka()
    elif index == 5:
        if 14 <= mouse_x and mouse_x<56*8 and 14<=mouse_y and mouse_y <56*10:
            cursor_x = int((mouse_x-14)/55.5)
            cursor_y = int((mouse_y-14)/55.5)
            if mouse_c == 1:
                mouse_c = 0
                set_tapioka()
                if key == "Up":
                    mouse_c = 0
                    tapioka[cursor_y][cursor_x]=tapioka[cursor_y-1][cursor_x]
                    tapioka[cursor_y-1][cursor_x]=check[cursor_y][cursor_x]
                    coin.play()
                    set_tapioka()
                if key == "Down":
                    mouse_c = 0
                    tapioka[cursor_y][cursor_x]=tapioka[cursor_y+1][cursor_x]
                    tapioka[cursor_y+1][cursor_x]=check[cursor_y][cursor_x]
                    coin.play()
                    set_tapioka()
                if key == "Left":
                    mouse_c = 0
                    tapioka[cursor_y][cursor_x]=tapioka[cursor_y][cursor_x-1]
                    tapioka[cursor_y][cursor_x-1]=check[cursor_y][cursor_x]
                    coin.play()
                    set_tapioka()
                if key == "Right":
                    mouse_c = 0
                    tapioka[cursor_y][cursor_x]=tapioka[cursor_y][cursor_x+1]
                    tapioka[cursor_y][cursor_x+1]=check[cursor_y][cursor_x]
                    coin.play()
                    set_tapioka()
                draw_tapioka()
                index = 2
        cvs.delete("CURSOR")
        cvs.create_image(cursor_x*55.5+46,cursor_y*55.5+46,image=カーソル
                         ,tag="CURSOR")

    elif index == 6:
        timer = timer + 1
        if timer == 1:
            draw_txt("GAME OVER",312,268,60,"red","OVER")
        if timer == 50:
            cvs.delete("OVER")
            index = 0
    cvs.delete("INFO")
    draw_txt("SCORE" + str(score),590,20,25,"blue","INFO")
    root.after(100,game_main)

#ウィンドウオブジェクト作成
root = tkinter.Tk()
root.title("落ち物パズル「タピオカ」")
root.resizable(False,False)
root.bind("",mouse_move)
root.bind("",mouse_press)
root.bind("",key_down)
cvs = tkinter.Canvas(root,width=700,height=590)
cvs.pack()
#画像アップロード
背景画像 = tkinter.PhotoImage(file =r"image\tapioka_bg.png")
カーソル = tkinter.PhotoImage(file =r"image\tapioka_cursor.png")
タピオカブロック = [
    None,
    tkinter.PhotoImage(file = r"image\tapioka1.png"),
    tkinter.PhotoImage(file = r"image\tapioka2.png"),
    tkinter.PhotoImage(file = r"image\tapioka3.png"),
    tkinter.PhotoImage(file = r"image\tapioka4.png"),
    tkinter.PhotoImage(file = r"image\消す.png")
]
#効果音
pygame.init()
pygame.mixer.init()
bgm=pygame.mixer.Sound("sound\BGM.mp3")
coin=pygame.mixer.Sound("sound\Coin.mp3")
magic_spell=pygame.mixer.Sound("sound\Magic-Spell.mp3")

#背景画像
cvs.create_image(350,295,image=背景画像)
cvs.create_text(595,280,text="【ルール説明】\n\n①\nクリックする\nとタピオカが\n落下する。\n\n②\nタピオカにカー\nソルをあてて、\n矢印キーを押し\nながらクリック\nすると矢印キー\nの方向にタピオ\nカが転がる。"
                ,fill = "blue",font=("HG丸ゴシックM-PRO",23))
BGM()
game_main()
root.mainloop()