Pythonアプリ(9):お金キャッチゲームを作ろう
1.まず、1個のボタンを落下させよう
ボタンが上から下へ落下するプログラムを作りましょう。下まで行ったら上から落下し直すのを繰り返します。placeメソッドを使っています。
from tentoapp import *import random
def move(): global b b.y += 1 b.place(b.x,b.y,b.w,b.h) if b.y > 400: b.x = random.randrange(0, 500) # 600だと、右端に隠れてしまう b.y = 0 app.after(10,move)
app = App()app.size(600,400)
b = Button(app)b.x = random.randrange(0, 500) # (0,600)では右端に隠れてしまうb.y = 0b.w = 100b.h = 30
app.after(1000,move)app.start()
関数 move()
の中で app.after(10,move)
を呼び出すことで、ループを作っています。その中で、 b.y += 1
をすることによって、ボタンを落下させています。
ボタンが下( b.y > 400
)まで落下すると、上( b.y = 0
)から落下し直します。
2.落下してきたボタンをキャッチできるようにしよう
落下中のボタンをマウスでクリック(キャッチ)したら、上から落下し直すようにしましょう。
from tentoapp import *import random
def init(): global b b = Button(app) b_set()
def b_set(): global b b.x = random.randrange(0, 500) b.y = 0 b.w = 100 b.h = 30 b.onclick = clicked
def move(): global b b.y += 1 b.place(b.x,b.y,b.w,b.h) if b.y > 400: b_set(b) app.after(10,move)
def clicked(): b_set()
app = App()app.size(600,400)
init()app.after(1000,move)app.start()
これまでメインルーチンの所にあったボタンのインスタンス化や初期設定( b = Button(app)
~ b.h = 30
)は、関数 init()
や b_set()
にまとめました。
ボタンをクリックすると関数 clicked()
が呼び出され、ボタンは上から落下し直します。
3.複数のボタンを落下させよう
ボタンを複数にします。ボタンが複数の場合、インスタンス化や初期設定もそれぞれ行わなければなりません。これは init()
関数の中で、for文を使って行います。ここで生成されたButtonオブジェクト b
は関数 b_set()
で初期設定された後、リスト bList
に次々に追加されます。
なお、 bList.append(b)
でbListに追加されるのは b
という変数ではなく、forループの中で次々に生成されるButtonオブジェクト b
のアドレス(のようなもの)が追加されます。
また、ボタンが複数になると、どのButtonオブジェクトを処理(上から落ち始めるように設定)するのかを指定しなければなりません。そのため、関数 b_set()
では引数を指定するようにします。
このため、関数init()
、 b_set()
は下記のようになります。
def init(): global bList for i in range(n): b = Button(app) b_set(b) bList.append(b)
def b_set(b): global bList b.x = random.randrange(0, 500) b.y = random.randrange(-400, 0) #(注) b.w = 100 b.h = 30 b.onclick = clicked
(注)これまでのようにb.y = 0とすると、複数のボタンが横一列で落下します。これを避けるために、 b.y = random.randrange(-400, 0)
としています。
リストに格納された複数のオブジェクトを順次処理したい場合は、
for 変数 in リスト:
という構文が使えます。添字(数字)を使う配列でもできますが、Pythonではこのような in リスト
の形がよく使われます。
これにより、関数 move()
は次のようになります。
def move(): global bList for b in bList: b.y += 1 b.place(b.x,b.y,b.w,b.h) if b.y > 400: b_set(b) app.after(10,move)
複数のウェジット(ここではButtonオブジェクト)があって、どのウェジットがクリックされたかを判別したいときは、下記のように 引数.widget
で判別します。
def clicked(e): eb = e.widget b_set(eb)
メインルーチンの部分も、下記のようになります。
n = 10bList = []
app = App()app.size(600,400)
init()app.after(1000,move)app.start()
4.各ボタンに金額を付けよう
各ボタンにランダムで金額を付け、表示させましょう。プラスの金額だけでなく、マイナスの金額も付けるとゲームとして面白くなるでしょう。
下記は、ボタンの数(n)によって出現する金額が変わるようにした例です。
def b_set(b): global bList b.x = random.randrange(0, 500) b.y = random.randrange(-400, 0) b.yen = 10 * random.randint(-n,n) b.text = str(b.yen)+"円" b.fontsize = 20 b.w = 100 b.h = 30 b.onclick = clicked
5.キャッチした合計金額を表示しよう
キャッチした合計金額を表示するようにしましょう。
プログラム全体はこのようになります。
from tentoapp import *import random
def init(): global bList for i in range(n): b = Button(app) b_set(b) bList.append(b)
def b_set(b): global bList b.x = random.randrange(0, 500) b.y = random.randrange(-400, 0) b.yen = 10 * random.randint(-n,n) b.text = str(b.yen)+"円" b.fontsize = 20 b.w = 100 b.h = 30 b.onclick = clicked
def move(): global bList for b in bList: b.y += 1 b.place(b.x,b.y,b.w,b.h) if b.y > 400: b_set(b) app.after(10,move)
def clicked(e): global money, get eb = e.widget money += eb.yen get.text = str(money) + "円" get.place(150,100) b_set(eb)
n = 10money = 0bList = []
app = App()app.size(600,400)
get = Label(app)get.text = "0円"get.fontsize = 100get.place(150,100)
init()app.after(1000,move)app.start()
やってみよう
1. 見逃し金額も表示しよう。☆
見逃したボタン全部を合計するのではなく、プラスの金額だけを合計すると悔しくなって面白いよ。
2. キャッチした時に音が鳴るようにしよう。☆☆
金額がプラスの場合とマイナスの場合では違う音にしてみよう。
3. 金額によってボタンの大きさや落下速度を変えよう。☆☆☆
4. 改造してみよう
その他、タイマーを設けたり、ボタンをお札の画像にしたり、キャッチした時に爆発したりしてみよう。