Menu
CoddyTech

Остановка при попадании

Часть раздела Звук и игровые ощущения путешествия по Pygame на Coddy. Урок 14 из 23.

Сильный удар ощущается мощнее, если игра замирает на долю секунды. В файтингах и экшен-играх так делают постоянно: при сильном ударе всё замирает на несколько кадров, а затем игра продолжается. Это называется хит-стоп.

Снова используйте счётчик, который показывает, сколько кадров осталось до конца паузы. Пока его значение больше 0, уменьшайте его и пропускайте всё обновление целиком. Продолжайте рисовать кадры, чтобы замерший момент оставался на экране:

if freeze > 0:
    freeze -= 1
else:
    enemy.x += enemy_speed
    # ... остальная часть обновления

Включайте паузу только при важных ударах. Здесь третий удар побеждает врага, поэтому при этом ударе задаётся freeze = 12 — пятая доля секунды. Если игра будет замирать после каждого слабого удара, она будет казаться вязкой, а не мощной.

Счётчик вспышки — часть обновления, поэтому он тоже ждёт: враг остаётся белым всё время паузы, звук взрыва звучит, а затем игра продолжается. События обрабатываются и во время паузы, поэтому нажатие клавиши игроком в этот момент не будет проигнорировано; здесь пробел наносит удар, только если hp > 0.

challenge icon

Задание

Средне

Враг ходит влево и вправо; три удара клавишей Space побеждают его. Заморозь игру после решающего удара:

  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