Pythonの練習⑪

前回、Pythonの基礎?(スイカ割りゲーム)が終わったのでGUIをしようと思ったので、kivyをダウンロードとかしたのですが、パスの関係かうまく立ちがらなかったので、Pythonを入れ直したりしました。つかないことには、練習にならないので、システムに入れ直したのですが、それでもkivyが動かなかったので、ちょっと調べます。で、

とりあえず、練習はtkinterを使用することにしました。進まないと練習になりませんし、昔ながらのGUIでいきたいと思います。perlでもちょっと使っていたので。

tkinterも最初のPythonではインストールされていなかった??ので、インストールし直しました。

tkinterは、Pythonに標準で組み込まれているのでwebからインストールとかもいらないのが強みです。他のプログラミング言語でも使われていますし。

ではやっていきます。

まず、ウィンドウをつくります。

4行目がタイトル名になり、5行目がウィンドウの大きさになります。

ボタンを追加してみました。

これで、Tkinterの概要はわかりました。

このGUIを用いて、これまでのすいか割ゲームを作ってみました。Tkinterのラベルとか、配置の意味があまりわからず時間がかかりました。人に教えてもらうのが一番だと感じましたね。

作成したコードは下記のとおりです。

import random
import math
import tkinter

def calc_distance(x1,y1,x2,y2):
    #2点間の距離を求める
    diff_x = x1 -x2
    diff_y = y1 -y2
    return math.sqrt(diff_x**2 + diff_y**2)

def start():
    global suika_x
    global suika_y
    global suika_num
    global player_num
    global player_y
    global player_x
    global distance

    suika_x = random.randrange(0,5) #すいかのx座標
    suika_y = random.randrange(0,5) #すいかのy座標
    suika_num = suika_x * 6 + suika_y

    player_x = random.randrange(0,5) #プレイヤーのx座標
    player_y = random.randrange(0,5) #プレイヤーのy座標
    player_num = player_x * 6 + player_y

    distance = calc_distance(player_x,player_y,suika_x,suika_y)
    print(player_x,player_y,player_num)

def changeText_up():
    global player_num
    global player_y
    global player_x
    global distance
    global i_data

    i_data = "No."+str(player_num)

    if player_y > 0 and player_y <= 5 :
        label[player_num]['text'] = str(i_data)
        label[player_num]['relief'] = "ridge"

        player_y = player_y - 1
        player_num = player_x * 6 + player_y

        label[player_num]['text'] = str("T")
        label[player_num]['relief'] = "flat"

        distance = calc_distance(player_x,player_y,suika_x,suika_y)

    print(player_x,player_y,player_num,i_data)
    suika_label[0]['text']= str(format(distance,'.3f'))

    if distance == 0 :
        suika_label[2]['text']= str("すいかを割りました!!!")

def changeText_down():
    global player_num
    global player_y
    global player_x
    global distance
    global i_data

    i_data = "No."+str(player_num)

    if player_y >= 0 and player_y < 5 :
        label[player_num]['text'] = str(i_data)
        label[player_num]['relief'] = "ridge"

        player_y = player_y + 1
        player_num = player_x * 6 + player_y

        label[player_num]['text'] = str("T")
        label[player_num]['relief'] = "flat"

        distance = calc_distance(player_x,player_y,suika_x,suika_y)

    print(player_x,player_y,player_num,i_data)
    suika_label[0]['text']= str(format(distance,'.3f'))

    if distance == 0 :
        suika_label[2]['text']= str("すいかを割りました!!!")

def changeText_left():
    global player_num
    global player_y
    global player_x
    global distance
    global i_data

    i_data = "No."+str(player_num)

    if player_x > 0 and player_x <= 5 :
        label[player_num]['text'] = str(i_data)
        label[player_num]['relief'] = "ridge"

        player_x = player_x - 1
        player_num = player_x * 6 + player_y

        label[player_num]['text'] = str("T")
        label[player_num]['relief'] = "flat"

        distance = calc_distance(player_x,player_y,suika_x,suika_y)

    print(player_x,player_y,player_num,i_data)
    suika_label[0]['text']= str(format(distance,'.3f'))

    if distance == 0 :
        suika_label[2]['text']= str("すいかを割りました!!!")

def changeText_right():
    global player_num
    global player_y
    global player_x
    global distance
    global i_data

    i_data = "No."+str(player_num)

    if player_x >= 0 and player_x < 5 :
        label[player_num]['text'] = str(i_data)
        label[player_num]['relief'] = "ridge"

        player_x = player_x + 1
        player_num = player_x * 6 + player_y

        label[player_num]['text'] = str("T")
        label[player_num]['relief'] = "flat"

        distance = calc_distance(player_x,player_y,suika_x,suika_y)

    print(player_x,player_y,player_num,i_data)
    suika_label[0]['text']= str(format(distance,'.3f'))

    if distance == 0 :
        suika_label[2]['text']= str("すいかを割りました!!!")

