Рыбий глаз в псевдо-3д движке

Есть код:

x = 3
y = 5
d = 0 // Угол

fn cast($x, $y, $d) // Функция луча
{
    $i = 0 // Расстояние, увеличивается каждый шаг луча
    while $i < 200
    {
        if $x >= get_xsize(world) || $x < 0 || $y >= get_ysize(world) || $y < 0
    {
        ret(200) // Вернуть 200 (максимальное расстояние)
    }
    
    if world[floor($x), floor($y)] // Массив, в котором хранятся стены
    {
        ret($i)
    }
    
    $x + cos($d) / 30
    $y + sin($d) / 30
    $i + 1
}
ret(200)
}

fn rend() // Функция отрисовки, вызывается каждый кадр
{
    $i = -250
    $j = -3.14 / 3
    while $i <= 250
    {
        $ray = cast(x, y, d + $j)
        $b = rgb2hex(0, 255 - $ray, 0) // Функция, которая возвращает цвет
    if $ray != 200
    {
        line($i, $ray - 200, $i, 200 - $ray, $b)
    }
    $i + 1
    $j + 0.0041887902
    }
}

Пояснение (особенности языка):

  • $i - локальная переменная
  • line(x0, y0, x1, y1, color) - отрисовка линии
  • Система координат с (0, 0) в центре, 512 на 512 пикселей
  • fn - объявление функции
  • ret() - аналог return.
  • $i + 1 - инкремент

Но при отрисовке появляется эффект рыбьего глаза. Как от него избавиться?

если смотреть на ровную стенку

если смотреть вдоль стенки


Ответы (1 шт):

Автор решения: Discord
  1. Умножить длину луча на косинус угла $j $ray = cast(x, y, d + $j) * cos($j)
  2. Изменить способ рендера line($i, -$ray / 2000, $i, 2000 / $ray, $b)
  3. Уменьшить расстояние, которое проходит луч за один шаг $x + cos($d) / 30 $y + sin($d) / 30 $i + 1
→ Ссылка