Menu
CoddyTech

Đừng tự cắn mình

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

Trò chơi cũng kết thúc khi đầu chạm vào thân. Thêm điều kiện này vào phép kiểm tra kết thúc trò chơi:

if x < 0 or x >= COLS or y < 0 or y >= ROWS or (x, y) in body[:-1]:
    alive = False

Phép kiểm tra dùng body[:-1], tức là mọi ô trừ ô cuối cùng. Khi không có thức ăn, đuôi rời khỏi ô của nó trong cùng một bước. Đuổi theo đuôi của chính mình là an toàn, vì vậy ô chứa đuôi không được tính.

[:-1] là một lát cắt: danh sách bắt đầu từ đầu và kéo dài đến nhưng không bao gồm phần tử cuối cùng.

challenge icon

Thử thách

Khó

Kết thúc trò chơi khi rắn cắn vào thân mình.

  1. Tìm điều kiện kiểm tra kết thúc trò chơi khi rắn chạm tường.
  2. Kết thúc trò chơi khi đầu mới (x, y) nằm trong body[:-1].

Nhấn Chơi, ăn vài lần, rồi quay đầu vào thân mình: Trò chơi kết thúc. Sau đó nhấn Kiểm tra.

Tự làm thử

import random
import pygame

CELL = 20
COLS, ROWS = 24, 18
TURNS = {
    pygame.K_LEFT: (-1, 0),
    pygame.K_RIGHT: (1, 0),
    pygame.K_UP: (0, -1),
    pygame.K_DOWN: (0, 1),
}

pygame.init()
screen = pygame.display.set_mode((COLS * CELL, ROWS * CELL))
pygame.display.set_caption("Snake")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)


def draw_cell(cell, color):
    col, row = cell
    pygame.draw.rect(screen, color, (col * CELL + 1, row * CELL + 1, CELL - 2, CELL - 2))


def new_food(body):
    while True:
        cell = (random.randrange(COLS), random.randrange(ROWS))
        if cell not in body:
            return cell


body = [(5, 9), (4, 9), (3, 9)]
direction = (1, 0)
food = new_food(body)
score = 0
alive = True

running = True
while running:
    moving = direction
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key in TURNS:
            turn = TURNS[event.key]
            if turn != (-moving[0], -moving[1]):
                direction = turn

    if alive:
        x = body[0][0] + direction[0]
        y = body[0][1] + direction[1]
        if x < 0 or x >= COLS or y < 0 or y >= ROWS:
            alive = False
        else:
            body.insert(0, (x, y))
            if (x, y) == food:
                score += 1
                food = new_food(body)
            else:
                body.pop()

    screen.fill((30, 30, 46))
    draw_cell(food, (235, 80, 80))
    for cell in body[1:]:
        draw_cell(cell, (120, 220, 120))
    draw_cell(body[0], (180, 255, 160))
    score_text = font.render(f"Score: {score}", True, (240, 240, 240))
    screen.blit(score_text, (8, 6))
    if not alive:
        message = font.render("Game over", True, (240, 240, 240))
        screen.blit(message, message.get_rect(center=(240, 180)))
    pygame.display.flip()
    clock.tick(10)

pygame.quit()

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

Tự luyện tập: Playground Pygame