محور واحد في كل مرة
جزء من قسم العوالم في رحلة Pygame على Coddy. الدرس 19 من 35.
يحرّك كود التصادم اللاعب على محور x ويصحّح موضعه، ثم يحرّكه على محور y ويصحّح موضعه. هذا المثال المبدئي يحرّكه على المحورين ويصحّح موضعه مرة واحدة. شغّله وامشِ إلى اليمين: سيقفز اللاعب إلى الخلف على طول الأرض.
player.x += dx
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0عندما يقف اللاعب على الأرض، تحرّكه الجاذبية بمقدار بكسل واحد إلى الأسفل داخل الأرض في كل إطار. وعند التحرك إلى اليمين في الإطار نفسه، يتداخل اللاعب مع قطعة الأرض تحته، ولا يستطيع الكود معرفة السبب. فهو يرى dx > 0 ويضع الجانب الأيمن للاعب عند الجانب الأيسر لتلك القطعة: إلى الخلف، على طول الأرض.
تداخل واحد، وحركتان، ولا سبيل لمعرفة أيّ حركة تسببت فيه. عند التحرك على محور واحد في كل مرة، يكون لكل تداخل سبب واحد. بعد الحركة على محور x، لا يكون اللاعب قد دخل الأرض بعد، لذا لا توقفه إلا الجدران الحقيقية. وبعد الحركة على محور y، لا يمكن أن يكون التداخل إلا ناتجًا عن الحركة على محور y.
التحدي
متوسط- قسّم الحركة:
player.x += dxوحلقة تمرّ علىwallsوتصحّح محور x فقط. - ثم الجاذبية، و
player.y += vel_y، وon_ground = False، وحلقة ثانية تصحّح محور y فقط.
جرّب بنفسك
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("One Axis at a Time")
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)
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
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0
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)
screen.blit(player_img, player)
pygame.display.flip()
clock.tick(60)
pygame.quit()
جميع دروس العوالم
4التصادم مع المنصات
الجدران من اليسار واليمينالهبوط على المنصاتارتطام الرأسالسقوط خارج المستوىمحور واحد في كل مرةتدرّب بنفسك: Playground لـ Pygame