Menu
CoddyTech

עקבו אחר החוקר

חלק מהיחידה עולמות במסלול ה-Pygame של Coddy. שיעור 30 מתוך 35.

רוחבה של המערה הוא ארבעה מסכים, לכן המצלמה עוקבת אחר החוקר, כמו ב״מצלמה נגללת״. אחרי שהשחקן זז, מרכזים את המצלמה עליו ומשאירים אותו בתוך השלב:

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

ציירו כל אריח ואת השחקן במיקום ה־x שלו פחות camera_x. רקע היער רחוק, ולכן הוא נע בשליש מהמהירות וחוזר על עצמו כל 72 פיקסלים:

shift = camera_x // 3 % 72
for y in range(0, HEIGHT, 72):
    for x in range(-shift, WIDTH, 72):
        screen.blit(background, (x, y))

הגדירו level_width = len(LEVEL[0]) * TILE ואת camera_x = 0 לפני הלולאה.

challenge icon

אתגר

קל
  1. לפני הלולאה, צרו את level_width מהמפה ואת camera_x = 0.
  2. בסוף העדכון של כל פריים, הגדירו את camera_x כך שיעקוב אחרי השחקן, והגבילו אותו לטווח שבין 0 לבין level_width - WIDTH.
  3. ציירו את הרקע באמצעות shift = camera_x // 3 % 72, והתחילו כל שורה ב--shift.
  4. ציירו את האריחים במיקום (rect.x - camera_x, rect.y) ואת השחקן במיקום (player.x - camera_x, player.y).

נסו בעצמכם

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

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

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

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

pygame.quit()
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה עולמות

תרגלו בעצמכם: Pygame אונליין