Der Ritter läuft
Teil des Abschnitts Projekte der Pygame-Journey von Coddy. Lektion 22 von 31.
Der Ritter startet auf dem P der Karte und bewegt sich mit den Pfeiltasten, 3 Pixel pro Frame.
Sein Bild füllt ein ganzes Feld, 48 mal 48, und genauso groß sind auch die Abstände zwischen den Wänden. Ein 48 Pixel großes Rect würde nur dann in einen Abstand passen, wenn es genau auf den Pixel ausgerichtet ist. Das Rect des Ritters ist also kleiner als sein Bild, 32 mal 32, und das Bild wird mittig darauf gezeichnet. Das Rect kollidiert; das Bild ist das, was du siehst.
def draw(image, rect):
screen.blit(image, image.get_rect(center=rect.center))
def cell_rect(col, row):
rect = pygame.Rect(0, 0, 32, 32)
rect.center = (col * TILE + 24, row * TILE + 24)
return rectDie Wände halten ihn auf dieselbe Weise auf wie die Plattformen in Moss Caves: Bewege ihn entlang der x-Achse, schiebe ihn aus jeder Wand, die er überlappt, und mache dann dasselbe entlang der y-Achse. Wenn du jeweils nur eine Achse bearbeitest, erkennst du, welche Seite er getroffen hat.
def move(self, dx, dy, blocks):
self.rect.x += dx
for block in blocks:
if self.rect.colliderect(block):
if dx > 0:
self.rect.right = block.left
elif dx < 0:
self.rect.left = block.right
# dann dasselbe für dy, mit bottom und topAufgabe
Schwer- Füge die Funktionen
drawundcell_rectoben hinzu. - Setze in
Roomvor der Schleifeself.start = (72, 72)und für einPself.start = cell_rect(col, row).center. - Schreibe
class Knight(pygame.sprite.Sprite): Die Methode__init__(self, center)setztself.image = knight_imgund ein 32 × 32 großesself.rect, das aufcenterzentriert ist. Füge die oben gezeigte Methodemove(dx, dy, blocks)mit dem y-Teil hinzu. - Erstelle nach dem Raum
knight = Knight(room.start). - Setze in jedem Frame
dxauf -3 bei Links oder auf 3 bei Rechts unddyauf -3 bei Oben oder auf 3 bei Unten (ansonsten auf 0). Rufe dannknight.move(dx, dy, room.walls)auf. - Zeichne den Ritter nach den Wänden:
draw(knight.image, knight.rect).
Probier es selbst
import pygame
TILE = 48
MAP = [
"##############",
"#............#",
"#.P......K...#",
"#............#",
"#....##......D",
"#....##......#",
"##.#######.###",
"#............#",
"#...S....H...#",
"##############",
]
pygame.init()
screen = pygame.display.set_mode((672, 480))
pygame.display.set_caption("Rune Keep")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)
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")
door_img = load("dungeon_door.png")
key_img = load("key.png")
slime_img = load("slime.png")
spider_img = load("spider.png")
heart_img = load("heart.png")
empty_img = load("heart_empty.png")
sword_img = load("sword.png")
potion_img = load("potion_red.png")
class Room:
def __init__(self, lines):
self.walls = []
for row, line in enumerate(lines):
for col, char in enumerate(line):
if char == "#":
self.walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
room = Room(MAP)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
for row in range(10):
for col in range(14):
screen.blit(floor_img, (col * TILE, row * TILE))
for wall in room.walls:
screen.blit(wall_img, wall)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Projekte
Übe selbstständig: Pygame-Playground