Menu
CoddyTech

Lớp Ball

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

Quả bóng gồm một Rect, hai con số và các việc nó thực hiện: di chuyển, nảy và được vẽ. Hãy tạo một lớp cho quả bóng, như bạn đã làm với các sprite: một lớp gom dữ liệu cùng các hàm sử dụng dữ liệu đó lại với nhau.

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

ball = Ball() tạo một đối tượng bóng và chạy __init__. Bên trong lớp, self là đối tượng, nên self.vx là vx của chính quả bóng này. Các hàm trong một lớp được gọi là phương thức: ball.move() gọi một phương thức.

Bên ngoài lớp, Rect của quả bóng giờ là ball.rect, còn tốc độ của nó là ball.vx và ball.vy, vì vậy code điều khiển thanh đỡ và tính điểm sẽ đọc các giá trị này tại đó. Trò chơi vẫn hoạt động như trước.

challenge icon

Thử thách

Khó

Biến quả bóng thành một lớp có thể tự di chuyển và vẽ chính nó.

  1. Ở đầu, viết class Ball với __init__ (self.rect, self.vx = 5, self.vy = 4), move() (di chuyển và nảy khỏi mép trên và mép dưới) và draw(surface).
  2. Tạo ball = Ball(), rồi gọi ball.move() và ball.draw(screen) trong vòng lặp.
  3. Ở mọi nơi khác, viết ball.rect, ball.vx và ball.vy.

Nhấn “Chơi”: trò chơi diễn ra đúng như trướ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
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.x += vx
        ball.y += vy
        if ball.top <= 0 or ball.bottom >= 400:
            vy = -vy
        if ball.colliderect(left):
            vx = abs(vx)
            vy = (ball.centery - left.centery) // 6
        if ball.colliderect(right):
            vx = -abs(vx)
            vy = (ball.centery - right.centery) // 6
        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
        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)
    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 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()

Tất cả bài học trong Dự án

Tự luyện tập: Playground Pygame