色塗りゲームで知識がつく




<dd>今回は、ゲームを作りながら学習できる“pythonで作るゲーム開発入門講座”という参考書を元に動くものを作っていきます。[本はこちら](https://www.bing.com/images/search?view=detailV2&ccid=AbtEhTya&id=7E2DA8CB2A20DE83EA9AB6CC4074B252DF39F6AF&thid=OIP.AbtEhTyaPpegCWKPCJSTxwHaHa&mediaurl=https%3a%2f%2fimage.yodobashi.com%2fproduct%2f100%2f000%2f009%2f003%2f165%2f650%2f100000009003165650_10204_002.jpg&exph=600&expw=600&q=python%e3%81%a7%e3%81%a4%e3%81%8f%e3%82%8b+%e3%82%b2%e3%83%bc%e3%83%a0%e9%96%8b%e7%99%ba+%e6%9c%ac&simid=608017070762690198&ck=D5C4B95776AEB29E8285BAB7D309FA61&selectedIndex=1&ajaxhist=0
)


＊マイク機能が使えないので順を追ってみてください

---







#after()命令を行う


```python:
import tkinter
tmr = 0
def count_up():
    global tmr
    tmr = tmr + 1
    label["text"] = tmr
    root.after(1000, count_up)

root = tkinter.Tk()
label = tkinter.Label(font=("Times New Roman", 80))
label.pack()
root.after(1000, count_up)
root.mainloop()
```

+ tmrを自由度の高いグローバル関数として宣言
+ ラベルにtmrの値を表示
+ １秒後に関数を実行
+ packで部品の配置
+ 1秒後に指定の関数を呼び出す
+ after(ミリ秒、実行関数）
+ 12行目でcountを呼び出し、7行目で再度実行

実行結果


![ezgif-4-974e0f7f28b9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/c0b1a76f-2142-8773-01a6-4527271ef668.gif)

---

# bind()命令を使う
```python:
import tkinter
key = 0
def key_down(e):
    global key
    key = e.keycode
    print("KEY:"+str(key))

root = tkinter.Tk()
root.title("キーコードを取得")
root.bind("<KeyPress>", key_down)
root.mainloop
```

+ bind(イベント,関数名)
+ 2行目：キーコードの変数を宣言
+ 3行目：キーを押したとき実行する関数の定義
+ 5行目：押されたキーコードをkeyに代入
+ 6行目：シェルウィンドにkeyの値を出力
+ **bind()命令**でキーを押したときの処理を確定

実行結果
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/74700084-c784-b9a2-5e08-863a55dfe83f.png)

＊一度間違えたのは、打ち間違えでありシェルウィンドウの指摘を見て直す

---

#keysymの値で判定する
```python:
import tkinter

key = ""
def key_down(e):
    global key
    key = e.keysym

def main_proc():
    label["text"] = key
    root.after(100, main_proc)

root = tkinter.Tk()
root.title("リアルタイムキー入力")
root.bind("<KeyPress>", key_down)
label = tkinter.Label(font=("Time New Roman", 80))
label.pack()
main_proc()
root.mainloop()
```

+ 8行目リアルタイムの関数を定義
+ 9行目ラベルにkeyの値を表示
+ 10行目0.1秒後に実行する関数を指定
+ packで配置

実行結果
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/277ccb06-c06b-be9b-ea3c-1333c56e68b1.png)

##packの豆知識##
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/394a61e5-c425-6057-1471-11fe9f61bd18.png)

- button作りテクニック
  - fill, xで横拡大, yで縦拡大
  - padx, 外側の余白, ipad, 内側の余白

引用元[こちら](https://pg-chain.com/python-pack-grid-place
)

---


#リアルタイムにキャラを動かす

```python:
import tkinter

key = ""
def key_down(e):
    global key
    key = e.keysym
def key_up(e):
    global key
    key = ""

cx = 400
cy = 300
def main_proc():
    global cx, cy
    if key == "Up":
        cy = cy - 20
    if key == "Down":
        cy = cy + 20
    if key == "Left":
        cx = cx - 20
    if key == "Right":
        cx = cx + 20
    canvas.coords("MYCHR", cx, cy)
    root.after(100, main_proc)

root = tkinter.Tk()
root.title("キャラクターの移動")
root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)
canvas = tkinter.Canvas(width=800, height=600, bg="lightgreen")
canvas.pack()
img = tkinter.PhotoImage(file="mimi.png")
canvas.create_image(cx, cy, image=img, tag="MYCHR")
main_proc()
root.mainloop()
```

+ 13行目からキャラクターの動作について定義していく
+ cx,cy：座標
+ 23行目：coords()はキャラクターを新しい位置へ移動(tag名,座標）
+ canvas.pack()でキャンバスを配置
+ 32行目：作成した画像を変数imgに読み込む
+ create_imageでキャンバスに画像を表示

**実行結果**
![ezgif-4-974e0f7f28b9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/c6ac6958-5d1f-87b9-1849-07ad0310e82d.gif)

+ キーで画像を操作できるようになる

<dd>画像はペイントで作成しましたが好きなアプリを使いましょう

###今回の注意点
プログラムは間違っていないのに、Runするとそのようなファイルはありませんと表示された。なぜなのか。先生に伺うと、同じディレクトリである必要があるとのこと。今回のプログラムで指されるファイルは同じ場所に保存されたファイルであるので、注意しておきたい。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/033ee936-0a8c-8fdb-6aec-da030e217c52.png)
＊このようにまとめておく

---

# 迷路の中を歩く