start()

frame=[]
label=[]
suika_label=[]

#window
root = tkinter.Tk()
root.title("test_tk")
root.geometry("400x300")

#frame
i = 0
while i <= 5:
    frame.append(tkinter.Frame(root, width=100, height=100, background="white", cursor="mouse"))
    i=i+1

#label
j = 0
while j <= 35:
    if j <= 5:
        label.append(tkinter.Label(frame[0],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))
    elif j <= 11:
        label.append(tkinter.Label(frame[1],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))
    elif j <= 17:
        label.append(tkinter.Label(frame[2],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))
    elif j <= 23:
        label.append(tkinter.Label(frame[3],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))
    elif j <= 29:
        label.append(tkinter.Label(frame[4],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))
    elif j <= 35:
        label.append(tkinter.Label(frame[5],text="No."+str(j+1),width=5, height=2,relief="ridge",bg="white"))

    j=j+1

frame[0].pack(side=tkinter.LEFT,anchor=tkinter.N)
frame[1].pack(side=tkinter.LEFT,anchor=tkinter.N)
frame[2].pack(side=tkinter.LEFT,anchor=tkinter.N)
frame[3].pack(side=tkinter.LEFT,anchor=tkinter.N)
frame[4].pack(side=tkinter.LEFT,anchor=tkinter.N)
frame[5].pack(side=tkinter.LEFT,anchor=tkinter.N)

x = 0
while x <= 35:
    label[x].pack()
    x=x+1

suika_label.append(tkinter.Label(text=str(format(distance,'.3f'))))
suika_label[0].place(x=280,y=70)
suika_label.append(tkinter.Label(text="すいかまでの距離"))
suika_label[1].place(x=280,y=50)
suika_label.append(tkinter.Label(text="--------"))
suika_label[2].place(x=280,y=100)

#button
button1 = tkinter.Button(root,text="up",height=1,width=4,command=changeText_up)
button1.place(x=340,y=200)
button2 = tkinter.Button(root,text="down",height=1,width=4,command=changeText_down)
button2.place(x=340,y=260)
button3 = tkinter.Button(root,text="left",height=1,width=4,command=changeText_left)
button3.place(x=320,y=230)
button4 = tkinter.Button(root,text="right",height=1,width=4,command=changeText_right)
button4.place(x=360,y=230)

#frame[1].propagate(0)

root.mainloop()

もっと綺麗な書き方が普通できるんでしょうが、個人レベルなのでこんなものです。他の方の書き方では、classを使ったりしていましたが、いまいちよくわからないので、これまで習ったことを基本に書いてみました。

流れ的には、下記の感じ。htmlでヘッダーとボディみたいな感じになっているような。

import (ライブラリの呼び出し)
変数の宣言 (流れ的にglobalで書いたけど、これは関数内だけでOKだよね)
各関数の定義
(calc_distance, start,
   changeText_up, changeText_down, changeText_left, changeText_right)
Tkinterの宣言
 frameの宣言
 labelの宣言
 buttonの宣言
main.roop()

距離の計算(calc_distance)やスイカとプレイヤーの位置決定(start)等の関数はスイカ割りゲームの物をそのまま使用しています。

ここで苦戦したのは、ラベルの配置とラベルの書き換えでしたね。

tkinterの使い方なので、あまり意味は無いのですが、pack(積み重ねる?)とplace(配置を決める)に苦戦でした。フレームの扱いもよくわからず。ラベルの配列もよくわからなくて、とりあえず、ネットを駆使してパクリで作ってみました。引用が無いような。コード丸パクリではないので大丈夫かな。

ネットってすごいですよね。よくみんなupしているなって関心します。プログラマーとか憧れますが、レベルが違い過ぎますね。めっちゃ効率化できそうだよね。

できたのがこちらです。

ブロック分けされていて、右下のup-left-right-downをどれか押します。

すると、動いた箇所にTマークが付きます。Tに意味はありません。

そして、すいかまでの距離が変更されます。1.414かなり近いですね。

leftをクリックすると、左に動き、Tの位置が変わります。そして、スイカまでの距離も変化します。この感じだと、19か21ですね。

downしてみましたが、距離が伸びてしまいました。これは、遠ざかっていますね。19確定ですね。

2回upして19に到達しました。すいかを割りました!!!が表示されました。

これまで作ったスイカ割りゲームをGUIにしたものができました。やっぱり、GUIでできるとわかりやすいですし、面白く感じます。この流れで、色々と作ることができそうですね(色を変えて一筆書きを作ったり、くじを作ったり)。ちなみに、この範囲を外れるような場合は移動できないようになっています。if文で制限をかけています。

batファイルで「python ファイルの場所」を入れれば、スイカ割りゲームがすぐに楽しめます。やらねー。

今度は、Excelとかと連携できるので、そっちをやってみようかなと思います。

ネットにいっぱい説明されているので、何でもできますね。すごい世の中です。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中