Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question
    
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? –  bummzack Jun 22 '11 at 10:07
    
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. –  Michiel Standaert Jun 22 '11 at 10:19
    
this is a pretty nice illustration of what i want to do: computer-turret.deviantart.com/art/AS3-Line-Of-Sight-153344844 –  Michiel Standaert Jun 22 '11 at 11:07
    
I updated my answer, see below. –  bummzack Jun 22 '11 at 11:36
add comment

1 Answer 1

up vote 10 down vote accepted

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.

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.