Thread: 2D vision engine

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    2D vision engine

    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);
    }

  2. #2
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Ok well I didn't see the edit button.... Just uploaded a video to youtube showing the problems I am facing. https://www.youtube.com/watch?v=SeKz...ature=youtu.be

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I do not understand what you are trying to do. The video does not help much.

  4. #4
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Quote Originally Posted by VirtualAce View Post
    I do not understand what you are trying to do. The video does not help much.
    I had given up on this site and posted on dreamincode.net ... What was happening is that there are some issues where the vertices get out of order(best description I can give) which makes the triangles draw through walls.

    That thread can be found here:
    Raycasting Visibility In 2D Game - C And C++ | Dream.In.Code

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help me in computer vision
    By howard in forum General AI Programming
    Replies: 1
    Last Post: 04-23-2009, 05:02 AM
  2. Problems with vision cone
    By Waterbottle in forum Game Programming
    Replies: 1
    Last Post: 07-02-2008, 01:24 PM
  3. Time to get those night-vision contacts
    By hk_mp5kpdw in forum A Brief History of Cprogramming.com
    Replies: 14
    Last Post: 01-22-2004, 05:53 PM
  4. Vision Prescription
    By FillYourBrain in forum A Brief History of Cprogramming.com
    Replies: 21
    Last Post: 08-08-2003, 10:27 PM
  5. a horrible vision of the future
    By iain in forum A Brief History of Cprogramming.com
    Replies: 7
    Last Post: 12-27-2001, 09:03 AM

Tags for this Thread