概要
Pygameには、メニューを実装しておらず、当然PopUpみたい機能がなく、Buttonすら用意されていないため、かなり下位レベルから作りこむ必要があった。
たたし、今回はChatGPTを借りて、Buttonグループを一元管理することで簡単に切り替えることが可能。
PopUpを一所懸命につくろうとしたが、なんだかあったり、ChatGPTちゃんが簡単にできてしまった。
あと、Alpha表示において、残像が残る問題があって、未だに解決していない。
以下は、これまでの完成画面
今回は作り途中のソースが整理されていない状態なので、Battleクラスは、スキップする
Buttonクラス
今回は、マウス操作によるメニューを作っているの、Buttonクラスを整理しました。
このコードは、Pygame を用いてボタンを描画し、ホバーやクリックなどの動作を実現するクラス Button
の実装です。以下で各部分を詳しく説明します。
コンストラクタ __init__(self, x, y, width, height, text, action)
このメソッドは、ボタンオブジェクトを初期化します。
-
x, y, width, height
: ボタンの位置とサイズを指定します。-
self.rect
はボタンの矩形領域を表します。
-
-
text
: ボタンに表示するテキスト。-
self.text
に保存します。
-
-
action
: ボタンがクリックされたときに実行される関数。- これを
self.action
に保存します。
- これを
-
self.color, self.hover_color
:-
self.color
: 通常時のボタンの背景色 (青)。 -
self.hover_color
: マウスホバー時のボタンの背景色 (赤)。
-
-
self.font
: ボタンに表示するテキストのフォント。- 外部フォント
Meiryo.ttf
を使用しています。
- 外部フォント
-
self.text_surface
:- 指定されたテキストを描画するための
Surface
オブジェクト。 - フォントを使用して白色で描画しています。
- 指定されたテキストを描画するための
-
self.text_rect
:- テキストの位置をボタンの中央に配置するための矩形。
-
self.current_color
:- ボタンの現在の色を保持します。通常時は
self.color
を初期値とします。
- ボタンの現在の色を保持します。通常時は
draw(self, screen)
このメソッドは、ボタンを画面に描画します。
-
マウス位置の取得:
mouse_pos = pg.mouse.get_pos()
-
ホバー判定:
- マウスがボタン領域(
self.rect
)に重なっているかを判定します。if self.rect.collidepoint(mouse_pos): self.current_color = self.hover_color else: self.current_color = self.color
- マウスがボタン領域(
-
ボタン背景の描画:
- 判定結果に基づき、
self.current_color
を背景色としてボタンの矩形を描画します。pg.draw.rect(screen, self.current_color, self.rect, border_radius=5)
-
border_radius=5
によりボタンの角が少し丸くなります。
-
- 判定結果に基づき、
-
テキストの描画:
- テキストは事前に生成した
self.text_surface
を使い、矩形self.text_rect
の位置に描画します。screen.blit(self.text_surface, self.text_rect)
- テキストは事前に生成した
check_click(self, mouse_pos)
このメソッドは、指定されたマウスの位置(クリックされた位置)がボタン内にあるかを判定します。
-
マウス位置判定:
return self.rect.collidepoint(mouse_pos)
-
self.rect.collidepoint(mouse_pos)
は、mouse_pos
がボタンの矩形領域内に含まれている場合にTrue
を返します。 - この結果を返すことで、ボタンがクリックされたかどうかを判定します。
-
動作フロー
-
初期化時:
- ボタンの位置、サイズ、テキスト、背景色などが設定されます。
-
描画時:
-
draw
メソッドが呼ばれると、現在のマウス位置に基づいてボタンの色が変更され、テキストと背景が描画されます。
-
-
クリック判定:
-
check_click
を使用して、クリック位置がボタン内にあるかを判定します。 - クリック位置がボタン内にあれば、
self.action()
を実行する仕組みと組み合わせることで動作を実現します。
-
例: ボタンの利用
以下のようにボタンを生成し、イベントループで draw
や check_click
を呼び出して動作させます。
# ボタンの生成
button = Button(100, 100, 150, 50, "Click Me", lambda: print("Button Clicked!"))
# ゲームループ
running = True
while running:
screen.fill((0, 0, 0)) # 背景をクリア
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.MOUSEBUTTONDOWN:
if button.check_click(pg.mouse.get_pos()):
button.action() # ボタンのアクションを実行
button.draw(screen) # ボタンを描画
pg.display.flip()
pg.quit()
ポイント
-
テキストの中央揃え:
-
self.text_rect
を使用して、テキストをボタンの中心に配置しています。
-
-
ホバーの視覚効果:
-
self.current_color
を切り替えることで、ホバー時に色が変わる視覚効果を実現しています。
-
-
クリック判定の分離:
- ボタン内部のクリック判定 (
check_click
) を独立させることで、柔軟なイベント処理が可能になります。
- ボタン内部のクリック判定 (
このクラスは、シンプルで柔軟なボタン機能を提供します。