6
\$\begingroup\$

I have a problem with a game i am programming. I am making some sort of security game and i would like to have some visual line of sight. The problem is that i can't restrict my line of sight so my cops can't see through the walls. Below you find the design, in which they can look through windows, but not walls. Further below you find an illustration of what my problem is exactly.

design

this is what it looks like now. As you can see, the cops can see through walls.

enter image description here

This is the map i would want to use to restrict the line of sight.

visual map

So the way i am programming the line of sight now is just by calculating some points and drawing the sight accordingly, as shown below. Note that i also check for a hittest using bitmapdata to check whether or not my player has been spotted by any of the cops.

private function setSight(e:Event=null):Boolean
{
    g = copCanvas.graphics;
    g.clear();

    for each(var cop:Cop in copCanvas.getChildren())
    {
        var _angle:Number = cop.angle;
        var _radians:Number = (_angle * Math.PI) / 180;
        var _radius:Number = 50;

        var _x1:Number = cop.x + (cop.width/2);
        var _y1:Number = cop.y + (cop.height/2);
        var _baseX:Number = _x1 + (Math.cos(_radians) * _radius);
        var _baseY:Number = _y1 - (Math.sin(_radians) * _radius);

        var _x2:Number = _baseX + (25 * Math.sin(_radians));
        var _y2:Number = _baseY + (25 * Math.cos(_radians));
        var _x3:Number = _baseX - (25 * Math.sin(_radians));
        var _y3:Number = _baseY - (25 * Math.cos(_radians));

        g.beginFill(0xff0000, 0.3);
        g.moveTo(_x1, _y1);
        g.lineTo(_x2, _y2);
        g.lineTo(_x3, _y3);
        g.endFill();
    }

    var _cops:BitmapData = new BitmapData(width, height, true, 0);
    _cops.draw(copCanvas);

    var _bmpd:BitmapData = new BitmapData(10, 10, true, 0);
    _bmpd.draw(me);

    if(_cops.hitTest(new Point(0, 0), 10, _bmpd, new Point(me.x, me.y), 255))
    {
        gameover.alpha = 1;
        setTimeout(function():void{ gameover.alpha = 0; }, 5000);
        stop();

        return true;
    }

    return false;
}

So now my question is: Is there someone who knows how to restrict the view so that the cops can't look through the walls? Thanks a lot in advance.

ps: i have already looked at this tutorial by emanuele feronato, but i can't use the code to restric the visual line of sight.

\$\endgroup\$
4
  • \$\begingroup\$ Do you just want to make sure the player cannot be seen when behind a wall, or do you want to dynamically change the cops field of vision? Eg. painting their actual field of vision, obstructed by walls instead of a red triangle? \$\endgroup\$
    – bummzack
    Jun 22, 2011 at 10:07
  • \$\begingroup\$ I want to really paint their actual field of vision (so dynamically change it so it can be obstructed by walls instead of always being a traingle). But if it isn't possible, i'll drop the line of sight and use the method you suggested below. \$\endgroup\$ Jun 22, 2011 at 10:19
  • \$\begingroup\$ this is a pretty nice illustration of what i want to do: computer-turret.deviantart.com/art/AS3-Line-Of-Sight-153344844 \$\endgroup\$ Jun 22, 2011 at 11:07
  • \$\begingroup\$ I updated my answer, see below. \$\endgroup\$
    – bummzack
    Jun 22, 2011 at 11:36

1 Answer 1

10
\$\begingroup\$

Since you already check if the player is inside the viewing-area of a cop, you can follow this up by a line-of-sight check.

It seems like you use a bitmap-based approach for your entire world. Therefore I suggest you do the following:

  • Check if player is inside a viewing-area of a cop
  • If yes, use the Bresenham line algorithm to sample pixels of the walls map from the cops position to the players position. If you hit a black pixel, the view is obstructed by a wall.

While this is not really accurate (your player can hide behind a small object, if the line from cop to player goes through that object), it will be really fast and should be accurate enough for your game.

Update: To improve this a little bit, you could do two line-of-sight tests, from the cops position to the leftmost point of the player and to the rightmost point, as shown in the following image:

line of sight example


Edit

It seems like you want to dynamically paint the actual viewing-area of each cop instead of just a triangle. A way to do that would be to look into 2D shadowing. I once did a quick flash experiment with 2D shadows based on a bitmap image. I integrated your wall map into my code. Here's the interactive result, and here's the source-code which you're free to use as a starting point for your own implementation.

2d shadowing example

In the top left, you'll see the composed image, on the top right there's the original map image. Bottom left shows the calculated light pixels and on the bottom right you'll find the distance-map that was used. You can drag the light with the mouse and increase/decrease the light radius using the arrow keys (left/right). Instead of rendering a circle, you would only render your triangle as active "light".

To make the calculation of every single pixel inside the light radius reasonably fast, I use a distance map that is being used to look up how much distance can be traveled from any given pixel without hitting an obstacle. The distance map is calculated at initialization time, therefore the flash file takes a while to initialize (because calculation of the distance-map is quite CPU heavy). To avoid this, you could also pre-calculate your distance-maps and store them as individual files.

Please note that a distance-map won't work with moving obstacles though.

\$\endgroup\$
4
  • \$\begingroup\$ this will surely help me get the result i need! thanks a lot! ^^ \$\endgroup\$ Jun 22, 2011 at 11:44
  • \$\begingroup\$ And thanks for letting me use your code, it will be very helpful! \$\endgroup\$ Jun 22, 2011 at 11:50
  • \$\begingroup\$ You're welcome. I guess the code lacks a bit of documentation but you should be able to figure out what's going on :) \$\endgroup\$
    – bummzack
    Jun 22, 2011 at 11:56
  • \$\begingroup\$ +1 For being caring and sharing, and other things ending in 'ing'. :D \$\endgroup\$ Jun 22, 2011 at 12:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .