Python でつくるガイスター、連載第 3 回です。
はグリッドやボタンを描画しました。今回はマウス操作でグリッドに駒を置いたり、ボタンを押したりできるようにします。
クリックで駒を置く
pygame ではpygame.event.get()
からイベントを取得し、event.type
でイベントの種類(マウス、キーボードなど)を取得します。
マウスクリックならevent.type == MOUSEBUTTONDOWN
で、
左クリックならさらにevent.button == 1
、右クリックでならevent.button == 3
という条件がつきます。
マウスカーソルの位置はevent.pos
から読み込めます。
クリックの種類とマウスカーソルの位置を表示するコードは次のようになります。
main.py1...2def main():3...4while True:5...6for event in pygame.event.get():7# マウスクリック8if event.type == MOUSEBUTTONDOWN:9# 左10if event.button == 1:11print('left:', event.pos)12# 右13elif event.button == 3:14print('right:', event.pos)
これで取得できる座標はウィンドウ座標ですが、扱いやすいようにゲーム内の座標に変換します。
座標変換
マウスで特定の位置をクリックしたとき、そのマス目の座標((1, 2) など)を返すようにします。
この関数はマウス関連の処理をまとめるモジュールに定義します。
mouse.py1from config import *23def chcoord(pos):4'''5座標 pos がどのマス上にあるかその位置を返す6-> tuple <- (int, int)7(0, 0)│...│(5, 0)8──────┼───┼──────9...10──────┼───┼──────11(5, 0)│...│(5, 5)1213pos : tuple <- (int, int)14対象の座標15'''16return (pos-MARGIN)//SQUARE_SIZE
これでゲーム内の座標が取得できるので、クリックした位置がどこかを判定して、
そのマスの中に駒を置いていきます。
駒を置く
駒がどのように配置されているかを表す変数を用意して、クリックしたときにその変数を変更します。
main.py1...2import draw, mouse34def main():5...6# 配置を決定する側7# 0 - 先攻, 1 - 後攻8_state = 09# 決定された初期配置と色10# [{(int, int): str}]11_order = [{}, {}]12...13while True:14screen.fill(IVORY)15draw.setup(screen, font, _state)16pygame.display.update()17# イベントハンドリング18for event in pygame.event.get():19...20# マウスクリック21if event.type == MOUSEBUTTONDOWN:22# 左23if event.button == 1:24_mouse_pos = event.pos25_square_pos = tuple(mouse.chcoord(_mouse_pos))26for i in range(1, 5):27for j in range(2, 4):28if _square_pos == (i, j):29_order[_state][(i, j)] = 'R'30# 右31elif event.button == 3:32_mouse_pos = event.pos33_square_pos = tuple(mouse.chcoord(_mouse_pos))34for i in range(1, 5):35for j in range(2, 4):36if _square_pos == (i, j):37_order[_state][(i, j)] = 'B'38...
その変数にしたがって駒を描画するようにします。
draw.py1...2def setup(screen, font, turn):3def setup(screen, font, turn, posdict):4'''5...6posdict : dict <- {(int, int): str}7どの位置にどの色の駒が置かれているかを表す辞書8'''9...10for (x, y), s in posdict.items():11_piece(screen, RED if s == 'R' else BLUE, (x, y))12...
main.py1...2def main():3...4while True:5screen.fill(IVORY)6draw.setup(screen, font, _state, _order[_state])7...
ボタンを押す
ボタン上にマウスカーソルがあるときに左クリックすると何らかのアクションを起こすようにします。
駒は赤と青 4 個ずつでなければならないので、その条件を満たさないとボタンが押せないようにします。
条件を満たしているか判定する関数を定義します。
main.py1...2def _check_color(colors):3'''4駒がすべて配置済みで赤と青が半分ずつあるか5-> bool67colors : list <- [str]8色のリスト9'''10return (len(colors) == 811and len([s for s in colors if s == 'R'])12== len([s for s in colors if s == 'B']))13...
マウスの座標がボタンにのっているか調べるため、別の関数も定義します。
(左上のほうが座標が小さいことに注意)
mouse.py1...2def on_area(x, y, left, top, w, h):3'''4座標 x, y が範囲内にあるか5-> bool67x, y : int8対象の座標9left, top : int10範囲の左・上端の座標11w, h : int12範囲の横・縦幅13'''14return left <= x <= left+w and top <= y <= top+h15...
そして、条件を満たしているときかつボタンがクリックされたときにのみ次の画面に進むことができます。
main.py1...2def main():3...4while True:5satisfied = _check_color(list(_order[_state].values()))6...7# 左8if event.button == 1:9...10if mouse.on_area(*_mouse_pos, 500, 530, 80, 50):11if satisfied:12_state += 113...
さらに、ボタンが押せるときと押せないときでボタンの色を変えます。
draw.py1...2def setup(screen, font, turn, posdict):3def setup(screen, font, turn, posdict, disabled):4'''5...6disabled : bool7ボタンを押せない8'''9...10_button(screen, font, (500, 530), (80, 50), 'OK')11_button(screen, font, (500, 530), (80, 50), 'OK', disabled)12...
main.py1...2def main():3...4while True:5...6draw.setup(screen, font, _state, _order[_state], not satisfied)7...
これで、駒が適切に配置されたときにのみボタンが押せるようになります。
右下のボタンの色が変わっていることがわかると思います。
効果音をつける
おまけですが、駒を置いたときやボタンを押したときに効果音をつけてみます。
main.py1...2def main():3pygame.init()4# 音声の設定5snd = pygame.mixer.Sound6select_snd = snd('./sounds/select.wav')7decide_snd = snd('./sounds/decide.wav')8forbid_snd = snd('./sounds/forbid.wav')9...10while True:11...12# 左13if event.button == 1:14_mouse_pos = event.pos15_square_pos = tuple(mouse.chcoord(_mouse_pos))1617for i in range(1, 5):18for j in range(2, 4):19if _square_pos == (i, j):20select_snd.play()21_order[_state][(i, j)] = 'R'2223if mouse.on_area(*_mouse_pos, 500, 530, 80, 50):24if satisfied:25decide_snd.play()26_state += 127else:28forbid_snd.play()29...
初期化して、パスを指定して音を取り込んで、該当部分で再生するだけです。
これで駒の初期配置を選択できるようになりました。
はここで決定した配置をゲーム本番での初期配置に反映していきます。お読みいただきありがとうございました。
では