Menu
CoddyTech

Giữ hiệu ứng tinh tế

Thuộc phần Âm thanh và cảm giác chơi trong hành trình Pygame của Coddy. Bài học 15 trên 23.

Cảm giác khi chơi giống như gia vị. Rung nhẹ khiến cú tiếp đất có cảm giác nặng hơn; rung quá nhiều khiến người chơi khó theo dõi trò chơi và có thể gây chóng mặt. Hai thói quen sau giúp bạn kiểm soát điều đó.

Giới hạn mức rung. Khi các hiệu ứng chồng lên nhau, mức rung có thể tăng mãi không dừng. Ở đây, mỗi cú tiếp đất cộng thêm 12 vào shake; bốn thùng hàng tiếp đất cùng lúc khiến mức rung vượt quá 40, làm khung hình nhảy 13 pixel. min() đặt giới hạn trên cho mức rung:

shake = min(shake + 12, 18)

Giờ đây, mức rung vẫn kéo dài hơn khi các thùng hàng liên tục tiếp đất, nhưng độ dịch chuyển không bao giờ vượt quá 18 // 3, tức 6 pixel.

Cho phép người chơi tắt tính năng này. Một số người không thể chơi khi màn hình chuyển động. Bạn chỉ cần thêm một biến (variable) cho tùy chọn này:

shake_on = True
...
if shake_on:
    offset = (random.randint(-amount, amount), random.randint(-amount, amount))

Vẽ nhãn sau khi blit thế giới, trực tiếp lên màn hình. Văn bản thuộc giao diện nên đứng yên trong khi thế giới rung lắc.

challenge icon

Thử thách

Trung bình

Giảm rung và cho phép người chơi tắt tính năng này.

  1. Đổi giá trị khi thùng chạm đất thành shake = min(shake + 12, 18).
  2. Đặt shake_on = True trước vòng lặp; phím S sẽ đảo giá trị này. Chỉ chọn độ lệch ngẫu nhiên khi shake_on là true.
  3. Sau khi vẽ world lên màn hình, hiển thị Shake: On hoặc Shake: Off tại (10, 10).

Nhấn Chơi rồi nhấn S: dòng Shake: Off xuất hiện và các thùng khi chạm đất không còn rung. Sau đó nhấn Kiểm tra.

Tự làm thử

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Crate Drop")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 28)

thud_sound = pygame.mixer.Sound("assets/sounds/thud.ogg")
falling = []
landed = []
shake = 0
world = pygame.Surface((480, 360))

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:
            falling.append(pygame.Rect(random.randint(140, 400), -40, 40, 40))

    for crate in falling:
        crate.y += 8
        if crate.bottom >= 300:
            crate.bottom = 300
            landed.append(crate)
            thud_sound.play()
            shake += 12
    falling = [crate for crate in falling if crate.bottom < 300]

    world.fill((30, 30, 46))
    pygame.draw.rect(world, (80, 80, 100), (0, 300, 480, 60))
    pygame.draw.rect(world, (80, 160, 255), (60, 220, 30, 80))
    for crate in falling + landed:
        pygame.draw.rect(world, (170, 110, 60), crate)

    offset = (0, 0)
    if shake > 0:
        amount = shake // 3
        offset = (random.randint(-amount, amount), random.randint(-amount, amount))
        shake -= 1
    screen.fill((0, 0, 0))
    screen.blit(world, offset)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Âm thanh và cảm giác chơi

Tự luyện tập: Playground Pygame