}
```
Теперь каждый раз при запуске игры бот начинал следовать за игроком, словно его кто-то преследовал по пустым коридорам. Даже представил, что этот противник будет бормотать и издавать звуки – что-то зловещее, чтобы добавить немного напряжения. Однако, звуковая система для будущего была планом максимум, поэтому на время отложил эту задачу.
Идеи текли одна за другой, но с каждой новой функцией ему становилось сложнее поддерживать высокую производительность программы. Мощностей местных компьютеров, а тем более моего ноутбука, для всего задуманного было бы мало, и пришлось обдумывать, как сжать графику и текстуры, чтобы втиснуть всё в лимиты памяти. Периодически экран затухал, процессор перегружался, и часть моих кодовых идей требовала упрощения. Но это меня не останавливало. Какое там, когда чувствовал такой азарт, словно каждый новый шаг приносил меня ближе к созданию по-настоящему революционного проекта!
Пару дней в мастерской, пару ночей за кодом – и вот, наконец, выдался момент, чтобы отдохнуть. Нашёл тихое кафе неподалёку, заказал крепкий чай и свежую булочку, уселся у окна. Открытый ноутбук, хоть и грелся заметно, стойко справлялся с нагрузкой. Сосредоточиться на разработке для "прототипа Дум" в этих условиях было удивительно удобно: пульсирующий шум улицы за окном и гул разговоров вокруг погружали меня в состояние, где мысли шли яснее.
Я понимал: на настоящие 3D-ускорители здесь надеяться не приходится, потому главный вызов был в том, чтобы создать иллюзию трёхмерного пространства с тем, что имелось – в сущности, с теми же вычислительными мощностями, что и в середине восьмидесятых. Запустил компилятор, снова вернулся к коду. Словно бы мелькнуло нечто – магия простых вычислений, которые, при правильном использовании, творят чудеса.
```c
// Код для базовой структуры трассировки лучей
int rayCasting(float playerX, float playerY, float playerAngle) {
for (int x = 0; x screenWidth; x++) {
// Преобразуем угол для каждого пикселя на экране
float rayAngle = (playerAngle - fov / 2.0) + (x / (float)screenWidth) * fov;
float distanceToWall = 0;
// Проверяем пересечение с стенами
float eyeX = cos(rayAngle); // единичный вектор по оси X
float eyeY = sin(rayAngle); // единичный вектор по оси Y
while (!hitWall distanceToWall maxDepth) {
distanceToWall += stepSize;
int testX = (int)(playerX + eyeX * distanceToWall);
int testY = (int)(playerY + eyeY * distanceToWall);
// Проверка выхода за пределы карты
if (testX 0 || testX = mapWidth || testY 0 || testY = mapHeight) {
hitWall = true; // если за пределами — считаем, что есть "стена"
distanceToWall = maxDepth;