Вычисление, какие мозаики освещены в основанной на мозаике игре (“трассировка лучей”)

Причина в том, что идентификатор или строгий оператор (===), он сравнивается без преобразования типа, это означает, что если оба значения не имеют одинакового значения и одного и того же типа, они не будут считаться равными.

взгляните на эту ссылку, вы не можете сомневаться , чтобы понять, как работает оператор-идентификатор

43
задан Zarkonnen 7 October 2008 в 02:09
поделиться

9 ответов

У подобного жулику сообщества разработчиков есть определенная одержимость углом обзора, алгоритмами поля зрения.

Вот ссылка на подобную жулику статью Wiki о предмете: http://roguebasin.roguelikedevelopment.org/index.php?title=Field_of_Vision

Для моей подобной жулику игры, я реализовал алгоритм построения теней ( http://roguebasin.roguelikedevelopment.org/index.php?title=Shadow_casting ) в Python. Это было немного сложно для соединения, но работало обоснованно эффективно (даже в чистом Python) и генерировало хорошие результаты.

"Разрешающее Поле зрения", кажется, завоевывает популярность также: http://roguebasin.roguelikedevelopment.org/index.php?title=Permissive_Field_of_View

21
ответ дан Dana 23 September 2019 в 12:56
поделиться

Можно войти во все виды сложностей с вычислением поглощения газов и т.д., или можно пойти для простого метода грубой силы: Для каждой ячейки используйте алгоритм визуализации строки такой в качестве Алгоритм Строки Bresenham для исследования каждой ячейки между текущей и источником света. Если кто-либо - заполненные ячейки или (если у Вас есть только один источник света), ячейки, которые были уже протестированы и, как находили, были в тени, Ваша ячейка находится в тени. При обнаружении с ячейкой, которая, как известно, была освещена ячейка аналогично будет освещена. Легкая оптимизация к этому должна установить состояние любых ячеек, с которыми Вы встречаетесь вдоль строки к тому, что конечный результат.

Это более или менее, что я использовал в моем 2004 IOCCC завоевание записи . Очевидно, это не делает хороший пример кода, все же.;)

Редактирование: Как loren указывает с этими оптимизациями, только необходимо выбрать пиксели вдоль края карты для трассировки от.

16
ответ дан Nick Johnson 23 September 2019 в 12:56
поделиться

Алгоритмы, представляемые здесь, кажется, мне делают больше вычислений, чем я думаю, необходимы. Я не протестировал это, но я думаю, что это работало бы:

Первоначально, отметьте все пиксели, как освещенный.

Для каждого пикселя на краю карты: Как предложенное Паукообразное насекомое, используйте Bresenham для трассировки строки от пикселя до света. Если та строка ударяет, что преграда тогда отмечает все пиксели от края до только вне преграды, как являющейся в тени.

6
ответ дан Loren Pechtel 23 September 2019 в 12:56
поделиться

Быстрый и грязный:

(В зависимости от того, насколько большой массив)

  • Цикл через каждую мозаику
  • чертит линию к Световому сигналу
  • , Если какое-либо парирование строки поражает X, то это находится в тени
  • (дополнительно): вычислите сумму X, строка проходит, и действительно представьте себе математику к determint пропорция мозаики в тени. NB: Это могло быть сделано путем сглаживания строки между мозаикой и Светом (поэтому рассмотрение других мозаик вдоль маршрута назад к источнику света) во время процедуры пороговой обработки, они появятся как маленький anomolies. В зависимости от логики использовал Вас, мог потенциально определить, насколько (если вообще) мозаика находится в тени.

Вы могли также отслеживать, которых пиксели были протестированы, поэтому оптимизируют решение немного и не повторно тестируют пиксели дважды.

Это могло быть куполом вполне прилично при помощи обработки изображения и проводящий прямые линии между эльфами (мозаики), Если строки полу прозрачный, и эти X блоков являются полупрозрачными снова. Вы можете порог изображение, чтобы определить, пересеклась ли строка 'X'

, Если у Вас есть опция использовать сторонний инструмент, затем идентификатор, вероятно, берет его. В конечном счете это могло бы оказаться более быстрым, но Вы поймете меньше о Вашей игре.

5
ответ дан TK. 23 September 2019 в 12:56
поделиться

Это только для забавы:

можно копировать Гибель 3 подхода в 2D, если Вы сначала делаете шаг для преобразования мозаик в строки. Например,

- - - - -
- X X X -
- X X - -
- X - - -
- - - - L

... был бы уменьшен в три строки, соединяющие углы твердого объекта в треугольнике.

Затем сделайте то, что Гибель делают 3 механизма: С точки зрения источника света рассмотрите каждую "стену", которая стоит перед светом. (В этой сцене только рассмотрели бы диагональную строку.) Для каждой такой строки, спроектируйте его в трапецоид, передний фронт которого является исходной строкой, стороны которой лежат на строках от источника света до каждой конечной точки, и чей назад далеко, мимо целой сцены. Так, это - трапецоид, который "указывает на" свет. Именно все пространство стена набирает свою тень. Заполните каждую мозаику в этом трапецоиде с темнотой.