## 迷路のデータを定義する
```python:
import tkinter
root = tkinter.Tk()
root.title("迷路の表示")
canvas = tkinter.Canvas(width=800, height=560, bg="white")
canvas.pack()
maze = [
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,0,0,0,1,0,0,1],
    [1,0,1,1,0,0,1,0,0,1],
    [1,0,0,1,0,0,0,0,0,1],
    [1,0,0,1,1,1,1,1,0,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
    ]
for y in range(7):
    for x in range(10):
        if maze[y][x] == 1:
            canvas.create_rectangle(x*80, y*80, x*80+80, y*80+80, fill="gray")
root.mainloop()
```

###二重ループのfor
<dd>for　変数1　in　変数１の範囲：
　　<dd>for　変数２　in　変数２の範囲：

- 二次元リストで定義
 - リスト名：maze
 - 横並びは行
 - maze[x][y]が１なら灰色に描画

##実行結果
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/82dd5683-4b48-a6c0-aeca-1d2f1c88d327.png)

---

##応用して作ってみる
```python:
import tkinter

key = ""
def key_down(e):
    global key
    key = e.keysym
def key_up(e):
    global key
    key = ""

mx = 1
my = 1
def main_proc():
    global mx, my
    if key == "Up" and maze[my-1][mx] == 0:
        my = my - 1
    if key == "Down" and maze[my+1][mx] == 0:
        my = my + 1
    if key == "Left" and maze[my][mx-1] == 0:
        mx = mx - 1
    if key == "Right" and maze[my][mx+1] == 0:
        mx = mx + 1
    canvas.coords("MYCHR", mx*80+40, my*80+40)
    root.after(300, main_proc)

root = tkinter.Tk()
root.title("迷路内を移動する")
root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)
canvas = tkinter.Canvas(width=800, height=560, bg="white")
canvas.pack()

maze = [
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,0,0,0,1,0,0,1],
    [1,0,1,1,0,0,1,0,0,1],
    [1,0,0,1,0,0,0,0,0,1],
    [1,0,0,1,1,1,1,1,0,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
    ]
for y in range(7):
    for x in range(10):
        if maze[y][x] == 1:
            canvas.create_rectangle(x*80, y*80, x*80+79, y*80+79, fill="darkturquoise", width=0)

img = tkinter.PhotoImage(file="cookie_s.png")
canvas.create_image(mx*80+40, my*80+40, image=img, tag="MYCHR")
main_proc()
root.mainloop()
```
- my,mxをグローバル関数として扱い、移動操作ができるようにする
 - andの内容としては、方向キーがタップされるかつタップされた方向が通路であった場合のみ進めるような処理である
 - maze[x][y]が１である場合、つまり壁である場合☞rectangle(x1,y1,x2,y2,塗色）
 - create_image関数で画像が中央にくるように＋４０とする

## 実行結果
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/2e58699e-7992-5d7b-696b-9014be74bbbe.gif)

---

#完成させる（クリアの判定を含む）

```python:
import tkinter
import tkinter.messagebox

key = ""
def key_down(e):
    global key
    key = e.keysym
def key_up(e):
    global key
    key = ""

mx = 1
my = 1
yuka = 0
def main_proc():
    global mx, my, yuka
    if key == "Up" and maze[my-1][mx] == 0:
        my = my - 1
    if key == "Down" and maze[my+1][mx] == 0:
        my = my + 1
    if key == "Left" and maze[my][mx-1] == 0:
        mx = mx - 1
    if key == "Right" and maze[my][mx+1] == 0:
        mx = mx + 1
    if maze[my][mx] == 0:
        maze[my][mx] = 2
        yuka = yuka + 1
        canvas.create_rectangle(mx*80, my*80, mx*80+79, my*80+79, fill="plum", width=0)
    canvas.delete("MYCHR")
    canvas.create_image(mx*80+40, my*80+40, image=img, tag="MYCHR")
    if yuka == 30:
        canvas.update()
        tkinter.messagebox.showinfo("God！", "クリアである")
    else:
        root.after(300, main_proc)

root = tkinter.Tk()
root.title("迷路を塗るゾ")
root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)
canvas = tkinter.Canvas(width=800, height=560, bg="white")
canvas.pack()

maze = [
    [1,1,1,1,1,1,1,1,1,1],
    [1,0,0,0,0,0,1,0,0,1],
    [1,0,1,1,0,0,1,0,0,1],
    [1,0,0,1,0,0,0,0,0,1],
    [1,0,0,1,1,1,1,1,0,1],
    [1,0,0,0,0,0,0,0,0,1],
    [1,1,1,1,1,1,1,1,1,1]
    ]
for y in range(7):
    for x in range(10):
        if maze[y][x] == 1:
            canvas.create_rectangle(x*80, y*80, x*80+79, y*80+79, fill="mediumturquoise", width=0)

img = tkinter.PhotoImage(file="monster.png")
canvas.create_image(mx*80+40, my*80+40, image=img, tag="MYCHR")
main_proc()
root.mainloop()
```

+ これまでの知識+クリア判定とメッセージ
<dd>if yuka == 30:   canvas.update()👈30箇所の床が塗られたらキャンバスを更新

+ 塗られた箇所が30に満たない場合は、else:root.after()でリアルタイム処理を続ける
+ ＊前回同様にファイルが見つからないというエラーが出た。今回は.pngの付け忘れだった。ファイル名には必ず拡張子を忘れずにつけること（↓参照）

##気付かずにミスしまくる
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/8ee51689-3855-459d-314c-712235d2c2e5.png)


##実行結果
![ezgif-4-974e0f7f28b9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638202/d9b7db36-f3ab-1791-12dc-282dc7567a2f.gif)

---

#感想
分かりやすく書かれたものを参考にしてまねて作っていったが、段階を踏んで組み合わせることが実践につながると感じた。何度も失敗したがするうちに失敗のパターンが見えてきた気がする。