---
title: "Эволюция 2D-камеры: от одного экрана Space Invaders и Defender до скроллинга Super Mario Bros. и The Legend of Zelda"
description: "Исторический и инженерный разбор эволюции камеры в 2D-играх: неподвижный экран Space Invaders (1978), радар и упреждение камеры в Defender (1981), регистр PPUSCROLL и запрет возврата влево в Super Mario Bros. (1985), комнаты 16×11 тайлов в The Legend of Zelda (1986) и проверенный код двух камер на JavaScript."
slug: evolyuciya-2d-kamery-ot-odnogo-ekrana-do-skrollinga
date: 2026-11-01
updated: 2026-11-02
scheduled_at: "2026-11-01T14:00:00+03:00"
rubric: istoriya-2d-igr
tags: ["istoriya-igr", "kamera", "skrolling", "retro-igry", "gejmdizajn"]
reading_time: 10
draft: false
summary: "За восемь лет — с 1978 по 1986 год — 2D-игры прошли путь от неподвижного экрана Space Invaders до протяжённых миров, которые не помещались в видеопамять целиком. Инженеры нашли три базовых способа показать большой мир через маленькое окно экрана: двунаправленную прокрутку с миникартой-радаром (Defender, 1981), непрерывный аппаратный скроллинг в одну сторону с подгрузкой тайлов за кадром (Super Mario Bros., 1985) и дискретное переключение комнат по сетке (The Legend of Zelda, 1986). Все три схемы по-прежнему лежат в основе современных 2D-игр."
---

## Коротко

Первые 2D-аркады помещались на одном неподвижном экране, потому что процессоры конца 1970-х годов не успевали перерисовывать тысячи байт фона `60` раз в секунду. Когда миры стали шире экрана, разработчики изобрели три фундаментальные модели камеры: скоростное упреждение по курсу корабля с верхней миникартой-радаром в *Defender* (1981), односторонний аппаратный скроллинг через регистр `PPUSCROLL` в *Super Mario Bros.* (1985) и покомнатное переключение экранов `16 × 11` тайлов в *The Legend of Zelda* (1986). В статье разобрано аппаратное устройство этих трёх решений по материалам исследования Итая Керена (GDC 2015) и документации NESdev, приведены формулы каждой камеры и проверенный в Node.js код покомнатной и односторонней камеры.

## Содержание

1. Один неподвижный экран: почему Space Invaders (1978) не могла двигать камеру
2. Defender (1981): выход за границы экрана, камера с упреждением и радар
3. Super Mario Bros. (1985): регистр PPUSCROLL и почему Марио не может пойти назад
4. The Legend of Zelda (1986): дискретная сетка комнат 16×11 тайлов
5. Практический сценарий: переключение комнат и односторонняя камера на JavaScript
6. Когда вам это не подойдёт

## Один неподвижный экран: почему Space Invaders (1978) не могла двигать камеру

В аркадах конца 1970-х годов — *Pong* (1972), *Breakout* (1976) и *Space Invaders* (Taito, конструктор Томохиро Нисикадо, 1978 год) — камера была жёстко прибита к одной позиции: весь игровой мир совпадал с размерами телевизионного кинескопа.

Причина была чисто аппаратной. В автомате *Space Invaders* центральный процессор Intel 8080 на тактовой частоте `2 МГц` работал с кадровым буфером объёмом `7 КБ` (`7168` байт), который отображал монохромную растровую сетку `224 × 256` пикселей (по `8` однобитных пикселей в каждом байте; источник: техническая схема автомата Taito *Space Invaders Maintenance Manual*, 1978 год, проверено: октябрь 2026). У видеосхемы не было ни аппаратных спрайтов, ни регистра сдвига фона:
- Даже чтобы сдвинуть `55` инопланетян, процессор перерисовывал только по **одному** пришельцу за кадр (`1/60` с) — поэтому полный шаг строя из `55` врагов занимал почти секунду, а по мере уничтожения врагов оставшиеся двигались всё быстрее;
- Если бы игра попыталась сдвинуть весь фон на `1` пиксель в сторону, процессору пришлось бы копировать все `7168` байт в каждом кадре (`7168 × 60 = 430 080` байт в секунду), на что тактовой частоты `2 МГц` физически не хватало.

## Defender (1981): выход за границы экрана, камера с упреждением и радар

В феврале 1981 года Юджин Джарвис и студия Williams Electronics выпустили космический шутер *Defender*, который разорвал рамки одного экрана: действие разворачивалось над поверхностью планеты на горизонтальной ленте шириной `2048` мировых единиц — примерно в `6,4` раза шире видимого окна `320 × 256` пикселей, замкнутой в кольцо.

Как показал исследователь геймдизайна Итай Керен в своём историческом докладе на конференции GDC 2015 (*«Scroll Back: The Theory and Practice of Cameras in Side-Scrollers»*, Game Developers Conference, март 2015 года, проверено: октябрь 2026), в *Defender* впервые появились сразу два приёма работы с широким 2D-миром:

