Чтение онлайн

на главную - закладки

Жанры

Шрифт:

Для того чтобы игра могла функционировать на машинах нынешнего времени, придётся отбросить много "фишек" из будущего. Ускорители 3D-графики, как 3D-графические карты, ещё не появились на массовом рынке, и нужно было работать с тем, что есть. Следовательно, всё, что обычно обрабатывалось графическим оборудованием, теперь должно было выполняться центральным процессором со всеми вытекающими из этого последствиями. И основной идеей было задействовать возможности процессоров для построения псевдо-3D графики. Вдохновляясь подходами к рендерингу старых систем, стал думать над алгоритмом, который позволил бы симулировать трёхмерное пространство без полного построения сцены. Пальцы лихо побежали по клавишам,

вводя очередные строчки кода:

```c

// Основная функция рендеринга

void RenderScene {

for (int y = 0; y screenHeight; y++) {

for (int x = 0; x screenWidth; x++) {

// Перевод экрана в псевдо-3D координаты

int mapX = x 3;

int mapY = y 3;

int tileType = map[mapY][mapX];

// Проверка для текстурирования

if (tileType == WALL) {

DrawWall(x, y);

} else {

DrawFloor(x, y);

}

}

}

}

```

Суть этого подхода заключалась в том, чтобы проецировать 2D-карту на экран, таким образом создавая иллюзию 3D-пространства. Для эмуляции высоты использовались заранее подготовленные тайлы – кирпичики, полы, стены – которые накладывались друг на друга, как слои в фотографии. Эффект получался не совсем реальным, но в условиях отсутствия 3D-ускорителя он был весьма неплох. Тем боле пока потребители даже такого не вкусили толком. Ух они у меня устроят мочилово!

Так и продолжал возиться с рендерингом – в каждом шаге приходилось тщательно учитывать ограничения как потенциальных возможностей машин, на которых будут игру запускать, так и того, что мог мой ноут. "Так, без прямой поддержки 3D могу рассчитывать только на простые матричные преобразования и рисовать на основе значений тайлов. Ну, а свет? Ладно, с фальшивым светом подумаю позже...". На этом открыл блокнот, где предварительно набросал идеи для освещения:

1. **Имитировать световые зоны** – в зависимости от расстояния до источника света текстуры становились бы темнее или светлее.

2. **Простая градация** – чем дальше от игрока, тем темнее зона, создавая эффект глубины.

Ещё пара строк кода, и на экране в отдельном окне возникла сцена с характерным серым полом и тёмными стенами. Ощущение присутствия было сырым, но для первого эксперимента неплохо. Да что там, супер, сказал бы даже. Я молодец! Если себя сам не похвалишь, кто это ещё сделает, тем более никто и не знает, какую революцию тут замутил.

```c

void DrawWall(int x, int y) {

// Закрашиваем стену с оттенком серого

int shade = 255 - (distanceToPlayer(x, y) * 10);

shade = max(0, min(shade, 255)); // Ограничиваем значения

SetPixelColor(x, y, RGB(shade, shade, shade));

}

```

"Отлично, - пришла мысль, — это первый шаг. Простейшие стены готовы".

После чего сделал несколько быстрых глотков чая, поглядывая на экран. Несмотря на довольно простую задачу – отрисовку стен и пола, – процесс оказался гораздо более сложным, чем думал внвчале. Даже каждая мелочь, вроде изменения оттенков или расчета расстояний, съедала память и ресурсы процессора. Гадство…. Прибил бы этого Билла Гейтса с его шестнадцатью килобайтами оперативы, которой хватит на всё! Но одна идея крутится в голове, давая новый импульс: вместо полной симуляции каждого шага, можно ведь бы использовать метод **Raycasting**, в прямом переводе звучащий довольно бессмысленно, – метод, которым создавались игры вроде *Wolfenstein 3D* в ранние девяностые годы. Он не требовал 3D-ускорения, но позволял

строить иллюзию трехмерного мира на основе двумерной карты.

Правда появился он куда как ранее, ещё в восьмидесятые, но это сейчас не важно, поскольку до нынешнего времени использовать его в практических приложения возможным не было, поскольку банально не хватало мощности компьютеров. Если сделаю игру и выпущу на рынок раньше, то будут упоминать меня, а не Кармака. Да и игра в которой его применили первой станет *DOOM*. В общем, тут можно сказать саму историю переписываю! А потому, сконцентрировавшись, начал накидывать основные принципы метода:

