31
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-10
1 / 10
今回は、ゲームを作りながら学習できる“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()命令を行う

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の値を表示
  • 1秒後に関数を実行
  • packで部品の配置
  • 1秒後に指定の関数を呼び出す
  • after(ミリ秒、実行関数)
  • 12行目でcountを呼び出し、7行目で再度実行

実行結果

ezgif-4-974e0f7f28b9.gif


bind()命令を使う

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

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


#keysymの値で判定する

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

##packの豆知識##
キャプチャ.PNG

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

引用元こちら


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

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

  • キーで画像を操作できるようになる
画像はペイントで作成しましたが好きなアプリを使いましょう

###今回の注意点
プログラムは間違っていないのに、Runするとそのようなファイルはありませんと表示された。なぜなのか。先生に伺うと、同じディレクトリである必要があるとのこと。今回のプログラムで指されるファイルは同じ場所に保存されたファイルであるので、注意しておきたい。
キャプチャ.PNG
*このようにまとめておく


迷路の中を歩く

迷路のデータを定義する

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

for 変数1 in 変数1の範囲:   
for 変数2 in 変数2の範囲:
  • 二次元リストで定義
  • リスト名:maze
  • 横並びは行
  • maze[x][y]が1なら灰色に描画

##実行結果
キャプチャ.PNG


##応用して作ってみる

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]が1である場合、つまり壁である場合☞rectangle(x1,y1,x2,y2,塗色)
  • create_image関数で画像が中央にくるように+40とする

実行結果

ezgif.com-video-to-gif.gif


#完成させる(クリアの判定を含む)

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()
  • これまでの知識+クリア判定とメッセージ
if yuka == 30: canvas.update()👈30箇所の床が塗られたらキャンバスを更新
  • 塗られた箇所が30に満たない場合は、else:root.after()でリアルタイム処理を続ける
  • *前回同様にファイルが見つからないというエラーが出た。今回は.pngの付け忘れだった。ファイル名には必ず拡張子を忘れずにつけること(↓参照)

##気付かずにミスしまくる
キャプチャ.PNG

##実行結果
ezgif-4-974e0f7f28b9.gif


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

31
43
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?