1. **Смещение камеры в сторону полёта (Camera Look-Ahead):** если держать быстро летящий истребитель строго по центру экрана `(160; 128)`, у игрока остаётся всего `160` пикселей обзора впереди — на высокой скорости вражеский снаряд прилетает быстрее времени реакции человека. Поэтому при полёте вправо камера *Defender* прижимает корабль к левой четверти экрана (`X ≈ 64..80` пикс), отдавая `75%` ширины монитора (`240` пикселей) под обзор впереди по курсу. При развороте корабля влево камера переезжает так, чтобы корабль оказался у правого края:

```text
targetCameraX = shipX + shipDirection * lookAheadOffset
```

2. **Двухуровневое зрение (основной вид + радар):** поскольку игрок видел только `15%` ширины планеты в конкретный момент, верхние `32` пикселя экрана занял сканер-миникарта (`Radar`), показывавший положение всех похитителей и астронавтов на всём кольце планеты сразу.

## Super Mario Bros. (1985): регистр PPUSCROLL и почему Марио не может пойти назад

В сентябре 1985 года Сигэру Миямото, Такаси Тэдзука и ведущий программист Тосихико Накаго выпустили *Super Mario Bros.* для консоли Famicom / NES. Чтобы плавно прокручивать длинные уровни на частоте `60 к/с` при крошечном объёме оперативной памяти (`2 КБ` основной RAM и `2 КБ` видеопамяти VRAM), игра опиралась на аппаратное устройство видеопроцессора Ricoh 2C02 (PPU).

По технической документации архитектуры NES (справочник *NESdev Wiki: PPU scrolling и регистр PPUSCROLL 0x2005*, проверено: октябрь 2026), видеопамять консоли хранила одновременно ровно две экранные таблицы фоновых тайлов (*Nametables*), каждая размером `32 × 30` тайлов по `8×8` пикселей (`256 × 240` пикселей):
- Чтобы сдвинуть весь фон на экране на любое число пикселей от `0` до `255` по горизонтали, процессору больше не нужно было копировать тысячи байт — достаточно было один раз за кадр записать два байта смещения `(scrollX, scrollY)` в аппаратный регистр **`PPUSCROLL`** по адресу `0x2005`;
- Пока камера плавно двигалась вправо по первому экрану (`Nametable A`), игра незаметно за правым обрезом телевизора дописывала в видеопамять по одному новому вертикальному столбцу из `16×16` мета-тайлов во второй экран (`Nametable B`).

Именно из экономии `2 КБ` оперативной памяти родилось знаменитое правило камеры *Super Mario Bros.* — **односторонний храповик (One-Way Camera Lock)**:
- Консоль не могла хранить в памяти изменённое состояние всего пройденного уровня (какие кирпичи уже разбиты, какие монеты собраны, какие грибы сбиты позади игрока) и не имела буфера для подгрузки столбцов слева;
- Поэтому координата левого края камеры `cameraLeftX` могла только расти и никогда не уменьшалась:

```text
// Когда Марио переходит середину экрана, он толкает камеру вправо:
newCameraLeftX = playerX - 128

// Храповик: камера никогда не сдвигается назад влево
cameraLeftX    = max(cameraLeftX, newCameraLeftX)

// Левый край экрана служит невидимой стеной для самого игрока:
playerX        = max(playerX, cameraLeftX + 8)
```

Это техническое ограничение 1985 года стало приёмом геймдизайна: односторонняя камера задаёт постоянный темп движения вперёд и используется в современных аркадах, раннерах и скролл-шутерах.

## The Legend of Zelda (1986): дискретная сетка комнат 16×11 тайлов

Через пять месяцев после *Super Mario Bros.*, в феврале 1986 года, та же команда Nintendo выпустила *The Legend of Zelda*, где для исследования большого нелинейного мира применила противоположную архитектуру камеры — **дискретное переключение комнат (Room Switching / Screen-by-Screen Flip)**.

Верхний мир игры (*Overworld*) представляет собой прямоугольную таблицу из `16 × 8 = 128` отдельных экранов-комнат. Каждый экран разбит следующим образом:
- Верхние `64` пикселя высоты (`256 × 64`) занимает неподвижная панель интерфейса (карта, инвентарь и сердечки жизни);
- Оставшиеся `256 × 176` пикселей образуют игровое поле комнаты, выложенное сеткой ровно из **`16 × 11` мета-тайлов** размером `16×16` пикселей каждый (`16 × 16 = 256` пикс по ширине, `11 × 16 = 176` пикс по высоте).

Пока Линк ходит внутри одной комнаты `(roomCol, roomRow)`, камера абсолютно неподвижна. Как только координаты героя выходят за границу `256 × 176`, игра вычисляет индекс новой комнаты и переводит камеру ровно на один экран в сторону перехода:

```text
roomCol       = floor(playerX / roomWidth)
roomRow       = floor(playerY / roomHeight)
targetCameraX = roomCol * roomWidth  + roomWidth / 2
targetCameraY = roomRow * roomHeight + roomHeight / 2
```

