Menu
CoddyTech

الجدران توقف الفارس

جزء من قسم المشاريع في رحلة Pygame على Coddy. الدرس 24 من 33.

يتحرك الفارس باستخدام مفاتيح الأسهم، بمقدار 3 بكسلات في كل إطار، وتوقفه الجدران كما فعلت المنصات في Moss Caves: تحرك على طول المحور x، وادفعه للخروج من أي جدار يتداخل معه، ثم افعل الشيء نفسه على طول المحور y. إن التحرك على محور واحد في كل مرة يخبرك بأي جانب اصطدم.

def move(self, dx, dy, blocks):
    self.rect.x += dx
    for block in blocks:
        if self.rect.colliderect(block):
            if dx > 0:
                self.rect.right = block.left
            elif dx < 0:
                self.rect.left = block.right
    self.rect.y += dy
    for block in blocks:
        if self.rect.colliderect(block):
            if dy > 0:
                self.rect.bottom = block.top
            elif dy < 0:
                self.rect.top = block.bottom

اقرأ مفاتيح الأسهم في كل إطار داخل dx وdy، كما في Catch the Blocks، ومرّر جدران الغرفة:

keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
    dx = -3
# الاتجاهات يمين وأعلى وأسفل بالطريقة نفسها
knight.move(dx, dy, room.walls)
challenge icon

التحدي

صعب

اجعل الفارس يمشي، وتوقفه الجدران.

  1. أضف إلى Knight الدالة move(dx, dy, blocks) المذكورة أعلاه.
  2. في كل إطار، عيّن dx إلى -3 عند الضغط على Left أو إلى 3 عند الضغط على Right، وعيّن dy إلى -3 عند الضغط على Up أو إلى 3 عند الضغط على Down، وإلى 0 خلاف ذلك.
  3. ثم استدعِ knight.move(dx, dy, room.walls).

اضغط على «العب» وامشِ باتجاه جدار: سيتوقف الفارس عنده. ثم اضغط على «تحقق».

جرّب بنفسك

import pygame

TILE = 48
MAP = [
    "##############",
    "#............#",
    "#.P......K...#",
    "#............#",
    "#....##......D",
    "#....##......#",
    "##.#######.###",
    "#............#",
    "#...S....H...#",
    "##############",
]

pygame.init()
screen = pygame.display.set_mode((672, 480))
pygame.display.set_caption("Rune Keep")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)


def load(name):
    return pygame.image.load("assets/images/" + name).convert_alpha()


floor_img = load("floor.png")
wall_img = load("wall.png")
knight_img = load("knight.png")
door_img = load("dungeon_door.png")
key_img = load("key.png")
slime_img = load("slime.png")
spider_img = load("spider.png")
heart_img = load("heart.png")
empty_img = load("heart_empty.png")
sword_img = load("sword.png")
potion_img = load("potion_red.png")


def draw(image, rect):
    screen.blit(image, image.get_rect(center=rect.center))


def cell_rect(col, row):
    rect = pygame.Rect(0, 0, 32, 32)
    rect.center = (col * TILE + 24, row * TILE + 24)
    return rect


class Room:
    def __init__(self, lines):
        self.walls = []
        self.start = (72, 72)
        for row, line in enumerate(lines):
            for col, char in enumerate(line):
                if char == "#":
                    self.walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
                elif char == "P":
                    self.start = cell_rect(col, row).center


class Knight(pygame.sprite.Sprite):
    def __init__(self, center):
        super().__init__()
        self.image = knight_img
        self.rect = pygame.Rect(0, 0, 32, 32)
        self.rect.center = center


room = Room(MAP)
knight = Knight(room.start)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    for row in range(10):
        for col in range(14):
            screen.blit(floor_img, (col * TILE, row * TILE))
    for wall in room.walls:
        screen.blit(wall_img, wall)
    draw(knight.image, knight.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

جميع دروس المشاريع

تدرّب بنفسك: Playground لـ Pygame