Уровень, камера и платформер
Уровень из строк
Уровень удобно нарисовать прямо в коде — строками символов:
LEVEL = [
"....o.o.....",
"...#####....",
".P.......o..",
"############",
]
Каждая клетка карты становится спрайтом. Строки считаются сверху, а y в arcade растёт вверх — поэтому номер строки переворачивают:
rows = len(LEVEL)
for row, line in enumerate(LEVEL):
for col, ch in enumerate(line):
x = col * SIZE + SIZE // 2
y = (rows - 1 - row) * SIZE + SIZE // 2
if ch == "#":
self.walls.append(arcade.SpriteSolidColor(SIZE, SIZE, center_x=x, center_y=y))
elif ch == "o":
self.coins.append(arcade.SpriteCircle(SIZE // 4, arcade.color.GOLD, center_x=x, center_y=y))
Для больших уровней рисуют карты в бесплатном редакторе Tiled и загружают их одной строкой: arcade.load_tilemap("level.tmx") и arcade.Scene.from_tilemap(...). Внутри — та же идея: слои клеток превращаются в списки спрайтов.
Камера
Уровень больше окна, поэтому нужна камера — она показывает часть мира вокруг своего центра.
self.camera = arcade.Camera2D() # камера мира
self.gui = arcade.Camera2D() # неподвижная камера для счёта и жизней
def on_update(self, delta_time):
self.camera.position = (self.player.center_x, self.player.center_y)
def on_draw(self):
self.clear()
with self.camera.activate(): # всё внутри рисуется «в мире»
self.walls.draw()
self.players.draw()
with self.gui.activate(): # а это — поверх, на месте экрана
arcade.draw_text(f"Счёт: {self.score}", 10, 570, arcade.color.WHITE, 16)
Чтобы у краёв уровня не была видна пустота, центр камеры ограничивают: не ближе половины окна к краю.
x = arcade.math.clamp(player.center_x, VIEW_W // 2, LEVEL_W - VIEW_W // 2)
Если уровень меньше окна, ограничение теряет смысл — камеру просто ставят в центр уровня.
Движущиеся платформы
Лифт — стена, у которой есть скорость. Игрок, стоящий на нём, должен ехать вместе с ним. Порядок важен:
- проверить, стоит ли игрок на лифте (
player.bottom == lift.topи есть перекрытие по горизонтали); - сдвинуть лифт;
- если стоял — сдвинуть игрока на столько же.
В PhysicsEnginePlatformer такие платформы уже поддерживаются: у стены задают change_x или change_y и границы boundary_left, boundary_right, boundary_bottom, boundary_top.
Итог
- карта из строк → спрайты; строку переворачивают:
(rows - 1 - row) * size; arcade.Camera2D,camera.position,with camera.activate():; отдельная камера для интерфейса;- центр камеры ограничивают
clampс отступом в половину окна; - лифт: проверить → сдвинуть лифт → сдвинуть игрока.
Вы прошли все части платформера: рисование, спрайты, монеты и шипы, гравитацию и прыжки, камеру и уровень. Попробуйте добавить в игру из последней задачи шипы, врагов-патрульных и лифт — всё это вы уже чинили.