個人でゲーム開発をしている中で、実装に苦労した部分が多かったので、テクニックとして紹介していこうと思います。
今回は「ボタン連打抑止」について書きます。
問題点
キーボードのEnterキーや方向キー、マウスクリックなどゲーム中ではボタン押下をトリガーにしていました。
すると、ある画面でEnterキーを連打すると、次の画面が表示されていないのに、すでにEnterキーが押された判定になってしまい、Enterキーを押していないのに勝手に処理が進むという事象に遭遇しました。
対策
ボタン押下というイベントがキューに溜まっていく仕様は理解しました。
とりあえず次の画面が表示されるまである程度Enterキーを連打しても大丈夫にしたいと考え、最終的には以下のコードになりました。
def is_wait(self):
"""
指定時間の間イベントを受け付けない
"""
if self.WAIT != 0 and self.START_TIME is not None:
if pg3.time.get_ticks() - self.START_TIME > self.WAIT:
# ウェイト終了
self.WAIT = 0
self.START_TIME = None
return False
else:
return True
return False
まずはウェイト判定をする関数です。
「self.WAIT」には待ちたい時間を入れておきます。
「self.START_TIME」にはウェイトを開始する時間を入れておきます。
あとは現在時間から開始時間を引いた値が待ち時間を超えるかどうかを判定しています。
ウェイトが終わった時点で、待ち時間と開始時間はリセットします。
def set_wait(self, wait):
"""
ウェイト関連の情報をセットする
"""
self.START_TIME = pg3.time.get_ticks()
self.WAIT = wait
次にウェイトしたいところで呼ぶ関数です。
待ち時間と開始時間をセットしています。
for event in pg3.event.get():
# ウェイト中はボタン無効化
if state.is_wait():
continue
if event.type == pg3.KEYDOWN and event.key == pg3.K_RETURN:
state.set_wait(1000)
使い方としてはこんな感じです。
ゲーム状態を管理するクラスを作っていたので、先ほどの関数はそのクラスで定義してあります。
Enterキーが押されたときに「set_wait(1000)」で1秒セットします。
「is_wait()」が1秒間Trueを返し続けるので、キー判定の処理に来る前にcontinueされて、次のボタン押下が無視されるという流れです。
待ち時間の「1000」の部分は実際にプレイして調整していました。
「ボタン連打抑止」に関しては以上となります。
リリース済みのゲームはこちら
・PC向け無料ゲーム
『LAbyrinth』(2Dの迷路探索ゲーム)
●Freem!
https://www.freem.ne.jp/win/game/33791
●Unityroom
https://unityroom.com/games/2025-labyrinth-isukaka