Продолжаются через все такие строки, и Вы закончите с "шаблоном", который включает все мозаики, видимые от источника света. Заполните эти мозаики светлым цветом. Можно хотеть осветить мозаику немного меньше, поскольку Вы убегаете от источника ("затухание") или делаете другой необычный материал.

Повторение для каждого источника света в Вашей сцене.

4
ответ дан Kevin Conner 23 September 2019 в 12:56
поделиться

Чтобы проверить, находится ли мозаика в тени, необходимо отодвинуть прямую линию к источнику света. Если строка пересекает другую мозаику, это занято, то мозаика, которую Вы тестировали, находится в тени. Алгоритмы трассировки лучей делают это для каждого объекта (в Вашей мозаике случая) в представлении.

статья Raytracing о Википедии имеет псевдокод.

3
ответ дан Bill the Lizard 23 September 2019 в 12:56
поделиться

Решением TK является то, которое Вы обычно использовали бы для этого вида вещи.

Для частичного сценария освещения, у Вас мог быть он так, чтобы, если мозаика приводит к тому, чтобы быть в тени, та мозаика была тогда разделена на 4 мозаики, и каждый из тех тестируется. Вы могли тогда разделить это так, как Вы хотели?

Редактирование:

можно также оптимизировать его немного, не тестируя ни одной из мозаик, смежных со светом - это было бы более важно сделать, когда у Вас есть несколько источников света, я предполагаю...

2
ответ дан Carl 23 September 2019 в 12:56
поделиться

Я имею на самом деле просто, недавно записал эту функциональность в один из моих проектов.

void Battle::CheckSensorRange(Unit* unit,bool fog){
    int sensorRange = 0;
    for(int i=0; i < unit->GetSensorSlots(); i++){
        if(unit->GetSensorSlot(i)->GetSlotEmpty() == false){
            sensorRange += unit->GetSensorSlot(i)->GetSensor()->GetRange()+1;
        }
    }
    int originX = unit->GetUnitX();
    int originY = unit->GetUnitY();

    float lineLength;
    vector <Place> maxCircle;

    //get a circle around the unit
    for(int i = originX - sensorRange; i < originX + sensorRange; i++){
        if(i < 0){
            continue;
        }
        for(int j = originY - sensorRange; j < originY + sensorRange; j++){
            if(j < 0){
                continue;
            }
            lineLength = sqrt( (float)((originX - i)*(originX - i)) + (float)((originY - j)*(originY - j)));
            if(lineLength < (float)sensorRange){
                Place tmp;
                tmp.x = i;
                tmp.y = j;
                maxCircle.push_back(tmp);
            }
        }
    }

    //if we're supposed to fog everything we don't have to do any fancy calculations
    if(fog){
        for(int circleI = 0; circleI < (int) maxCircle.size(); circleI++){
            Map->GetGrid(maxCircle[circleI].x,maxCircle[circleI].y)->SetFog(fog);
        }
    }else{

        bool LOSCheck = true;
        vector <bool> placeCheck;

        //have to check all of the tiles to begin with 
        for(int circleI = 0; circleI < (int) maxCircle.size(); circleI++){
            placeCheck.push_back(true);
        }

        //for all tiles in the circle, check LOS
        for(int circleI = 0; circleI < (int) maxCircle.size(); circleI++){
            vector<Place> lineTiles;
            lineTiles = line(originX, originY, maxCircle[circleI].x, maxCircle[circleI].y);

            //check each tile in the line for LOS
            for(int lineI = 0; lineI < (int) lineTiles.size(); lineI++){
                if(false == CheckPlaceLOS(lineTiles[lineI], unit)){
                    LOSCheck = false;

                    //mark this tile not to be checked again
                    placeCheck[circleI] = false;
                }
                if(false == LOSCheck){
                    break;
                }
            }

            if(LOSCheck){
                Map->GetGrid(maxCircle[circleI].x,maxCircle[circleI].y)->SetFog(fog);
            }else{
                LOSCheck = true;
            }
        }
    }

}

существует некоторый дополнительный материал там, что Вам не было бы нужно при адаптации его к собственному использованию. Место типа просто определяется как положение X и Y для пользы удобств.

функция строки взята из Википедии с очень маленькими модификациями. Вместо того, чтобы распечатать x y координирует, я изменил его для возврата вектора места со всеми точками в строке. Функция CheckPlaceLOS просто возвращает TRUE или FALSE на основе того, если мозаика имеет объект на нем. Существует еще некоторая оптимизация, которая могла быть сделана с этим, но это хорошо для моих потребностей.

2
ответ дан DShook 23 September 2019 в 12:56
поделиться

Если Вы не хотите проводить время к reinvent/re-implement это, существует много игровых механизмов там. Ogre3D является игровым механизмом с открытым исходным кодом, который полностью поддерживает освещение, а также звуковые и пульты управления игрой.

0
ответ дан Scottie T 23 September 2019 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: