Anahtarı Bul
Coddy'nin Pygame Journey'sinin Dünyalar bölümünün bir parçası. Ders 34 / 36.
Mağara zemininde bir anahtar duruyor ve bir sonraki adımda bir kapıyı açıyor. K taşı anahtardır: key adlı bir Rect; harita döngüsünde, başlangıçtaki P gibi okunur.
Dokunmak, has_key = True değerini bir kez ayarlar:
if not has_key and player.colliderect(key):
has_key = TrueO zamana kadar anahtar seviyenin bir parçasıdır, bu yüzden kamera üzerinden çizilir. Alındıktan sonra oyuncuya ait olur, bu yüzden kalplerin yanındaki üst çubuğa taşınır ve kamera kullanılmadan çizilir:
if not has_key:
screen.blit(key_img, (key.x - camera_x, key.y))
# kalplerden sonra
if has_key:
screen.blit(key_img, (130, 8))Görev
OrtaMağaraya bir anahtar koy.
key.pngdosyasınıkey_imgiçine yükle vehas_key = Falseolarak ayarla.- Harita döngüsünde, bir
Kdeğerikey = rectayarını yapar. - Blob'ların ardından,
keyile temas etmekhas_key = Trueayarını yapar. has_keydoğru olana kadar anahtarı(key.x - camera_x, key.y)konumunda, ardından(130, 8)konumunda çiz.
“Oyna” düğmesine bas ve anahtara doğru yürü: anahtar üst çubuğa taşınır. Ardından “Kontrol et” düğmesine bas.
Kendin dene
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()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
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")
coin_img = load("coin.png")
spikes_img = load("spikes.png")
heart_img = load("heart.png")
heart_empty_img = load("heart_empty.png")
blob_img = load("blob.png")
blob_walk_img = load("blob_walk.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] == "#"
class Blob(pygame.sprite.Sprite):
def __init__(self, midbottom):
super().__init__()
self.frames = [blob_img, blob_walk_img]
self.image = blob_img
self.rect = pygame.Rect(0, 0, 30, 26)
self.rect.midbottom = midbottom
self.direction = 1
self.timer = 0
def update(self):
self.timer += 1
self.image = self.frames[self.timer // 10 % 2]
self.rect.x += self.direction
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
walls = []
tiles = []
coins = []
spikes = []
blobs = pygame.sprite.Group()
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
elif char == "C":
coins.append(rect)
elif char == "^":
spikes.append(pygame.Rect(rect.x, rect.y + 18, TILE, 18))
elif char == "E":
blobs.add(Blob(rect.midbottom))
level_width = len(LEVEL[0]) * TILE
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
camera_x = 0
coins_collected = 0
lives = 3
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
hurt = False
if player.top > HEIGHT:
hurt = True
for coin in coins[:]:
if player.colliderect(coin):
coins.remove(coin)
coins_collected += 1
for spike in spikes:
if player.colliderect(spike):
hurt = True
blobs.update()
for blob in blobs:
if player.colliderect(blob.rect):
if vel_y > 0 and player.bottom < blob.rect.centery:
blob.kill()
vel_y = -8
else:
hurt = True
if hurt:
lives -= 1
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))
for coin in coins:
screen.blit(coin_img, (coin.x - camera_x, coin.y))
for spike in spikes:
screen.blit(spikes_img, (spike.x - camera_x, spike.y - 18))
for blob in blobs:
spot = blob.image.get_rect(midbottom=(blob.rect.centerx - camera_x, blob.rect.bottom))
screen.blit(blob.image, spot)
screen.blit(player_img, (player.x - camera_x, player.y))
for i in range(3):
if i < lives:
screen.blit(heart_img, (10 + i * 40, 8))
else:
screen.blit(heart_empty_img, (10 + i * 40, 8))
text = font.render(f"Coins: {coins_collected}", True, (255, 255, 255))
screen.blit(text, text.get_rect(topright=(WIDTH - 12, 14)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Dünyalar bölümündeki tüm dersler
1Metinden Haritalar
Metinde Bir SeviyeSatırlar ve SütunlarAnlam Taşıyan HarflerOyuncunun Başladığı YerHer Seferinde Bir Ekran3Yerçekimi ve Zıplama
Yerçekimiyle DüşmeYerden ZıplamaKısa SıçrayışlarEn Yüksek Düşme HızıZıplama Tamponu6Devriye Gezen Düşmanlar
Devriye Gezen Bir BlobÜzerine Bas ya da Darbe AlYürüme DöngüsüHaritadaki DüşmanlarKendi başına pratik yap: Pygame playground