האביר צועד
חלק מהיחידה פרויקטים במסלול ה-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אתגר
קשה- הוסף למעלה את הפונקציות
drawו־cell_rect. - ב־
Room, הגדר אתself.start = (72, 72)לפני הלולאה, ועבורP, הגדר אתself.start = cell_rect(col, row).center. - כתוב
class Knight(pygame.sprite.Sprite): הפונקציה__init__(self, center)שלה מגדירה אתself.image = knight_imgואתself.rectבגודל 32 על 32, שממורכזת ב־center. הוסף לה את המתודהmove(dx, dy, blocks)שמופיעה למעלה, כולל החלק של y. - צור את
knight = Knight(room.start)אחרי החדר. - בכל פריים, הגדר את
dxל־-3 עם Left או ל־3 עם Right, ואתdyל־-3 עם Up או ל־3 עם Down (ו־0 אחרת), ואז קרא ל־knight.move(dx, dy, room.walls). - צייר את האביר אחרי הקירות:
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()
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה פרויקטים
תרגלו בעצמכם: Pygame אונליין