Menu
CoddyTech

ヒットストップ

CoddyのPygameジャーニー「サウンドとゲームの手応え」セクションの一部。レッスン 14/23。

大きな一撃は、ゲームが一瞬だけ止まると、より強く感じられます。格闘ゲームやアクションゲームではよく使われる演出です。強い一撃を受けると、数フレームの間すべてが停止し、その後また動き出します。これはヒットストップと呼ばれます。

停止する残りフレーム数を数えるカウンターを使います。値が0より大きい間は、カウントダウンして更新処理全体をスキップします。描画は続けるので、停止した瞬間が画面に残ります。

if freeze > 0:
    freeze -= 1
else:
    enemy.x += enemy_speed
    # ... 更新処理の残り

重要な一撃のときだけ設定します。ここでは3回目の攻撃で敵を倒すため、その攻撃で freeze = 12 を設定します。これは5分の1秒です。小さな攻撃のたびに停止すると、力強さではなく、動きが引っかかるように感じられます。

フラッシュカウンターも更新処理の一部なので、同じように待機します。敵は停止中ずっと白く光り、爆発音が鳴り、その後ゲームが再開します。停止中もイベントは処理されるため、その間にキーを押したプレイヤーの入力が無視されることはありません。ここでは、hp > 0 のときだけ Space で攻撃できます。

challenge icon

チャレンジ

中級

敵は左右に移動し、スペースキーで3回攻撃すると倒せます。敵を倒した攻撃のときにゲームを一時停止します。

  1. ループの前に freeze = 0 を設定します。
  2. 攻撃によって hp が0になったところで、freeze = 12 を設定します。
  3. 更新処理では、freeze が0より大きい間、値を1減らし、更新処理内のほかの処理をすべてスキップします。描画処理はそのままにします。

自分で試してみよう

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Training Dummy")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)

hit_sound = pygame.mixer.Sound("assets/sounds/hit.ogg")
explosion_sound = pygame.mixer.Sound("assets/sounds/explosion.ogg")
enemy = pygame.Rect(100, 150, 60, 60)
enemy_speed = 2
hp = 3
flash = 0
defeated = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and hp > 0:
            hp -= 1
            flash = 6
            if hp == 0:
                explosion_sound.play()
            else:
                hit_sound.play()

    enemy.x += enemy_speed
    if enemy.left < 40 or enemy.right > 440:
        enemy_speed = -enemy_speed
    if flash > 0:
        flash -= 1
    if hp == 0:
        defeated += 1
        hp = 3
        enemy.x = 100

    screen.fill((30, 30, 46))
    if flash > 0:
        pygame.draw.rect(screen, (255, 255, 255), enemy)
    else:
        pygame.draw.rect(screen, (220, 80, 80), enemy)
    label = font.render(f"HP: {hp}   Defeated: {defeated}", True, (240, 240, 240))
    screen.blit(label, (20, 20))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

サウンドとゲームの手応えのすべてのレッスン

自分で練習してみよう: Pygameプレイグラウンド