Seekor Monster
Pelajaran 5 dari 20 dalam kursus Proyek Pygame: Pertahankan Benteng di Coddy.
Monster berjalan lurus menuju ksatria. pygame.Vector2 menyimpan nilai x dan y yang dapat berupa desimal, dan kamu dapat menjumlahkan serta mengurangkan Vector2 utuh:
step = pygame.Vector2(target) - self.pos
if step.length() > 0:
self.pos += step.normalize() * self.speed
self.rect.center = self.posstep mengarah dari monster ke ksatria, sejauh apa pun jaraknya. normalize() mempertahankan arahnya, tetapi membuat panjangnya 1 piksel, jadi dikalikan dengan self.speed, monster bergerak tepat sejauh kecepatannya setiap frame, ke arah mana pun. Rect hanya menyimpan bilangan bulat, jadi posisi tepatnya tersimpan di self.pos dan Rect mengikutinya.
Setiap jenis monster mendapat satu baris dalam tabel, jadi menambahkan jenis baru nanti hanya perlu satu baris:
MONSTERS = {
"slime": {"image": load("slime.png"), "speed": 1.0},
}Monster muncul dari luar jendela. edge_point() memilih satu sisi dengan random.randint(0, 3) dan titik acak di sepanjang sisi itu, 24 piksel dari tepinya.
Tantangan
Sedang- Tambahkan
import randomdan tabelMONSTERSyang berisi slime. - Tulis
edge_point(): sisi 0 adalah(random.randint(0, WIDTH), -24), sisi 1 sama, tetapi menggunakanHEIGHT + 24, sisi 2 adalah(-24, random.randint(0, HEIGHT)), dan sisi 3 sama, tetapi menggunakanWIDTH + 24. - Tulis
class Monster(pygame.sprite.Sprite):__init__(self, kind, pos)menyimpankind,image, danspeeddari tabel,possebagai Vector2, sertarectberukuran 28 kali 28 yang berpusat padanya;update(self, target)bergerak seperti di atas. - Di dalam
Night:self.monsters = pygame.sprite.Group()dengan satu slime diedge_point();updatememanggilself.monsters.update(self.knight.rect.center). Gambar setiap monster dengandrawsebelum knight.
Coba sendiri
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()
Semua pelajaran di Proyek Pygame: Pertahankan Benteng
Latihan sendiri: Playground Pygame