Menu
CoddyTech

האביר צועד

חלק מהיחידה פרויקטים במסלול ה-Pygame של Coddy. שיעור 22 מתוך 31.

האביר מתחיל ב־P של המפה והולך באמצעות מקשי החצים, 3 פיקסלים בכל פריים.

התמונה שלו היא בגודל של אריח שלם, 48 על 48, וכך גם המרווחים בין הקירות. מלבן Rect בגודל 48 פיקסלים יתאים למרווח רק כשהוא מיושר לפיקסל המדויק. לכן ה־Rect של האביר קטן יותר מהתמונה שלו, 32 על 32, והתמונה מצוירת כשהיא ממורכזת עליו. ה־Rect הוא זה שמתנגש; התמונה היא מה שרואים.

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

הקירות עוצרים אותו כמו שהפלטפורמות עשו במערות הטחב: נעים לאורך ציר 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, עם bottom ו-top
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 עם Left או ל־3 עם Right, ואת dy ל־-3 עם Up או ל־3 עם Down (ו־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בחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

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

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