Причина в том, что идентификатор или строгий оператор (===), он сравнивается без преобразования типа, это означает, что если оба значения не имеют одинакового значения и одного и того же типа, они не будут считаться равными.
взгляните на эту ссылку, вы не можете сомневаться , чтобы понять, как работает оператор-идентификатор
У подобного жулику сообщества разработчиков есть определенная одержимость углом обзора, алгоритмами поля зрения.
Вот ссылка на подобную жулику статью 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
Можно войти во все виды сложностей с вычислением поглощения газов и т.д., или можно пойти для простого метода грубой силы: Для каждой ячейки используйте алгоритм визуализации строки такой в качестве Алгоритм Строки Bresenham для исследования каждой ячейки между текущей и источником света. Если кто-либо - заполненные ячейки или (если у Вас есть только один источник света), ячейки, которые были уже протестированы и, как находили, были в тени, Ваша ячейка находится в тени. При обнаружении с ячейкой, которая, как известно, была освещена ячейка аналогично будет освещена. Легкая оптимизация к этому должна установить состояние любых ячеек, с которыми Вы встречаетесь вдоль строки к тому, что конечный результат.
Это более или менее, что я использовал в моем 2004 IOCCC завоевание записи . Очевидно, это не делает хороший пример кода, все же.;)
Редактирование: Как loren указывает с этими оптимизациями, только необходимо выбрать пиксели вдоль края карты для трассировки от.
Алгоритмы, представляемые здесь, кажется, мне делают больше вычислений, чем я думаю, необходимы. Я не протестировал это, но я думаю, что это работало бы:
Первоначально, отметьте все пиксели, как освещенный.
Для каждого пикселя на краю карты: Как предложенное Паукообразное насекомое, используйте Bresenham для трассировки строки от пикселя до света. Если та строка ударяет, что преграда тогда отмечает все пиксели от края до только вне преграды, как являющейся в тени.
Быстрый и грязный:
(В зависимости от того, насколько большой массив)
Вы могли также отслеживать, которых пиксели были протестированы, поэтому оптимизируют решение немного и не повторно тестируют пиксели дважды.
Это могло быть куполом вполне прилично при помощи обработки изображения и проводящий прямые линии между эльфами (мозаики), Если строки полу прозрачный, и эти X блоков являются полупрозрачными снова. Вы можете порог изображение, чтобы определить, пересеклась ли строка 'X'
, Если у Вас есть опция использовать сторонний инструмент, затем идентификатор, вероятно, берет его. В конечном счете это могло бы оказаться более быстрым, но Вы поймете меньше о Вашей игре.
Это только для забавы:
можно копировать Гибель 3 подхода в 2D, если Вы сначала делаете шаг для преобразования мозаик в строки. Например,
- - - - -
- X X X -
- X X - -
- X - - -
- - - - L
... был бы уменьшен в три строки, соединяющие углы твердого объекта в треугольнике.
Затем сделайте то, что Гибель делают 3 механизма: С точки зрения источника света рассмотрите каждую "стену", которая стоит перед светом. (В этой сцене только рассмотрели бы диагональную строку.) Для каждой такой строки, спроектируйте его в трапецоид, передний фронт которого является исходной строкой, стороны которой лежат на строках от источника света до каждой конечной точки, и чей назад далеко, мимо целой сцены. Так, это - трапецоид, который "указывает на" свет. Именно все пространство стена набирает свою тень. Заполните каждую мозаику в этом трапецоиде с темнотой.
Продолжаются через все такие строки, и Вы закончите с "шаблоном", который включает все мозаики, видимые от источника света. Заполните эти мозаики светлым цветом. Можно хотеть осветить мозаику немного меньше, поскольку Вы убегаете от источника ("затухание") или делаете другой необычный материал.
Повторение для каждого источника света в Вашей сцене.
Чтобы проверить, находится ли мозаика в тени, необходимо отодвинуть прямую линию к источнику света. Если строка пересекает другую мозаику, это занято, то мозаика, которую Вы тестировали, находится в тени. Алгоритмы трассировки лучей делают это для каждого объекта (в Вашей мозаике случая) в представлении.
Решением TK является то, которое Вы обычно использовали бы для этого вида вещи.
Для частичного сценария освещения, у Вас мог быть он так, чтобы, если мозаика приводит к тому, чтобы быть в тени, та мозаика была тогда разделена на 4 мозаики, и каждый из тех тестируется. Вы могли тогда разделить это так, как Вы хотели?
Редактирование:
можно также оптимизировать его немного, не тестируя ни одной из мозаик, смежных со светом - это было бы более важно сделать, когда у Вас есть несколько источников света, я предполагаю...
Я имею на самом деле просто, недавно записал эту функциональность в один из моих проектов.
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 на основе того, если мозаика имеет объект на нем. Существует еще некоторая оптимизация, которая могла быть сделана с этим, но это хорошо для моих потребностей.
Если Вы не хотите проводить время к reinvent/re-implement это, существует много игровых механизмов там. Ogre3D является игровым механизмом с открытым исходным кодом, который полностью поддерживает освещение, а также звуковые и пульты управления игрой.