Menu
CoddyTech

Paralaks

Termasuk bagian Dunia Game dalam perjalanan Pygame di Coddy. Pelajaran 23 dari 35.

Lihat ke luar dari kereta yang sedang bergerak: pagar melesat lewat, sementara bukit-bukit yang jauh hampir tidak bergerak. Menggambar benda yang jauh lebih lambat daripada benda yang dekat membuat game datar terasa memiliki kedalaman. Ini disebut parallax.

Gambar latar belakang awan dengan sepertiga pergerakan kamera. Latar ini berulang setiap 72 piksel, jadi yang penting hanya camera_x // 3 % 72: setelah bergeser sejauh satu gambar penuh, tampilannya akan sama.

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

Perulangan x dimulai dari -shift, di sebelah kiri jendela, sehingga salinan pertama menutupi tepi kiri saat bergeser keluar. Ubin dan pemain tetap menggunakan seluruh camera_x: keduanya berada dekat.

challenge icon

Tantangan

Sedang
  1. Alih-alih menggunakan screen.fill, gambar background (yang dimuat dalam kode awal) dalam kisi 72 piksel.
  2. Setiap frame, atur shift = camera_x // 3 % 72 dan mulai setiap baris salinan pada x = -shift, dengan langkah 72 hingga WIDTH.
  3. Gambar ubin dan pemain setelah latar belakang, seperti sebelumnya.

Coba sendiri

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()

Semua pelajaran di Dunia Game

Latihan sendiri: Playground Pygame