Menu
CoddyTech

اجمع العملات

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

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

اقرأ كل C وأضفه إلى قائمة من كائنات Rects، تمثّل كلًّا منها المربع الكامل للبلاطة، لأن coin.png له حدّ فارغ خاص به. عندما يلمس اللاعب عملة، أزلها من القائمة وأضفها إلى العدد:

for coin in coins[:]:
    if player.colliderect(coin):
        coins.remove(coin)
        coins_collected += 1

coins[:] نسخة من القائمة. إزالة العناصر من قائمة أثناء المرور عليها في حلقة تؤدي إلى تحريك العناصر تحت الحلقة وتجاوز أحدها؛ لذا فإن المرور على نسخة يتجنب ذلك.

اعرض العدد في الزاوية العلوية اليمنى. فهو يتبع النافذة لا المستوى، لذا يُرسم من دون الكاميرا:

font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
# داخل الحلقة
text = font.render(f"Coins: {coins_collected}", True, (255, 255, 255))
screen.blit(text, text.get_rect(topright=(WIDTH - 12, 14)))
challenge icon

التحدي

متوسط
  1. حمّل coin.png إلى coin_img وأنشئ font من assets/fonts/pixel.ttf بحجم 24.
  2. أنشئ coins = [] وcoins_collected = 0؛ وفي حلقة الخريطة، أضف Rect الخاص بالبلاطة لكل C.
  3. في كل إطار، بعد الحركة، أزِل كل قطعة نقدية يلمسها اللاعب وأضف 1 إلى coins_collected.
  4. ارسم كل قطعة نقدية عند إحداثي x الخاص بها مطروحًا منه camera_x، وارسم النص Coins: والعدد في أعلى اليمين، كما هو موضّح.

جرّب بنفسك

import pygame

TILE = 36
WIDTH, HEIGHT = 576, 360
SPEED = 4
GRAVITY = 1
JUMP = -15
MAX_FALL = 12

LEVEL = [
    "................................................................",
    "................................................................",
    "................................................................",
    "................................................................",
    "#..............................................................#",
    "#....................C.........................#####...........#",
    "#......CC...C................CC.....CC.........#####.....CC....#",
    "#....................#.........................D...............#",
    "#.P.........#...E....#...^.......K......E......D.C....^......F.#",
    "#######..####################..##########################..#####",
]

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Moss Caves")
clock = pygame.time.Clock()


def load(name):
    return pygame.image.load("assets/images/" + name).convert_alpha()


background = pygame.image.load("assets/backgrounds/forest.png").convert_alpha()
grass_img = load("grass.png")
grass_left_img = load("grass_left.png")
grass_right_img = load("grass_right.png")
dirt_img = load("dirt.png")
player_img = load("player.png")


def solid(row, col):
    if row < 0 or row >= len(LEVEL) or col < 0 or col >= len(LEVEL[0]):
        return False
    return LEVEL[row][col] == "#"


walls = []
tiles = []
for row, line in enumerate(LEVEL):
    for col, char in enumerate(line):
        rect = pygame.Rect(col * TILE, row * TILE, TILE, TILE)
        if char == "#":
            if solid(row - 1, col):
                image = dirt_img
            elif not solid(row, col - 1) and solid(row, col + 1):
                image = grass_left_img
            elif solid(row, col - 1) and not solid(row, col + 1):
                image = grass_right_img
            else:
                image = grass_img
            walls.append(rect)
            tiles.append((image, rect))
        elif char == "P":
            start = rect.midbottom

level_width = len(LEVEL[0]) * TILE
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
camera_x = 0

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
                on_ground = True
            elif vel_y < 0:
                player.top = wall.bottom
            vel_y = 0

    if player.top > HEIGHT:
        player.midbottom = start
        vel_y = 0

    camera_x = player.centerx - WIDTH // 2
    camera_x = max(0, min(camera_x, level_width - WIDTH))

    shift = camera_x // 3 % 72
    for y in range(0, HEIGHT, 72):
        for x in range(-shift, WIDTH, 72):
            screen.blit(background, (x, y))
    for image, rect in tiles:
        screen.blit(image, (rect.x - camera_x, rect.y))
    screen.blit(player_img, (player.x - camera_x, player.y))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

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

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