Menu
CoddyTech

Parallasse

Fa parte della sezione Mondi del percorso Pygame di Coddy. Lezione 23 di 35.

Guarda fuori da un treno in movimento: la recinzione sfreccia e le colline lontane quasi non si muovono. Disegnare gli oggetti lontani più lentamente di quelli vicini dà a un gioco bidimensionale una sensazione di profondità. Questo si chiama parallasse.

Disegna lo sfondo con le nuvole usando un terzo del movimento della telecamera. Si ripete ogni 72 pixel, quindi conta solo camera_x // 3 % 72: una volta che è scivolato di un'immagine intera, sembra uguale.

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

Il ciclo x inizia da -shift, a sinistra della finestra, così la prima copia copre il bordo sinistro mentre scivola fuori. Le tessere e il giocatore usano ancora tutto camera_x: sono vicini.

challenge icon

Sfida

Medio
  1. Invece di screen.fill, disegna background (caricato nel codice iniziale) su una griglia di 72 pixel.
  2. A ogni fotogramma, imposta shift = camera_x // 3 % 72 e inizia ogni riga di copie da x = -shift, avanzando a passi di 72 fino a WIDTH.
  3. Disegna le tessere e il giocatore dopo lo sfondo, come prima.

Provalo tu

import pygame

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

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

pygame.init()
screen = pygame.display.set_mode((WIDTH, 360))
pygame.display.set_caption("Parallax")
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)

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

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

    screen.fill((140, 200, 240))
    for wall in walls:
        screen.blit(block_img, (wall.x - camera_x, wall.y))
    screen.blit(player_img, (player.x - camera_x, player.y))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tutte le lezioni di Mondi

Esercitati da solo: Playground Pygame