الوحوش الهلامية في الكهوف
جزء من قسم العوالم في رحلة Pygame على Coddy. الدرس 33 من 35.
يتجوّل كائنان هلاميان على أرضية الكهف. أضف الصنف Blob من درس الأعداء الذين يتجوّلون، مع دورة مشيه: يستدير عند الجدران والحواف، ويعرض وضعيتيه بالتناوب.
تضيف كل E في الخريطة كائنًا هلاميًا يقف على ذلك البلاط. في كل إطار، حدّث المجموعة، ثم اختبر تصادم كل كائن هلامي مع اللاعب. تؤدي القفزة فوقه إلى إزالته وارتداد اللاعب؛ أما أي ملامسة أخرى فهي خطرة، لذا تضبط hurt كما يحدث عند لمس شوكة:
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ارسم كل كائن هلامي عبر الكاميرا، بحيث يكون منتصف أسفل صورته محاذيًا لمنتصف أسفل مستطيله:
spot = blob.image.get_rect(midbottom=(blob.rect.centerx - camera_x, blob.rect.bottom))
screen.blit(blob.image, spot)التحدي
صعب- حمّل
blob.pngوblob_walk.pngفيblob_imgوblob_walk_img، وأضف الفئةBlobمع دورية الحركة ودورة المشي الخاصة بها، بعدsolid(). - أنشئ
blobs = pygame.sprite.Group()قبل حلقة الخريطة، وأضفBlob(rect.midbottom)لكلE. - في كل إطار، بعد المسامير، حدّث
blobsواسحق الكائنات أو عيّنhurtكما هو موضّح. - ارسم الكائنات بعد المسامير.
جرّب بنفسك
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")
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 = []
coins = []
spikes = []
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))
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
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))
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()
جميع دروس العوالم
4التصادم مع المنصات
الجدران من اليسار واليمينالهبوط على المنصاتارتطام الرأسالسقوط خارج المستوىمحور واحد في كل مرة7كهوف الطحالب
ابنِ الكهوفاركض واقفزتدرّب بنفسك: Playground لـ Pygame