Menu
CoddyTech

الجدران من اليسار واليمين

جزء من قسم العوالم في رحلة Pygame على Coddy. الدرس 15 من 35.

تُرسَم الكتل، لكن اللاعب يمر عبرها. يجب أن يوقف الجدار اللاعب. حرّك اللاعب أولًا، ثم صحّح الحركة: إذا كان اللاعب يتداخل الآن مع جدار، فأزِحه إلى الخارج من الجهة التي أتى منها.

player.x += dx
for wall in walls:
    if player.colliderect(wall):
        if dx > 0:
            player.right = wall.left
        elif dx < 0:
            player.left = wall.right

يمثّل dx الحركة الجانبية في هذا الإطار: قيمة موجبة تعني الحركة إلى اليمين. عند التحرك إلى اليمين، يصطدم اللاعب بالجانب الأيسر من الجدار، لذا يصبح حدّه الأيمن عند ذلك الجانب. وعند التحرك إلى اليسار، يصبح حدّه الأيسر عند الجانب الأيمن من الجدار.

الخريطة مُضمّنة في walls، وهي قائمة من Rects، بالطريقة نفسها المتبعة في Maps from Text. وما يزال الخط عند FLOOR يمثّل الأرضية، وما يزال بإمكان اللاعب السقوط فوق كتلة: سنتناول الهبوط على الجدران في الخطوة التالية.

challenge icon

التحدي

متوسط
  1. بعد player.x += dx، كرّر على walls.
  2. لكل جدار يصطدم به اللاعب: عندما يكون dx > 0، عيّن player.right = wall.left؛ وعندما يكون dx < 0، عيّن player.left = wall.right.

جرّب بنفسك

import pygame

TILE = 36
SPEED = 4
GRAVITY = 1
JUMP = -15
MAX_FALL = 12
FLOOR = 324

LEVEL = [
    "................",
    "................",
    "................",
    "................",
    "................",
    "................",
    "................",
    "#..........##..#",
    "#.P..#.....##..#",
    "################",
]

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Walls")
clock = pygame.time.Clock()

background = pygame.image.load("assets/backgrounds/clouds.png").convert_alpha()
block_img = pygame.image.load("assets/images/block.png").convert_alpha()
player_img = pygame.image.load("assets/images/player.png").convert_alpha()

walls = []
for row, line in enumerate(LEVEL):
    for col, char in enumerate(line):
        if char == "#":
            walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
        elif char == "P":
            start = (col * TILE + TILE // 2, row * TILE + TILE)

player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
            if on_ground:
                vel_y = JUMP
        elif event.type == pygame.KEYUP and event.key in (pygame.K_SPACE, pygame.K_UP):
            if vel_y < -4:
                vel_y = -4

    keys = pygame.key.get_pressed()
    dx = 0
    if keys[pygame.K_LEFT]:
        dx -= SPEED
    if keys[pygame.K_RIGHT]:
        dx += SPEED

    player.x += dx

    vel_y = min(vel_y + GRAVITY, MAX_FALL)
    player.y += vel_y
    on_ground = False
    if player.bottom > FLOOR:
        player.bottom = FLOOR
        vel_y = 0
        on_ground = True

    for y in range(0, 360, 72):
        for x in range(0, 576, 72):
            screen.blit(background, (x, y))
    for wall in walls:
        screen.blit(block_img, wall)
    screen.blit(player_img, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

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

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