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 = clicked5.キャッチした合計金額を表示しよう
キャッチした合計金額を表示するようにしましょう。
プログラム全体はこのようになります。
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. 改造してみよう
その他、タイマーを設けたり、ボタンをお札の画像にしたり、キャッチした時に爆発したりしてみよう。