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

כל השיעורים ביחידה פרויקטים

תרגלו בעצמכם: Pygame אונליין