The Knight
Part of the Projects section of Coddy's Pygame journey. Lesson 23 of 33.
The knight starts on the P of the map.
His picture is a whole tile, 48 by 48, and so are the gaps between walls. A 48 pixel Rect would fit a gap only when lined up to the exact pixel. So the knight's Rect is smaller than his picture, 32 by 32, and the picture is drawn centred on it. The Rect is what collides; the picture is what you see.
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 rectcell_rect(col, row) is the 32 by 32 Rect in the middle of a tile. The knight is a sprite, like the runner of Sky Runner, made at a point:
class Knight(pygame.sprite.Sprite):
def __init__(self, center):
super().__init__()
self.image = knight_img
self.rect = pygame.Rect(0, 0, 32, 32)
self.rect.center = centerChallenge
MediumPut the knight in the first room, standing on the P.
- Add the
drawandcell_rectfunctions above. - In
Room, setself.start = (72, 72); aPsetsself.start = cell_rect(col, row).center. - Write the
Knightclass above, and makeknight = Knight(room.start)after the room. - After the walls, call
draw(knight.image, knight.rect).
Press Play: the knight stands on the P. Then Check.
Try it yourself
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()
All lessons in Projects
Practice on your own: Pygame playground