Как заставить компьютер реализовать 360 градусов = 0 градусов, вращая револьверную пушку - PullRequest
19 голосов
/ 26 июня 2009

Я делаю игру, и в ней есть орудийная башня с компьютерным управлением. Орудийная башня может вращаться на 360 градусов.

Он использует триггер, чтобы определить угол, который необходим для прицеливания пистолета (objdeg), и текущий угол наклона пистолета сохраняется в (gundeg)

следующий код вращает пистолет с заданной скоростью

if (objdeg > gundeg)
{
    gundeg++;
}
if (objdeg < gundeg)
{
    gundeg--;
}

Проблема в том, что если объект находится под углом 10 градусов, пистолет вращается, стреляет и уничтожает его, если другая цель появляется на 320 градусов, пистолет будет поворачиваться на 310 градусов против часовой стрелки, а не просто поворачиваться на 60 градусов по часовой стрелке, чтобы поразить его. .

Как я могу исправить свой код, чтобы он не работал глупо?

Ответы [ 14 ]

0 голосов
/ 21 января 2012

Вот пример короткого теста псевдокода, который, я думаю, решает проблему. Он работает в вашей области положительных углов 0..359 и обрабатывает граничные условия перед обработкой «нормальных».

if (objdeg >= 180 and gundeg < 180)
    gundeg = (gundeg + 359) % 360;
else if (objdeg < 180 and gundeg >= 180)
    gundeg = (gundeg + 1) % 360;
else if (objdeg > gundeg)
    gundeg = (gundeg + 1) % 360;
else if (objdeg < gundeg)
    gundeg = (gundeg + 359) % 360;
else
    shootitnow();
0 голосов
/ 04 декабря 2009

В случае риска велосипедного хранения, сохранение степеней как целое число, а не как его собственный класс может быть причиной "примитивной одержимости". Если я правильно помню, в книге «Прагматичный программист» предлагалось создать класс для хранения степеней и выполнения над ними операций.

0 голосов
/ 26 июня 2009

Вот как я недавно реализовал нечто подобное в игре:

double gundeg;

// ...

double normalizeAngle(double angle)
{
    while (angle >= 180.0)
    {
        angle -= 360.0;
    }
    while (angle < -180.0)
    {
       angle += 360.0;
    }
    return angle;
}

double aimAt(double objAngle)
{
    double difference = normalizeAngle(objdeg - gundeg);
    gundeg = normalizeAngle(gundeg + signum(difference));
}

Все угловые переменные ограничены -180 .. + 180, что облегчает такой расчет.

0 голосов
/ 26 июня 2009

Проблема в том, чтобы найти направление, которое даст кратчайшее расстояние.

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

С этой целью Киршштейн , кажется, думает, что рядом со мной.
Я работаю с целым числом в этом простом псевдокоде.

if (objdeg != gundeg)
{
    // we still need to move the gun
    delta = gundeg - objdeg
    if (delta > 0)
        if (unsigned(delta) > 180)
           gundeg++;
        else
           gundeg--;
    else // delta < 0
        if (unsigned(delta) > 180)
           gundeg--;        
        else
           gundeg++;

    if (gundeg == 360)
        gundeg = 0;
    else if (gundeg == -1)
        gundeg = 359;
}

Попробуйте работать с этим постепенно с gundeg = 10 и objdeg = 350, чтобы увидеть, как gundeg будет перемещен с 10 до 0, а затем с 359 до 350.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...