Hello all,

My current project is a top down shooter and I am trying to get wall to block the player's vision. I can do this with just a simple point to point check vs my walls, but I am trying to get it to black out the places where the player can not see. I am very close with the following code, but it has some glitches I am having trouble understanding why they are happening and how to prevent it.

Code:#include "Visibility.h" #include <allegro.h> #include <iostream> #include <winalleg.h> #include <vector> #include <algorithm> #include <string> #include <sstream> #include <math.h> #include "Line_Segment_2D.h" #include "Point_2D.h" bool sortByAngle(const Point_2D &lhs,const Point_2D &rhs){return lhs.Last_Angle < rhs.Last_Angle;} bool sortByDistance(const Line_Segment_2D *lhs, const Line_Segment_2D *rhs){return lhs->dist < rhs->dist;} bool PointIsVisible(Point_2D ori, Point_2D p, std::vector <Line_Segment_2D *> &w) { Line_Segment_2D t(ori,p); Point_2D intersect; for(unsigned int i = 0;i < w.size();i++) { if(p != w[i]->A && p != w[i]->B && ori != w[i]->A && ori != w[i]->B ) //if we don't belong to this line; basicly line should not interfere with itself or other walls that end at the same point. { if(t.Segments_Intersect(w[i],intersect))return false; } } return true; } Point_2D Find_Projection_Intersection(Point_2D Ori, Point_2D ver, std::vector <Line_Segment_2D *> W) { Point_2D intersect(0,0); Line_Segment_2D *Line_Of_Sight; Line_Of_Sight = new Line_Segment_2D(ver,Ori); Line_Of_Sight->Resize(3072); //need a big number here to extend to at least the outer bounding box. for(unsigned int i = 0;i < W.size();i++) { if(Line_Of_Sight->Segments_Intersect(W[i],intersect)) { //ok wall intersects with LOS! Lets make sure it isn't our origonal wall now or one that ends at the same spot. intersect.isProjection = true; intersect.Last_Angle = ver.Last_Angle; if(intersect != ver) { return intersect; } } } } Visibility::Visibility(int x, int y) { TESTING = false; size_x = x; size_y = y; VIS_MAP = create_bitmap(x,y); } BITMAP* Visibility::Get_Visibility(int max, int x,int y, std::vector <Line_Segment_2D *> &Walls) { Point_2D Ori(x,y); std::vector <Point_2D> Endpoints; rectfill(VIS_MAP,0,0,size_x,size_y,makecol(0,0,0)); //put fog of war up over everything! for(unsigned int i = 0;i < Walls.size();i++) //populate Endpoints from the walls in the nearby area. { Walls[i]->DistanceToPoint(Ori); Endpoints.push_back(Walls[i]->A); Ori.Angle_In_Degrees(Endpoints[i*2]); Endpoints.push_back(Walls[i]->B); Ori.Angle_In_Degrees(Endpoints[(i*2)+1]); } std::sort(Endpoints.begin(),Endpoints.end(),sortByAngle); //sort vertices by angle std::sort(Walls.begin(),Walls.end(),sortByDistance); //sort walls by distance std::vector <Point_2D> Final_Points; //container for vertices for(unsigned int i = 0; i < Endpoints.size();i++) { while(i+1 < Endpoints.size() && Endpoints[i] == Endpoints[i+1])Endpoints.erase(Endpoints.begin()+i); //only one of each vertex bool has_start = false; bool has_end = false; if(i==0 || i == Endpoints.size()-1){has_end = true;has_start = true;} for(unsigned int j = 0; j < Walls.size();j++) { if(Walls[j]->A == Endpoints[i] || Walls[j]->B == Endpoints[i]) { if(Walls[j]->Active == true) { Walls[j]->Active = false; has_end = true; }else { Walls[j]->Active = true; has_start = true; } } } if(PointIsVisible(Ori,Endpoints[i],Walls)) { if(has_end && has_start) //if a wall starts and ends here { Final_Points.push_back(Endpoints[i]); }else { if(has_end) //end has projection second { Final_Points.push_back(Endpoints[i]); Final_Points.push_back(Find_Projection_Intersection(Ori,Endpoints[i],Walls)); } else //start has projection first { Final_Points.push_back(Find_Projection_Intersection(Ori,Endpoints[i],Walls)); Final_Points.push_back(Endpoints[i]); } } } } for(unsigned int i = 0;i + 1 < Final_Points.size();i++) { triangle(VIS_MAP,Final_Points[i].x,Final_Points[i].y,Final_Points[i+1].x,Final_Points[i+1].y,Ori.x,Ori.y,makecol(255,0,255)); line(VIS_MAP,Final_Points[i+1].x,Final_Points[i+1].y,Final_Points[i].x,Final_Points[i].y,makecol(255,0,0)); circlefill(VIS_MAP,Final_Points[i].x,Final_Points[i].y,5,makecol(255,255,0)); } triangle(VIS_MAP,Final_Points[Final_Points.size() -1].x,Final_Points[Final_Points.size()-1].y,Final_Points[0].x,Final_Points[0].y,Ori.x,Ori.y,makecol(255,0,255)); return VIS_MAP; } Visibility::~Visibility() { destroy_bitmap(VIS_MAP); }