Menu
CoddyTech

Devriye Gezen Bir Blob

Coddy'nin Pygame Journey'sinin Dünyalar bölümünün bir parçası. Ders 24 / 35.

İki blob sağa ve havaya doğru yürür. Devriye gezen bir düşman ileri geri yürür: bir duvara çarptığında veya zemininin sonuna ulaştığında döner. Blob sınıfı, sağ için 1 ve sol için -1 olan direction değerini tutar.

Her adımdan sonra, blob'un öndeki ayağının bir piksel ilerisindeki noktaya, ayaklarıyla aynı yükseklikte bakın. Bu noktayı hiçbir duvar tutmuyorsa, sonraki adım havaya doğru olacaktır:

if self.direction > 0:
    ahead = self.rect.right
else:
    ahead = self.rect.left - 1
hit_wall = any(self.rect.colliderect(wall) for wall in walls)
ground_ahead = any(wall.collidepoint(ahead, self.rect.bottom) for wall in walls)
if hit_wall or not ground_ahead:
    self.rect.x -= self.direction
    self.direction = -self.direction

any(...), en az bir duvar testi geçtiğinde True değerini verir. Dönüş, adımı geri alır ve yönü tersine çevirir. Blob'un Rect'i gövdesine uyar; 30'a 26 boyutlarındadır ve alt orta noktası Rect'in alt orta noktasına gelecek şekilde çizilen 48 piksel boyutundaki görüntüden daha küçüktür.

challenge icon

Görev

Zor

Blob.update içinde, şu adımdan sonra:

  1. Sağa hareket ederken ahead değerini self.rect.right olarak, aksi hâlde self.rect.left - 1 olarak ayarla.
  2. Blob'un herhangi bir duvarla çakışıp çakışmadığını ve herhangi bir duvarın (ahead, self.rect.bottom) noktasını içerip içermediğini bul.
  3. Bir duvara çarptıysa veya ileride zemin yoksa adımı geri al ve self.direction değerini tersine çevir.

Kendin dene

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("Patrol")
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()
blob_img = pygame.image.load("assets/images/blob.png").convert_alpha()


class Blob(pygame.sprite.Sprite):
    def __init__(self, midbottom):
        super().__init__()
        self.image = blob_img
        self.rect = pygame.Rect(0, 0, 30, 26)
        self.rect.midbottom = midbottom
        self.direction = 1

    def update(self):
        self.rect.x += self.direction

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)

blobs = pygame.sprite.Group(Blob((432, 144)), Blob((432, 324)))
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

    blobs.update()

    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)
    for blob in blobs:
        screen.blit(blob.image, blob.image.get_rect(midbottom=blob.rect.midbottom))
    screen.blit(player_img, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Dünyalar bölümündeki tüm dersler

Kendi başına pratik yap: Pygame playground