ציר אחד בכל פעם
חלק מהיחידה עולמות במסלול ה-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()
כל השיעורים ביחידה עולמות
תרגלו בעצמכם: Pygame אונליין