Menu
CoddyTech

Đánh trúng và đặt lại bằng phương thức

Thuộc phần Dự án trong hành trình Pygame của Coddy. Bài học 21 trên 33.

Bóng còn hai nhiệm vụ nữa: nảy khỏi thanh đỡ và quay về giữa. Khi được viết dưới dạng phương thức, vòng lặp chính thể hiện các quy tắc của trò chơi.

def reset(self):
    self.rect.center = (300, 200)
    self.vx = -self.vx

Hai lần kiểm tra va chạm với thanh đỡ chỉ khác nhau ở hướng bóng bay ra: sang phải khi bật khỏi thanh đỡ bên trái, sang trái khi bật khỏi thanh bên phải. Truyền hướng đó dưới dạng một con số, way, là 1 hoặc -1, để một phương thức xử lý cả hai trường hợp:

ball.hit(left, 1)
ball.hit(right, -1)

Bên trong phương thức, self.vx = way * abs(self.vx) đưa bóng bay theo hướng đó bất kể trước đó bóng đang di chuyển theo hướng nào, còn góc đánh vẫn giữ nguyên.

challenge icon

Thử thách

Khó

Chuyển xử lý va chạm với thanh đỡ và đặt lại bóng vào lớp Ball.

  1. Viết hit(paddle, way): khi va chạm, đặt self.vx = way * abs(self.vx) và tính góc nảy.
  2. Viết reset(): đặt tâm tại (300, 200) và đảo chiều self.vx.
  3. Trong vòng lặp, gọi ball.hit(left, 1), ball.hit(right, -1) và ball.reset() sau mỗi điểm.

Nhấn “Chơi”: trò chơi vẫn diễn ra như cũ. Sau đó nhấn “Kiểm tra”.

Tự làm thử

import pygame


class Ball:
    def __init__(self):
        self.rect = pygame.Rect(293, 193, 14, 14)
        self.vx = 5
        self.vy = 4

    def move(self):
        self.rect.x += self.vx
        self.rect.y += self.vy
        if self.rect.top <= 0 or self.rect.bottom >= 400:
            self.vy = -self.vy

    def draw(self, surface):
        pygame.draw.rect(surface, (255, 196, 0), self.rect)


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 = Ball()
left = pygame.Rect(20, 160, 12, 80)
right = pygame.Rect(568, 160, 12, 80)
left_score = 0
right_score = 0
waiting = False
winner = None

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:
            if winner is None:
                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.move()
        if ball.rect.colliderect(left):
            ball.vx = abs(ball.vx)
            ball.vy = (ball.rect.centery - left.centery) // 6
        if ball.rect.colliderect(right):
            ball.vx = -abs(ball.vx)
            ball.vy = (ball.rect.centery - right.centery) // 6
        if ball.rect.left > 600:
            left_score += 1
            ball.rect.center = (300, 200)
            ball.vx = -ball.vx
            waiting = True
        if ball.rect.right < 0:
            right_score += 1
            ball.rect.center = (300, 200)
            ball.vx = -ball.vx
            waiting = True
        if left_score == 5:
            winner = "Left player wins!"
        elif right_score == 5:
            winner = "Right player wins!"

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (80, 160, 255), left)
    pygame.draw.rect(screen, (235, 80, 80), right)
    ball.draw(screen)
    score = font.render(f"{left_score} : {right_score}", True, (240, 240, 240))
    screen.blit(score, score.get_rect(center=(300, 30)))
    if winner is not None:
        message = font.render(winner, True, (240, 240, 240))
        screen.blit(message, message.get_rect(center=(300, 120)))
    elif 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()
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 Dự án

Tự luyện tập: Playground Pygame