לדרוך או להיפגע
חלק מהיחידה עולמות במסלול ה-Pygame של Coddy. שיעור 25 מתוך 35.
מגע בכתם צריך להיות משמעותי בשתי דרכים. נוחתים עליו מלמעלה והכתם מובס. נתקלים בו והדמות נפגעת.
ההבדל הוא האופן שבו הדמות הגיעה אליו. היא הגיעה מלמעלה אם היא נופלת, vel_y > 0, וכפות הרגליים שלה עדיין מעל מרכז הכתם:
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:
player.midbottom = start
vel_y = 0blob.kill() מסיר את הספרייט מהקבוצה, ולכן הוא כבר לא מתעדכן או מצויר. vel_y = -8 הוא קפיצה קטנה, שמאותתת לדמות שהנחיתה עבדה ומאפשרת לה לשרשר אותה לקפיצה. כל מגע אחר הוא פגיעה מהצד או מלמטה, והדמות חוזרת להתחלה, כמו אחרי נפילה.
עוברים בלולאה על הקבוצה כדי לבדוק כל כתם. השימוש ב-kill() בתוך הלולאה בטוח כאן, כי הלולאה עוברת על הספרייטים שהיו בקבוצה כשהיא התחילה.
אתגר
בינוני- לאחר שהבועות נעות, בצע לולאה על
blobs. - כשהשחקן מתנגש ב־Rect של בועה: אם
vel_y > 0וגםplayer.bottom < blob.rect.centery, קרא ל־blob.kill()והגדרvel_y = -8. - אחרת, הגדר
player.midbottom = startוגםvel_y = 0.
נסו בעצמכם
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("Stomp")
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()
blob_img = pygame.image.load("assets/images/blob.png").convert_alpha()
class Blob(pygame.sprite.Sprite):
def __init__(self, midbottom):
super().__init__()
self.image = blob_img
self.rect = pygame.Rect(0, 0, 30, 26)
self.rect.midbottom = midbottom
self.direction = 1
def update(self):
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 = []
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)
blobs = pygame.sprite.Group(Blob((432, 144)), Blob((432, 324)))
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
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
blobs.update()
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)
for blob in blobs:
screen.blit(blob.image, blob.image.get_rect(midbottom=blob.rect.midbottom))
screen.blit(player_img, player)
pygame.display.flip()
clock.tick(60)
pygame.quit()
כל השיעורים ביחידה עולמות
תרגלו בעצמכם: Pygame אונליין