一つ前のページではマウスでキャラクターを動かす方法について学習しました。
今回は 画面にボタンを表示する方法 について見ていきましょう。
Chapter1:pygame入門|画面を表示しよう
Chapter2:簡単なノベルゲームを作ろう
- Chapter2-1:キーボードでキャラクターを動かそう
- Chapter2-2:マウスでキャラクターを動かそう
- Chapter2-3:画面にボタンを表示しよう ◁今回はここ
- Chapter2-4:紙芝居を作ろう
- Chapter2-5:ノベルゲームを作ろう
Chapter3:簡単なアクションゲームを作ろう
Chapter4:ブロック崩しを作ろう
Chapter5:シューティングゲームを作ろう
Extra1:横スクロールのアクションゲームを作ろう
ゲームを作る際、ボタンを配置することでプレイヤーが操作できる仕組みを作ることができます。
例えば「スタート」ボタンを押してゲームを開始したり、「終了」ボタンを押してゲームを終了したりするなど、ボタンを使えばゲームのインタラクティブ性を向上させることができます。
ゲームを開発する上で、ボタンの作成やクリック判定の処理を理解することは非常に重要なスキルです。
本記事では、pygame を使って画面にボタンを配置する方法を学び、ボタンがクリックされたことを検出するプログラムを作成します。
それでは、まず最初に画面にボタンを配置する方法から始めましょう。
ゲーム画面にボタン画像を配置して表示しよう
まずはpygameを使って画面にボタン画像を表示しましょう。ボタンを作成するには、以下の2つの手順を行います。
- ボタン用の画像を準備する
- 画像を指定した座標に配置する
Chapter1の復習になります。順番に実施していきましょう。
表示用のボタン画像を準備する
Chapter1-3|画面に画像を表示しよう で学習したように、pygameでは画像ファイル(PNGやJPEGなど)を pygame.image.load()
を使って読み込み、画面に表示できます。
今回は↓↓のシンプルなボタン画像を使用します。画像を右クリックして “btn.png” という名前で保存し、プログラムと同じフォルダに置いてください。
画面上にボタンを描画する方法|blit()メソッドを使おう
準備したボタン画像を画面に表示するには、blit()
メソッド を使用します。
# 初期化(ゲームの準備をする) import pygame, sys pygame.init() screen = pygame.display.set_mode((800,600)) btn_img = pygame.image.load("btn.png") # ボタン画像を読み込む # メインループ while True: screen.fill(pygame.Color("WHITE")) # 画面の初期化(背景を白に設定) btn = screen.blit(btn_img, (350, 200)) # ボタンを描画(位置をx=350, y=200に設定) pygame.display.update() # 画面を更新(描画した内容を反映) # 終了処理(ウィンドウの「×」ボタンが押されたら終了) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
このコードでは、pygameを使って 800×600のウィンドウ を作成し、ボタンの画像を (350, 200) の位置 に描画しています。
コード | 説明 |
---|---|
pygame.image.load(“btn.png”) | 画像ファイル “btn.png” を読み込む |
screen.blit(btn_img, (350, 200)) | ボタン画像を (350, 200) に描画 |
screen.fill(pygame.Color(“WHITE”)) | 背景を白にする |
pygame.display.update() | 画面の更新(ボタンを表示) |
このコードを実行すると、ウィンドウの中央付近にボタン画像が表示されます。
ボタンがクリックされたかどうかを判定する
ボタンを画面に表示することができたので、次は マウスでクリックされたことを判定する処理 を実装していきます。
ゲームにおけるボタンは、クリックすると何かのアクションが実行される仕組み になっています。それには以下の手順が必要です。
- マウスのクリック状態を取得する
- マウスカーソルの位置を取得する
- クリック位置がボタンの範囲内かを判定する
- クリックされた場合に処理を実行する
マウスの状態を取得する方法
Capter2-1で学習したように、マウスのクリック状態を取得するには pygame.mouse.get_pressed()
を使用します。
この関数は、(左ボタン, 中ボタン, 右ボタン) の3つの値を含んだタプルを返します。
値 | 意味 |
---|---|
mdown[0] | 左クリック が押されているか |
mdown[1] | ホイールボタン が押されているか |
mdown[2] | 右クリック が押されて |
また、マウスの現在の座標を取得するには、pygame.mouse.get_pos()
を使います。
この関数は、マウスの X座標とY座標のタプル を返します。
ボタンの範囲内でクリックされたかを判定する
ボタンがクリックされたかどうかを判定するには、以下の手順を行います。
- マウスの左クリックが押されているか (
mdown[0]
をチェック) - マウスの座標がボタンの範囲内にあるか (
collidepoint(mx, my)メソッド
)
if mdown[0]: # もし左クリックが押されているなら if btn.collidepoint(mx, my): # もし(mx, my)がボタンの範囲内にあるなら print("クリックされました")
すなわち「ボタン画像が描画されている座標の範囲」と「クリックされた座標」が重なっていた場合に、ボタンがクリックされたと判定します。
クリック判定を実装したコード
上記の内容を踏まえて、ボタンがクリックされたかどうかを判定するプログラムを作成してみましょう。
# 初期化(ゲームの準備をする) import pygame, sys pygame.init() screen = pygame.display.set_mode((800,600)) btn_img = pygame.image.load("btn.png") # ボタン画像を読み込む # メインループ while True: screen.fill(pygame.Color("WHITE")) # 画面の初期化(背景を白に設定) btn = screen.blit(btn_img, (350, 200)) # ボタンを描画 # マウスの状態を取得 mdown = pygame.mouse.get_pressed() # 現在クリックされているか (mx, my) = pygame.mouse.get_pos() # 現在のマウスカーソルの位置 # ボタンのクリックを判定 if mdown[0]: # もしmdown[0]がTrueなら(クリックされているなら) if btn.collidepoint(mx, my): # もし(mx, my)がボタンの範囲内にあるなら print("クリックされました") else: print("クリックされていません") # 画面を更新 pygame.display.update() pygame.time.Clock().tick(60) # 終了処理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
このプログラムを実行すると、ボタンをクリックしたときに「クリックされました」
と表示されます。
ただし、このプログラムでは、少しクリックしただけでも何回も「クリックされました」と表示されてしまいます。
1秒間に60回繰り返す処理の中で、押している間はずっと条件が満たされるためです。
そこで次の章では、クリックが1回だけ認識される仕組み(連続クリック防止) を実装していきます。
これによって、ボタンを押し続けた場合でも 1回のクリックだけが認識される処理 が可能になります。
クリックを1回だけ認識させる方法
前の章では、ボタンがクリックされたかどうかを判定する方法を学びました。しかし、実際のゲームプログラムではクリックが1回だけ認識される仕組みが重要です。
これを実現するには、フラグ変数(pushFlag
)を使ってクリックの状態を管理する 方法が有効です。
(フラグ管理、なんて言うと、いよいよゲーム開発をしてる感じがしてきましたね^^)
フラグ変数(pushFlag)で制御しよう
クリックが 1回だけ認識されるようにするには、「すでにクリックされたかどうか」を記録しておく必要があります。
そのために、フラグ変数 pushFlag
を使います。
フラグ変数の動作
- クリックされていないとき (
pushFlag == False
) → クリックを認識 - クリックされたら (
pushFlag = True
) → それ以上認識しない - ボタンが離されたら (
pushFlag = False
) → 次のクリックを認識できるようにする
この仕組みを使えば、ボタンがクリックされた瞬間に 1回だけ処理を実行し、押し続けても連続で判定されない ようにできます。
一度だけ動作させるコードの書き方
それでは、実際に pushFlag
を使って、ボタンのクリックを1回だけ認識するコードを書いてみましょう。
# 初期化(ゲームの準備をする) import pygame, sys pygame.init() screen = pygame.display.set_mode((800,600)) btn_img = pygame.image.load("btn.png") # ボタン画像を読み込む pushFlag = False # クリック状態を管理するフラグ変数 # メインループ while True: screen.fill(pygame.Color("WHITE")) # 画面の初期化(背景を白に設定) btn = screen.blit(btn_img, (350, 200)) # ボタンを描画 # マウスの状態を取得 mdown = pygame.mouse.get_pressed() # 現在クリックされているか (mx, my) = pygame.mouse.get_pos() # 現在のマウスカーソルの位置 # ボタンのクリックを1回だけ認識する処理 if mdown[0]: # もしmdown[0]がTrueなら(クリックされているなら) if btn.collidepoint(mx, my) and pushFlag == False: # もしボタンの範囲内 かつ クリックされていなかったなら print("クリックされました") pushFlag = True # クリックされたことを記録 else: pushFlag = False # クリックを解除(次のクリックを認識できるようにする) # 画面を更新 pygame.display.update() pygame.time.Clock().tick(60) # 終了処理 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit()
このコードを実行すると、ボタンをクリックしたとき 「クリックされました」 が1回だけ出力されるようになります。
処理 | 説明 |
---|---|
pushFlag = False | クリックを記録するフラグ変数(最初はFalse) |
if btn.collidepoint(mx, my) and pushFlag == False: | クリックされておらず、ボタンの範囲内なら処理を実行 |
pushFlag = True | クリックを記録し、連続クリックを防ぐ |
else: pushFlag = False | クリックが解除されたらフラグをリセット |
まとめ
今回はpygameを使って 画面にボタンを配置し、クリックを判定する方法 を学びました。
ゲームのUIとして、ボタンはとても重要な要素です。プレイヤーが操作できる仕組みを作ることで、ゲームのインタラクティブ性を高めることができます。
これらの技術を組み合わせることで、ボタンを使った ゲームのメニュー画面やシーン遷移 などを実装できるようになります。
ここまでお疲れさまでした!ゲーム開発の基礎をしっかり身につけながら、次のステップへ進んでいきましょう!
FAQ|画面にボタンを配置する方法に関するよくある質問
今回の記事に関する「よくある質問」とその解答について、以下の内容を参考にしてください。
- Q1. ボタンを配置するときに
collidepoint(mx, my)
メソッドを使う理由は何ですか? -
collidepoint(mx, my)
メソッドは、マウスクリックなどのイベントがボタンの範囲内で発生したかどうかを簡単に判定できます。これにより手動で座標を比較する手間を省き、よりシンプルで安全なコードを書けます。
- Q2. 複数のボタンを画面に配置したい場合は、どのように管理するのが効率的ですか?
-
ボタンごとに
pygame.Rect
オブジェクトを用意し、それぞれのcollidepoint
を使って判定します。リストや辞書でボタンを管理すると、ループ処理がしやすくなり、コードの可読性や拡張性も向上します。
- Q3. ボタンの見た目(デザイン)を変えたい場合、どんな方法がありますか?
-
pygame.draw.rect()
で色や枠線を変更したり、ボタンの上に画像や文字を描画することでデザインを自由にアレンジできます。押下時だけ色を変える、ホバー時にアニメーションさせるなども可能です。
画面にボタンを配置する際によくあるトラブルと解決法
今回の記事に関する「よくあるトラブル」とその原因、解決法について、以下の内容を参考にしてください。
ボタンをクリックしても何も起こらない
- トラブルの原因と対処法を見る
-
トラブルの原因
ボタンの判定に使っている
collidepoint(mx, my)
の座標引数に、pygame.mouse.get_pos()
で取得した値が正しく渡されていない場合があります。トラブルの解決法
pygame.mouse.get_pos()
で取得した座標(mx, my)が、ボタン判定のタイミングで最新のものになっているか、また値の型(タプルやint)が正しいかをソースコードで確認しましょう。また、イベントループ内で座標取得の場所が適切かどうかも確認しましょう。
ボタンの表示位置が意図した場所とずれる
- トラブルの原因と対処法を見る
-
トラブルの原因
pygame.Rect
でボタンの位置とサイズを指定する際、左上の座標やサイズの指定が意図とずれている、または座標計算が間違っていることがあります。トラブルの解決法
ボタン用の
pygame.Rect
で指定した座標値やサイズが、画面サイズや他のオブジェクトとの関係上、適切かどうかを見直しましょう。実際の値をprintで表示してデバッグしたり、座標を固定値ではなく変数や定数で一元管理してみましょう。
ボタンのクリック範囲が正しく判定されない
- トラブルの原因と対処法を見る
-
トラブルの原因
ボタンの描画と判定に使うRectオブジェクトが一致していない(例:描画時と判定時で座標やサイズが異なる)場合があります。
トラブルの解決法
ボタンの描画用と判定用のRectが同じ値になっているかを確認し、もし異なる場合は同じ変数を使うようコードを見直しましょう。
特に、ボタンのサイズや位置が動的に変わる場合は、判定用Rectも一緒に更新されているか確かめてみてください。