Roguelike FOV проблема - PullRequest
       23

Roguelike FOV проблема

3 голосов
/ 03 марта 2011

Я работаю над проектом compsci для колледжа, и мне нужна помощь с алгоритмом поля зрения.Я в основном работаю, но в некоторых ситуациях алгоритм видит сквозь стены и стены, освещенные светом, которые игрок не должен видеть.

void cMap::los(int x0, int y0, int radius)
{ //Does line of sight from any particular tile

for(int x = 0; x < m_Height; x++) {
    for(int y = 0; y < m_Width; y++) {
        getTile(x,y)->setVisible(false);
    }
}

double  xdif = 0;
double  ydif = 0;
bool    visible = false;
float   dist = 0;

for (int x = MAX(x0 - radius,0); x < MIN(x0 + radius, m_Height); x++) {      //Loops through x values within view radius
    for (int y = MAX(y0 - radius,0); y < MIN(y0 + radius, m_Width); y++) {         //Loops through y values within view radius

        xdif = pow( (double) x - x0, 2);
        ydif = pow( (double) y - y0, 2);

        dist = (float) sqrt(xdif + ydif); //Gets the distance between the two points

        if (dist <= radius) {               //If the tile is within view distance,
            visible = line(x0, y0, x, y);       //check if it can be seen.

            if (visible) {                          //If it can be seen,
                getTile(x,y)->setVisible(true);        //Mark that tile as viewable
            }
        }
    }   
}
}

bool cMap::line(int x0,int y0,int x1,int y1)
{
bool steep = abs(y1-y0) > abs(x1-x0);

if (steep) {
    swap(x0, y0);
    swap(x1, y1);
}

if (x0 > x1) {
    swap(x0,x1);
    swap(y0,y1);
}

  int deltax = x1-x0;
  int deltay = abs(y1-y0);
  int error = deltax/2;
  int ystep;
  int y = y0;

  if (y0 < y1)
     ystep = 1;
  else
     ystep = -1;

  for (int x = x0; x < x1; x++) {

      if ( steep && getTile(y,x)->isBlocked()) {
          getTile(y,x)->setVisible(true);
          getTile(y,x)->setDiscovered(true);
        return false;
      } else if (!steep && getTile(x,y)->isBlocked()) {
          getTile(x,y)->setVisible(true);
          getTile(x,y)->setDiscovered(true);
        return false;
      }

     error -= deltay;

     if (error < 0) {
        y = y + ystep;
        error = error + deltax;
     }

  }

  return true;
}

Если кто-нибудь может помочь мне сделать первые заблокированные плитки видимыми, но остановит остальные,Я был бы признателен.

спасибо, Manderin87

1 Ответ

2 голосов
/ 03 марта 2011

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

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

while (current_cell != destination) {
    current_cell.visible = true;
    if (current_cell.opaque) break;
    else current_cell = current_cell.next();
}

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

Некоторые полезныересурсы:

...