Un monstre
Leçon 5 sur 20 du cours Projet Pygame : Défendez le donjon de Coddy.
Un monstre marche tout droit vers le chevalier. pygame.Vector2 contient une coordonnée x et une coordonnée y qui peuvent avoir des décimales, et tu peux additionner et soustraire des Vector2 entiers :
step = pygame.Vector2(target) - self.pos
if step.length() > 0:
self.pos += step.normalize() * self.speed
self.rect.center = self.posstep pointe du monstre vers le chevalier, quelle que soit la distance qui les sépare. normalize() conserve sa direction, mais lui donne une longueur de 1 pixel ; multiplié par self.speed, le monstre se déplace exactement à sa vitesse à chaque image, dans n’importe quelle direction. Un Rect ne contient que des nombres entiers, donc la position exacte se trouve dans self.pos et le Rect la suit.
Chaque type de monstre occupe une ligne dans une table, donc ajouter un type plus tard ne nécessite qu’une ligne :
MONSTERS = {
"slime": {"image": load("slime.png"), "speed": 1.0},
}Les monstres arrivent de l’extérieur de la fenêtre. edge_point() choisit un côté avec random.randint(0, 3) et un emplacement aléatoire le long de ce côté, à 24 pixels à l’extérieur.
Défi
Moyenimport randomet ajoute le tableauMONSTERSavec le monstre glu.- Écris
edge_point(): le côté 0 est(random.randint(0, WIDTH), -24), le côté 1 utilise la même coordonnée avecHEIGHT + 24, le côté 2 est(-24, random.randint(0, HEIGHT))et le côté 3 utilise la même coordonnée avecWIDTH + 24. - Écris
class Monster(pygame.sprite.Sprite):__init__(self, kind, pos)conservekind,imageetspeeddu tableau,possous forme de Vector2 et unrectde 28 par 28 centré sur cette position ;update(self, target)se déplace comme précédemment. - Dans
Night:self.monsters = pygame.sprite.Group()avec un monstre glu àedge_point();updateappelleself.monsters.update(self.knight.rect.center). Dessine chaque monstre avecdrawavant le chevalier.
Essayez vous-même
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")
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}"
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 Night:
def __init__(self):
self.knight = Knight()
self.time = 0
def update(self, keys):
self.time += 1
self.knight.move(keys)
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
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()
Toutes les leçons de Projet Pygame : Défendez le donjon
Entraînez-vous par vous-même : Playground Pygame