Таблица: Сравнение трёх классических архитектур 2D-камеры для выбора под свою игру

| Архитектура камеры | Исторический эталон | Формула координаты камеры `camX` | Когда выбирать в своей 2D-игре |
|---|---|---|---|
| **Односторонний храповик (только вперёд)** | *Super Mario Bros.* (1985) | `camX = max(camX, playerX)` | Динамичные аркады, линейные уровни на время, горизонтальные и вертикальные скролл-шутеры |
| **Свободное слежение с упреждением** | *Defender* (1981), *Sonic* (1991) | `camX = lerp(camX, playerX + dir * offset, t)` | Просторные исследовательские платформеры, гонки, полёты с возвратом по карте |
| **Дискретные комнаты по сетке** | *The Legend of Zelda* (1986), *Celeste* (2018) | `camX = floor(playerX / W) * W + W / 2` | Приключения с видом сверху, покомнатные головоломки, хардкорные платформеры с перезапуском одной комнаты |

Заметьте: вышедший в 2018 году платформер *Celeste* тоже построен по принципу отдельных комнат *The Legend of Zelda* — каждый экран является самостоятельным испытанием, при входе в которое камера плавно переезжает на координаты нового зала и фиксируется по его краям.

## Практический сценарий: переключение комнат и односторонняя камера на JavaScript

Покомнатная камера в духе *The Legend of Zelda* и *Celeste* и односторонний храповик в духе *Super Mario Bros.* для окна `1280 × 720` укладываются в две короткие функции на JavaScript. Код ниже проверен в Node.js 24; комментарии показывают его фактический вывод.

```js
const VIEW_W = 1280, VIEW_H = 720;

// 1. Покомнатная камера (Zelda, Celeste): центр комнаты, в которой стоит игрок
function roomCamera(playerX, playerY) {
  const roomCol = Math.floor(playerX / VIEW_W);
  const roomRow = Math.floor(playerY / VIEW_H);
  return { x: roomCol * VIEW_W + VIEW_W / 2, y: roomRow * VIEW_H + VIEW_H / 2, roomCol: roomCol };
}
console.log(roomCamera(1270, 400)); // { x: 640, y: 360, roomCol: 0 }
console.log(roomCamera(1290, 400)); // { x: 1920, y: 360, roomCol: 1 }

// 2. Односторонняя камера (Super Mario Bros.): центр камеры только растёт,
// левый край окна — невидимая стена для игрока с отступом 16 пикс
function createRatchet() { return { camX: VIEW_W / 2 }; }
function updateRatchet(cam, player) {
  cam.camX = Math.max(cam.camX, player.x);
  const leftWall = cam.camX - VIEW_W / 2 + 16;
  if (player.x < leftWall) player.x = leftWall;
}
const cam = createRatchet(), player = { x: 100 };
for (const x of [500, 900, 1500, 1200, 300]) { player.x = x; updateRatchet(cam, player); }
console.log(cam.camX, player.x); // 1500 876 — назад дальше левого края окна не пройти
```

Переход через отметку `X = 1280` переключает камеру с центра `640` на центр второй комнаты `1920`, а храповик после рывка до `X = 1500` не пускает игрока левее `876` пикселей. В покомнатном режиме при смене комнаты стоит сохранять точку возрождения у входа, чтобы после ошибки игрок перезапускал только текущий зал.

## Когда вам это не подойдёт

Исторические режимы жёсткой односторонней или покомнатной камеры подходят не каждой игре:

- **Метроидвании и квесты с постоянным возвратом за секретами:** если заблокировать возврат камеры влево по схеме *Super Mario Bros.*, игрок не сможет вернуться к развилке или запертому сундуку — там нужна двунаправленная камера.
- **Сверхскоростные полёты и гонки при покомнатном делении:** если корабль летит со скоростью `800 пикс/с`, он будет пересекать комнату шириной `1280` пикселей каждые `1,6 секунды`, и постоянные переключения экранов утомят глаза — для высоких скоростей нужна плавная камера с упреждением по схеме *Defender*.
- **Игры на одном экране:** если поле целиком помещается в окно, как в *Space Invaders*, камера не нужна вовсе — любая из трёх схем только добавит код.

---

Мы разрабатываем **J2DRU** — браузерный 2D игровой движок; он в разработке и публично пока не открыт, заявку можно оставить на [странице раннего доступа](/early-access?utm_source=blog&utm_medium=article&utm_campaign=evolyuciya-2d-kamery-ot-odnogo-ekrana-do-skrollinga) (подача заявки не гарантирует приглашение).

**Читайте также:**
- [Камера, параллакс и «джус» (Game Feel): как оживить 2D-сцену](/blog/kamera-parallaks-i-game-feel-v-2d-igre)
- [От первых аркад и «Змейки» до инди-хитов: история ключевых механик 2D-игр](/blog/istoriya-klyuchevyh-mehanik-2d-igr)
- [Тайловые сетки и устройство 2D-миров](/blog/tajlovye-setki-i-ustrojstvo-2d-mirov)
