Menu
CoddyTech

Giữ để bắn

Thuộc phần Sprite và hình ảnh trong hành trình Pygame của Coddy. Bài học 32 trên 39.

Nhấn Space cho mỗi phát bắn khiến các ngón tay mỏi. Hầu hết trò chơi bắn súng đều bắn khi bạn giữ nút, nhưng nếu tia laser xuất hiện ở mỗi khung hình thì nó sẽ tạo thành một chùm sáng liên tục. Thời gian hồi giới hạn tốc độ bắn: sau mỗi phát bắn, phải chờ 250 mili giây mới bắn tiếp.

Ghi nhớ thời điểm bắn phát cuối cùng và chỉ bắn khi bạn giữ Space, đồng thời đã chờ đủ thời gian:

keys = pygame.key.get_pressed()
now = pygame.time.get_ticks()
if keys[pygame.K_SPACE] and now - last_shot >= 250:
    lasers.add(Laser(player.rect.centerx, player.rect.top))
    last_shot = now

now - last_shot cho biết phát bắn cuối cùng diễn ra cách đây bao lâu. Đặt last_shot = 0 trước vòng lặp. Giờ đây, giữ Space sẽ bắn bốn tia laser mỗi giây, còn nhấn nhanh liên tục cũng không thể bắn nhanh hơn mức đó.

Cách này thay cho việc bắn bằng KEYDOWN: chỉ có một cách bắn với một quy tắc.

challenge icon

Thử thách

Trung bình

Bắn khi giữ phím Space, bốn lần mỗi giây.

  1. Xóa thao tác bắn bằng KEYDOWN khỏi vòng lặp sự kiện.
  2. Đặt last_shot = 0 trước vòng lặp.
  3. Trong phần cập nhật, khi đang giữ Space và đã qua ít nhất 250 ms kể từ last_shot, hãy bắn một tia laser và đặt last_shot thành thời điểm hiện tại.

Nhấn Chơi và giữ Space: bốn tia laser mỗi giây. 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("Star Patrol")
clock = pygame.time.Clock()

ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = ship_image
        self.rect = self.image.get_rect(midbottom=(320, 470))

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 6
        if keys[pygame.K_RIGHT]:
            self.rect.x += 6
        self.rect.clamp_ip(screen.get_rect())


class Laser(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = laser_image
        self.rect = self.image.get_rect(midbottom=(x, y))

    def update(self):
        self.rect.y -= 10
        if self.rect.bottom < 0:
            self.kill()


player = Player()
lasers = pygame.sprite.Group()

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:
            lasers.add(Laser(player.rect.centerx, player.rect.top))

    player.update()
    lasers.update()

    screen.fill((12, 14, 30))
    lasers.draw(screen)
    screen.blit(player.image, player.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Sprite và hình ảnh

Tự luyện tập: Playground Pygame