Menu
CoddyTech

Cú đánh theo góc

Bài học 36 trên 41 trong khóa học Tạo trò chơi với Pygame của Coddy.

Trong Pong, vị trí bóng chạm vào thanh đỡ sẽ quyết định hướng bóng bay. Gần đầu trên, bóng bay lên; gần đầu dưới, bóng bay xuống; còn ở giữa, bóng bay thẳng ngang.

Đo khoảng cách giữa tâm bóng và tâm thanh đỡ, rồi dùng kết quả đó làm giá trị mới cho vy:

if ball.colliderect(right):
    vx = -abs(vx)
    vy = (ball.centery - right.centery) // 6

Ở phía trên tâm, độ chênh lệch là số âm nên bóng bay lên; ở phía dưới, độ chênh lệch là số dương. Chia cho 6 giúp bóng không bay quá nhanh: một cú đánh trúng ngay đầu thanh đỡ sẽ cho giá trị vy khoảng 7.

Cách này biến Pong thành trò chơi đòi hỏi kỹ năng: bạn ngắm bằng thanh đỡ của mình.

challenge icon

Thử thách

Khó

Hãy điều chỉnh hướng đánh của các thanh để bóng bay theo hướng bạn muốn.

  1. Trong cả hai va chạm với thanh, sau khi đặt vx, hãy đặt vy bằng vị trí giữa của bóng trừ đi vị trí giữa của thanh tương ứng.
  2. Chia kết quả cho 6 bằng //.

Nhấn Chơi rồi đánh bóng bằng đầu thanh: bóng sẽ bay theo một góc. Sau đó nhấn Kiểm tra.

Tự làm thử

import pygame

pygame.init()
screen = pygame.display.set_mode((600, 400))
pygame.display.set_caption("Pong")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)

ball = pygame.Rect(293, 193, 14, 14)
vx, vy = 5, 4
left = pygame.Rect(20, 160, 12, 80)
right = pygame.Rect(568, 160, 12, 80)
left_score = 0
right_score = 0
waiting = False

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:
            waiting = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_w]:
        left.y -= 6
    if keys[pygame.K_s]:
        left.y += 6
    if keys[pygame.K_UP]:
        right.y -= 6
    if keys[pygame.K_DOWN]:
        right.y += 6
    left.clamp_ip(screen.get_rect())
    right.clamp_ip(screen.get_rect())

    if not waiting:
        ball.x += vx
        ball.y += vy
        if ball.top <= 0 or ball.bottom >= 400:
            vy = -vy
        if ball.colliderect(left):
            vx = abs(vx)
        if ball.colliderect(right):
            vx = -abs(vx)
        if ball.left > 600:
            left_score += 1
            ball.center = (300, 200)
            vx = -vx
            waiting = True
        if ball.right < 0:
            right_score += 1
            ball.center = (300, 200)
            vx = -vx
            waiting = True

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (80, 160, 255), left)
    pygame.draw.rect(screen, (235, 80, 80), right)
    pygame.draw.rect(screen, (255, 196, 0), ball)
    score = font.render(f"{left_score} : {right_score}", True, (240, 240, 240))
    screen.blit(score, score.get_rect(center=(300, 30)))
    if waiting:
        message = font.render("Press Space to serve", True, (240, 240, 240))
        screen.blit(message, message.get_rect(center=(300, 360)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Tạo trò chơi với Pygame

Tự luyện tập: Playground Pygame