Menu
CoddyTech

ارتطام الرأس

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

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

vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
    if player.colliderect(wall):
        if vel_y > 0:
            player.bottom = wall.top
            on_ground = True
        elif vel_y < 0:
            player.top = wall.bottom
        vel_y = 0

يصل الرأس إلى أسفل الجدار، وتصبح السرعة 0 في كلتا الحالتين. بعد الاصطدام، تبدأ الجاذبية السقوط فورًا. من دون vel_y = 0، يواصل اللاعب محاولة الحركة إلى الأعلى ويلتصق بأسفل المنصة إلى أن تستنفد الجاذبية قوة القفزة.

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

challenge icon

التحدي

سهل
  1. في حلقة التصادم العمودي، أضف الحالة vel_y < 0: player.top = wall.bottom.
  2. عيّن vel_y = 0 بعد الحالتين، لكي يوقف الاصطدام الصعود.

يبدأ اللاعب أسفل منصة؛ اقفز لتجرّب ذلك.

جرّب بنفسك

import pygame

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

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

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Head Bump")
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
    for wall in walls:
        if player.colliderect(wall):
            if dx > 0:
                player.right = wall.left
            elif dx < 0:
                player.left = wall.right

    vel_y = min(vel_y + GRAVITY, MAX_FALL)
    player.y += vel_y
    on_ground = False
    for wall in walls:
        if player.colliderect(wall):
            if vel_y > 0:
                player.bottom = wall.top
                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