First of all, I am working on a 2D strategy using the XNA infrastructure.
I use 2D fog of war for my game. The graphic part has already been completed and works pretty well, but now I'm trying to implement the "logical" part of this fog of war.
I created a 2D grid representing my level. Each frame, each block updates the cells in a circle around it, using the Breshenem algorithm (which seems to be the best way to find out which cells are in a given circle). It really works ... When I want to know if a given position is visible or not, I just need to get the state of the cell ...
The problem is that when I have a large number of units generated, my game runs so slowly ... The first reason for this performance problem is that since each block updates the cells around it, many cells are updated several times ... But I do not see any solution for this ...
So ... Perhaps I was mistaken in implementing it this way, or maybe I lack the obvious optimization, but I was kind of stuck ...
Here is the code:
class LevelGridCell { public void SetVisible(float a_time) { if (m_visibleTime < a_time) m_visibleTime = a_time; } public bool IsVisible(float a_time) { return (m_visibleTime != 0f && m_visibleTime >= a_time); } float m_visibleTime = 0; } class LevelGrid { public LevelGridCell GetAt(int a_x, int a_y) { return m_grid[a_x + a_y * m_width]; } public void SetVisible(float a_time, int a_x, int a_y, float a_radius) { GetAt(a_x, a_y).SetVisible(a_time); int intRadius = (int)(a_radius / m_cellSize); int x = 0, y = intRadius, p = 1 - intRadius; PlotSetVisible(a_x, a_y, x, y, a_time); while (x < y) { x++; if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x - y) + 1; } PlotSetVisible(a_x, a_y, x, y, a_time); } } private void SafeSetVisible(int a_x, int a_y, float a_time) { if (a_x >= 0 && a_x < m_width && a_y >= 0 && a_y < m_height) { GetAt(a_x, a_y).SetVisible(a_time); } } private void PlotSetVisible(int xctr, int yctr, int x, int y, float a_time) { for (int i = xctr - x; i <= xctr + x; ++i) { SafeSetVisible(i, yctr + y, a_time); SafeSetVisible(i, yctr - y, a_time); } for (int i = xctr - y; i <= xctr + y; ++i) { SafeSetVisible(i, yctr + x, a_time); SafeSetVisible(i, yctr - x, a_time); } } List<LevelGridCell> m_grid = new List<LevelGridCell>(); float m_cellSize; int m_width; int m_height; }