1. **Лучевая трассировка** - при каждом обновлении экрана будет высылаться множество «лучей», начиная с точки игрока и направленных в разные стороны. Эти лучи «натыкались» на стены, вычисляя расстояние до каждой из них.

2. **Ширина и высота стен** зависели от расстояния до них, создавая эффект перспективы.

3. **Свет и тени** – расстояние к стенам также влияло бы на их яркость, что добавляло бы глубину сцене.

Набросав общий план, открыл новый файл и начал писать код для этого подхода:

```c

void RenderRaycasting {

for (int x = 0; x screenWidth; x++) {

// Рассчитываем угол луча от игрока

float rayAngle = (player.angle - FOV / 2) + ((float)x / screenWidth) * FOV;

float distanceToWall = 0;

bool hitWall = false;

// Переменные для отслеживания попаданий луча

float eyeX = cos(rayAngle);

float eyeY = sin(rayAngle);

while (!hitWall distanceToWall renderDistance) {

distanceToWall += 0.1;

int testX = (int)(player.x + eyeX * distanceToWall);

int testY = (int)(player.y + eyeY * distanceToWall);

// Проверка столкновения луча с границей карты

if (testX 0 || testX = mapWidth || testY 0 || testY = mapHeight) {

hitWall = true;

distanceToWall = renderDistance; // Установка максимального расстояния

} else if (map[testY][testX] == WALL) {

hitWall = true;

}

}

// Расчёт высоты стены на экране

int ceiling = (screenHeight / 2) - (screenHeight / distanceToWall);

int floor = screenHeight - ceiling;

// Закрашивание столбца стены

for (int y = 0; y screenHeight; y++) {

if (y ceiling) {

DrawCeiling(x, y);

} else if (y floor) {

DrawFloor(x, y);

} else {

int shade = 255 - (distanceToWall * 20); // Чем дальше, тем темнее

SetPixelColor(x, y, RGB(shade, shade, shade));

}

}

}

}

```

Остановившись проглядел код, чувствуя тихое удовлетворение. Это был достаточно экономный подход для графики, не требовавшей оборудования доступного в будущем. Кстати об этом, после выпуска игры надо будет попробовать самому принять участие в будущей гонке ускорителей. Может всего и не съем, но чего-нибудь, да надкусаю! Правда, еще не тестировал, как движок поведет себя с большим количеством объектов, но и это уже был ощутимый прогресс. Запустив программу, наблюдать, как на экране проступили низкие серые стены, обрамленные «потолком» и «полом». Простая перспектива, создающая эффект коридора, была достигнута! Наложение света и тени добавляло глубины, делая картинку более выразительной. Почти то, что нужно! Да, наконец удовлетворённо вздохнул, слегка откинулся назад, снова сделал глоток уже остывающего чая и продолжил писать в блокнот идеи, которые планировал реализовать в будущем:

Поделиться:
Популярные книги

Барон диктует правила

Ренгач Евгений
4. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон диктует правила

Титан империи 8

Артемов Александр Александрович
8. Титан Империи
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Титан империи 8

Проводник

Кораблев Родион
2. Другая сторона
Фантастика:
боевая фантастика
рпг
7.41
рейтинг книги
Проводник

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Сердце Дракона. Том 9

Клеванский Кирилл Сергеевич
9. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.69
рейтинг книги
Сердце Дракона. Том 9

Сумеречный Стрелок 3

Карелин Сергей Витальевич
3. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 3

Убивать чтобы жить 4

Бор Жорж
4. УЧЖ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 4

Брак по принуждению

Кроу Лана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Брак по принуждению

Темный Лекарь 11

Токсик Саша
11. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 11

Папина дочка

Рам Янка
4. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Папина дочка

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая

Дурашка в столичной академии

Свободина Виктория
Фантастика:
фэнтези
7.80
рейтинг книги
Дурашка в столичной академии

Кротовский, вы сдурели

Парсиев Дмитрий
4. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
рпг
5.00
рейтинг книги
Кротовский, вы сдурели

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III