الأشواك والقلوب
جزء من قسم العوالم في رحلة Pygame على Coddy. الدرس 32 من 35.
تحتاج اللعبة إلى الخطر. لدى المستكشف 3 أرواح، تُعرض على شكل قلوب. تُكلّف الأشواك والسقوط خارج الكهف روحًا واحدة لكل منهما.
تملأ الأشواك النصف السفلي فقط من بلاطتها، لذا يكون Rect الخاص بها هو النصف السفلي: pygame.Rect(rect.x, rect.y + 18, TILE, 18). ارسم الصورة أعلى بمقدار 18 بكسل، عند زاوية البلاطة.
تؤدي الأخطار المتعددة الفعل نفسه: تسلب روحًا وتعيد المستكشف إلى نقطة البداية. امنحها علمًا مشتركًا واحدًا وكتلة واحدة تتصرف بناءً عليه:
hurt = False
if player.top > HEIGHT:
hurt = True
for spike in spikes:
if player.colliderect(spike):
hurt = True
# لاحقًا
if hurt:
lives -= 1
player.midbottom = start
vel_y = 0القلوب صور ثلاث مرتبة في صف أعلى اليسار: ممتلئة لكل روح متبقية، وفارغة لكل روح مفقودة.
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))التحدي
متوسط- حمّل
spikes.pngوheart.pngوheart_empty.pngإلىspikes_imgوheart_imgوheart_empty_img. - أنشئ
spikes = []وlives = 3؛ ولكل^، أضف النصف السفلي من المستطيل. - استبدل إعادة الضبط عند السقوط بـ
hurt = True؛ واجعلhurtكذلكTrueعندما يلمس اللاعب شوكة. ضع كتلةif hurt:بعد العملات. - ارسم الأشواك عند
(spike.x - camera_x, spike.y - 18)والقلوب الثلاثة في أعلى اليسار.
جرّب بنفسك
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")
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 = []
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)
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
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
if player.top > HEIGHT:
player.midbottom = start
vel_y = 0
for coin in coins[:]:
if player.colliderect(coin):
coins.remove(coin)
coins_collected += 1
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))
screen.blit(player_img, (player.x - camera_x, player.y))
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