מכל צד
שיעור 6 מתוך 20 בקורס פרויקט Pygame: להגן על המצודה של Coddy.
רירון אחד הוא לא עדר. צרו רירון חדש בכל שנייה. self.time % 60 שווה ל־0 פעם בכל 60 פריימים, ולכן זה מוסיף מפלצת פעם בשנייה:
def spawn(self):
if self.time % 60 == 0:
self.monsters.add(Monster("slime", edge_point()))יצירה של דברים חדשים נקראת זימון. תנו לה מתודה משלה: בשיעורים הבאים ישתנו התדירות והסוג, וכל זה יהיה בתוך spawn.
קראו לה מתוך update לפני שהמפלצות זזות, כדי שמפלצת חדשה תעשה את הצעד הראשון שלה בפריים שבו היא מופיעה.
אתגר
קל- הסר את הרפש היחיד מתוך
Night.__init__. - כתוב את
spawn(self): בכל 60 פריימים, רפש ב־edge_point(). - קרא ל־
self.spawn()בתוךupdate, אחרי שהאביר זז ולפניself.monsters.update(...).
נסו בעצמכם
import random
import pygame
WIDTH, HEIGHT = 720, 480
TILE = 48
NIGHT = 60 * 60 * 4
WHITE = (240, 240, 240)
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Hold the Keep")
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()
floor_img = load("floor.png")
wall_img = load("wall.png")
knight_img = load("knight.png")
MONSTERS = {
"slime": {"image": load("slime.png"), "speed": 1.0},
}
courtyard = pygame.Rect(TILE, TILE, WIDTH - 2 * TILE, HEIGHT - 2 * TILE)
background = pygame.Surface((WIDTH, HEIGHT))
for row in range(HEIGHT // TILE):
for col in range(WIDTH // TILE):
x = col * TILE
y = row * TILE
if courtyard.collidepoint(x, y):
background.blit(floor_img, (x, y))
else:
background.blit(wall_img, (x, y))
def draw(image, center):
screen.blit(image, image.get_rect(center=center))
def clock_text(frames):
seconds = frames // 60
return f"{seconds // 60}:{seconds % 60:02d}"
def edge_point():
side = random.randint(0, 3)
if side == 0:
return (random.randint(0, WIDTH), -24)
if side == 1:
return (random.randint(0, WIDTH), HEIGHT + 24)
if side == 2:
return (-24, random.randint(0, HEIGHT))
return (WIDTH + 24, random.randint(0, HEIGHT))
class Knight(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = knight_img
self.rect = pygame.Rect(0, 0, 24, 24)
self.rect.center = courtyard.center
self.speed = 3
def move(self, keys):
if keys[pygame.K_LEFT]:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT]:
self.rect.x += self.speed
if keys[pygame.K_UP]:
self.rect.y -= self.speed
if keys[pygame.K_DOWN]:
self.rect.y += self.speed
self.rect.clamp_ip(courtyard)
class Monster(pygame.sprite.Sprite):
def __init__(self, kind, pos):
super().__init__()
self.kind = kind
self.image = MONSTERS[kind]["image"]
self.speed = MONSTERS[kind]["speed"]
self.pos = pygame.Vector2(pos)
self.rect = pygame.Rect(0, 0, 28, 28)
self.rect.center = self.pos
def update(self, target):
step = pygame.Vector2(target) - self.pos
if step.length() > 0:
self.pos += step.normalize() * self.speed
self.rect.center = self.pos
class Night:
def __init__(self):
self.knight = Knight()
self.time = 0
self.monsters = pygame.sprite.Group()
self.monsters.add(Monster("slime", edge_point()))
def update(self, keys):
self.time += 1
self.knight.move(keys)
self.monsters.update(self.knight.rect.center)
night = Night()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
night.update(pygame.key.get_pressed())
screen.blit(background, (0, 0))
knight = night.knight
for monster in night.monsters:
draw(monster.image, monster.rect.center)
draw(knight.image, knight.rect.center)
left = font.render(clock_text(max(0, NIGHT - night.time)) + " until dawn", True, WHITE)
screen.blit(left, left.get_rect(center=(WIDTH // 2, 24)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
כל השיעורים ביחידה פרויקט Pygame: להגן על המצודה
תרגלו בעצמכם: Pygame אונליין