Menu
CoddyTech

الفارس يمشي

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

يبدأ الفارس عند P على الخريطة، ويتحرك باستخدام مفاتيح الأسهم بمقدار 3 بكسلات في كل إطار.

صورته بحجم مربع كامل، 48 في 48، وكذلك المسافات بين الجدران. لن يتسع مستطيل بحجم 48 بكسل في المسافة إلا إذا حاذاها بدقة بكسل واحد. لذلك يكون مستطيل الفارس أصغر من صورته، 32 في 32، وتُرسم الصورة في وسطه. المستطيل هو ما يصطدم؛ أما الصورة فهي ما تراه.

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

توقفه الجدران بالطريقة نفسها التي أوقفت بها المنصات حركته في 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
    # ثم افعل الشيء نفسه مع dy، باستخدام الحافتين السفلية والعلوية
challenge icon

التحدي

صعب
  1. أضف الدالتين draw وcell_rect أعلاه.
  2. في Room، عيّن self.start = (72, 72) قبل الحلقة، وعند وجود P، عيّن self.start = cell_rect(col, row).center.
  3. اكتب class Knight(pygame.sprite.Sprite): تجعل __init__(self, center) قيمة self.image = knight_img، وتنشئ self.rect بأبعاد 32 في 32 وتوسّطه عند center. أضف إليها الطريقة move(dx, dy, blocks) الواردة أعلاه، مع جزء المحور y.
  4. أنشئ knight = Knight(room.start) بعد الغرفة.
  5. في كل إطار، عيّن dx إلى -3 عند الضغط على مفتاح اليسار أو إلى 3 عند الضغط على مفتاح اليمين، وعيّن dy إلى -3 عند الضغط على مفتاح الأعلى أو إلى 3 عند الضغط على مفتاح الأسفل (وإلا فاجعله 0)، ثم استدعِ knight.move(dx, dy, room.walls).
  6. ارسم الفارس بعد الجدران: draw(knight.image, knight.rect).

جرّب بنفسك

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")


class Room:
    def __init__(self, lines):
        self.walls = []
        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))


room = Room(MAP)

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)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

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

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