الفارس يمشي
جزء من قسم المشاريع في رحلة 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، باستخدام الحافتين السفلية والعلويةالتحدي
صعب- أضف الدالتين
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 عند الضغط على مفتاح اليسار أو إلى 3 عند الضغط على مفتاح اليمين، وعيّنdyإلى -3 عند الضغط على مفتاح الأعلى أو إلى 3 عند الضغط على مفتاح الأسفل (وإلا فاجعله 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()
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس المشاريع
تدرّب بنفسك: Playground لـ Pygame