Sprite chính xác đến từng pixel
Thuộc phần Sprite và hình ảnh trong hành trình Pygame của Coddy. Bài học 24 trên 39.
Sprite cũng có thể dùng mask, và pygame tự xử lý độ lệch cho bạn. Tạo self.mask cho mỗi sprite, chỉ tạo một lần trong __init__:
self.mask = pygame.mask.from_surface(self.image)Sau đó truyền pygame.sprite.collide_mask làm đối số thứ tư cho spritecollide:
hits = pygame.sprite.spritecollide(player, balls, False, pygame.sprite.collide_mask)Đối số thứ tư là phép kiểm tra dùng cho từng cặp. Nếu không có đối số này, phép kiểm tra sẽ dùng Rect. Khi dùng collide_mask, phép kiểm tra sẽ dùng mask, được đặt theo Rect của mỗi sprite. groupcollide cũng nhận đối số thứ năm tương tự.
Phép kiểm tra mask tốn chi phí hơn phép kiểm tra Rect, nhưng overlap chỉ so sánh các pixel nằm trong vùng hai Rect chồng lên nhau, nên các cặp ở xa nhau sẽ được xử lý nhanh. Với vài chục sprite, bạn sẽ không nhận thấy chi phí này. Nếu sprite không có mask, collide_mask sẽ tạo mask từ hình ảnh của sprite trong mỗi lần kiểm tra, vì vậy hãy đặt mask trong __init__.
Thử thách
Trung bìnhChỉ tính là va chạm khi các hình chạm nhau.
- Tạo
self.maskchoPlayervàBalltừself.image. - Truyền
pygame.sprite.collide_maskvàospritecollide.
Nhấn Chơi: Hit! chỉ xuất hiện khi các hình chạm nhau. Sau đó nhấn Kiểm tra.
Tự làm thử
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Spike Field")
clock = pygame.time.Clock()
ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
ball_image = pygame.image.load("assets/images/spike_ball.png").convert_alpha()
font = pygame.font.Font(None, 40)
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = ship_image
self.rect = self.image.get_rect(topleft=(420, 320))
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.rect.x -= 4
if keys[pygame.K_RIGHT]:
self.rect.x += 4
if keys[pygame.K_UP]:
self.rect.y -= 4
if keys[pygame.K_DOWN]:
self.rect.y += 4
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = ball_image
self.rect = self.image.get_rect(center=(x, y))
player = Player()
balls = pygame.sprite.Group(Ball(160, 240), Ball(320, 240), Ball(480, 240))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
player.update()
hits = pygame.sprite.spritecollide(player, balls, False)
screen.fill((20, 22, 40))
balls.draw(screen)
screen.blit(player.image, player.rect)
if hits:
text = font.render("Hit!", True, (240, 240, 240))
screen.blit(text, (10, 10))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Tất cả bài học trong Sprite và hình ảnh
5Va chạm chính xác đến từng pixel
Hình chữ nhật thật bất côngMặt nạSprite chính xác đến từng pixelVùng va chạm hình tròn3Lớp cho đối tượng trong trò chơi
Lớp đầu tiên của bạnPhương thứcSelf là đối tượngDanh sách đối tượngĐối tượng có hình ảnhDanh sách kẻ địchLớp con6Hoạt ảnh từ sprite sheet
Cắt sprite sheetBộ đếm khung hìnhTạo hoạt ảnh theo thời gianHiệu ứng nổ chỉ chạy một lầnTự luyện tập: Playground Pygame