# Point-to-Point Line-of-Site

**URL:** <https://forum.kirupa.com/t/point-to-point-line-of-site/165548>\
**Category:** open source\
**Created:** [October 11, 2005, 11:33pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548 "2005-10-11T23:33:01Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![icio](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/icio/32/484_2.png) [@icio](https://forum.kirupa.com/u/icio)\
**Post date:** [October 11, 2005, 11:33pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/1 "2005-10-11T23:33:01Z")

</div>

Point-to-Point Line-of-Sight\* [size=1]Oops[/size]  
Man that sounds so cool.

**edit:**  
Since this original post I have learnt of the world of Raycasting. You can see my attempts of it in this post:

> **[Point-to-Point Line-of-Site - Page 3](https://www.kirupa.com/forum/showthread.php?p=1746388)**
>
> Got a web design/development question or just want to hang out with the most awesome people on the planet? Drop on in!

Here’s the script. I have used Flash 8’s BitmapData and Rectangle classes, but the theory could easily be applied to another tile-based world without any of these, these classes were simply used to display everything.

Use the Arrow keys to move the character, and the character aims to the mouse position.

**[http://icio.co.uk/random/files/flash/sight.swf](http://icio.co.uk/random/files/flash/sight.swf)**

```auto
import flash.display.BitmapData;
import flash.geom.Rectangle;

Stage.scaleMode = "noScale";
Mouse.hide();

// *********************************************************
// Variables
var tileSize:Number = 10;
var map:Array = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1], [1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]; // This is an awesomely-long line, y0. (762 characters before comment)
var baseBitmap:BitmapData = new BitmapData(map[0].length*tileSize, map.length*tileSize, false, 0xEEEEEE);	_root.attachBitmap(baseBitmap, _root.getNextHighestDepth());	// \
var objBitmap:BitmapData = new BitmapData(baseBitmap.width, baseBitmap.height, true, 0x00000000); _root.attachBitmap(objBitmap, _root.getNextHighestDepth()); // |- The bitmaps used in the game
var hitBitmap:BitmapData = new BitmapData(baseBitmap.width, baseBitmap.height, true, 0x0000FF00); _root.attachBitmap(hitBitmap, _root.getNextHighestDepth()); // /
var tileRectangle:Rectangle = new Rectangle(0, 0, tileSize, tileSize); // A Rectangle object for drawing tiles onto the base bitmap.
var objects:Array = []; // An array of all the objects
var player:Object = {y:10*tileSize, x:1*tileSize, color:0xFFFF3399, xspd:0, yspd:0}; objects.push(player);	// The player object

for (y=0; y<map.length; y++) { for (x=0; x<map[0].length; x++) { if (map[y][x] == 1) {	// Cycle through the numbers in the map and process, then
	tileRectangle.x = x*tileSize; tileRectangle.y = y*tileSize; // Reposition the tile rectangle
	baseBitmap.fillRect(tileRectangle, 0x999999); // Draw it onto the base bitmap
} } }

// Draw the objects onto the object bitmap
function drawObjects() { objBitmap.fillRect(objBitmap.rectangle, 0x00000000); for (i in objects) { objBitmap.fillRect(new Rectangle(objects*.x, objects*.y, tileSize, tileSize), objects*.color); } objBitmap.fillRect(new Rectangle(_xmouse-1, _ymouse-1, 3, 3), 0xFFFF0000); }
	
// ****************************************************************************************
// THE IMPORTANT FUNCTION - THIS IS WHAT IT'S ALL ABOUT !! *******************************
// ****************************************************************************************
function lineOfSite(x1:Number, y1:Number, x2:Number, y2:Number) {
	var dist:Number = Math.sqrt(Math.pow(x2-x1, 2)+Math.pow(y2-y1, 2)); // The distance from the start point to end point
	var angle:Number = Math.atan((y2-y1)/(x2-x1)); // The angle from start point to end point (in radians)
		angle += x2-x1<0 ? Math.PI : 0; // angle correction
		angle += x2-x1>=0 && y2-y1<0 ? 2*Math.PI : 0; // angle correction
		hitBitmap.fillRect(hitBitmap.rectangle, 0x0000FF00); // (Eye-Candy)

	var pos:Number = 0; // Where we're going to start from on the line
	while (pos < dist) { // Loop until we've tested further than, or to the same distance as, the total distance
		pos = pos+1<=dist ? pos+1 : dist; // Move onto the test position. (Increasing/Decreasing '1' increases/decreases accuracy)
		var x:Number = Math.floor(pos*Math.cos(angle)+x1); // Calculate the new x-coordinate for testing
		var y:Number = Math.floor(pos*Math.sin(angle)+y1); // Calculate the new y-coordinate for testing
		if (map[Math.floor(y/tileSize)][Math.floor(x/tileSize)] == 1) { // Check to see if the current point's relative tile is '1' or '0'
			break; // Exit the loop if the tile is a '1'. Upon exitting, `x` and `y` maintain the coordinates
		}
			hitBitmap.setPixel32(x, y, 0xFF666666); // (Eye-Candy)
	}
		hitBitmap.fillRect(new Rectangle((pos==dist?x2: x)-1, (pos==dist?y2:y)-1, 3, 3), pos==dist?0xFF0000FF:0xFF000000); // (Eye-Candy)
	return pos==dist; // Will return true if the target was reachable and false otherwise.
}
// ****************************************************************************************

// *********************************************************
// Player Movement - Can't be assed commenting all of this.
function movePlayer() {
	player.xspd += Key.isDown(Key.RIGHT)?1: (Key.isDown(Key.LEFT)?-1:0); player.xspd = Math.abs(player.xspd)>tileSize?tileSize*player.xspd/Math.abs(player.xspd):player.xspd;
	player.yspd += Key.isDown(Key.DOWN)?1: (Key.isDown(Key.UP)?-1:0); player.yspd = Math.abs(player.yspd)>tileSize?tileSize*player.yspd/Math.abs(player.yspd):player.yspd;
	if (!Key.isDown(Key.RIGHT) && !Key.isDown(Key.LEFT)) { player.xspd *= Math.abs(player.xspd)<0.1?0:0.8; }
	if (!Key.isDown(Key.UP) && !Key.isDown(Key.DOWN)) { player.yspd *= Math.abs(player.yspd)<0.1?0:0.8; }
	var xL:Number = Math.floor(player.x / tileSize); var xR:Number = Math.floor((player.x+tileSize-1) / tileSize);
	var yT:Number = Math.floor(player.y / tileSize); var yB:Number = Math.floor((player.y+tileSize-1) / tileSize);
	var maxL:Number = xL*tileSize; var maxR:Number = xR*tileSize;
	var maxU:Number = yT*tileSize; var maxD:Number = yB*tileSize;
	var cL:Boolean = !(map[yT][xL-1]==1 || map[yB][xL-1]==1);
	var cR:Boolean = !(map[yT][xR+1]==1 || map[yB][xR+1]==1);
	var cU:Boolean = !(map[yT-1][xL]==1 || map[yT-1][xR]==1);
	var cD:Boolean = !(map[yB+1][xL]==1 || map[yB+1][xR]==1);
	var xmove:Number = player.xspd; var ymove:Number = player.yspd;
	if (!cL && player.x+player.xspd < maxL) { xmove = maxL - player.x; player.xspd = 0; }
	if (!cR && player.x+player.xspd > maxR) { xmove = maxR - player.x; player.xspd = 0; }
	if (!cU && player.y+player.yspd < maxU) { ymove = maxU - player.y; player.yspd = 0; }
	if (!cD && player.y+player.yspd > maxD) { ymove = maxD - player.y; player.yspd = 0; }
	player.x += xmove; player.y += ymove;
}

// Call Everything
_root.onEnterFrame = function() { movePlayer(); drawObjects(); lineOfSite(player.x+tileSize/2, player.y+tileSize/2, _xmouse, _ymouse); }

```

[size=1]Dam, smilies make it difficult to post code :P[/size]

**Update:**  
Problems upload .swf at the moment, so here’s the .fla:

---

<div class="post-metadata">

**Author:** ![anbu\_xynthos](https://avatars.discourse-cdn.com/v4/letter/a/dbc845/32.png) [@anbu\_xynthos](https://forum.kirupa.com/u/anbu_xynthos)\
**Post date:** [March 24, 2006, 2:31am UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/2 "2006-03-24T02:31:09Z")

</div>

I wish I could do that… it makes me feel dumb.

Wah.

---

<div class="post-metadata">

**Author:** ![Jeff\_Wheeler](https://avatars.discourse-cdn.com/v4/letter/j/59ef9b/32.png) [@Jeff\_Wheeler](https://forum.kirupa.com/u/Jeff_Wheeler)\
**Post date:** [March 24, 2006, 2:40am UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/3 "2006-03-24T02:40:08Z")

</div>

As for the little bug… couldn’t you try building two more lines, one pixel above, and one pixel below, and see if both of those hit. If they do… then it can’t see it, and you’ve reached the bug.

---

<div class="post-metadata">

**Author:** ![vvman](https://avatars.discourse-cdn.com/v4/letter/v/dc4da7/32.png) [@vvman](https://forum.kirupa.com/u/vvman)\
**Post date:** [April 11, 2006, 9:34pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/4 "2006-04-11T21:34:52Z")

</div>

respect

---

<div class="post-metadata">

**Author:** ![GNXDan](https://avatars.discourse-cdn.com/v4/letter/g/f05b48/32.png) [@GNXDan](https://forum.kirupa.com/u/GNXDan)\
**Post date:** [April 23, 2006, 6:02pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/5 "2006-04-23T18:02:48Z")

</div>

Maybe im the only one who isnt impressed, no affence. But i made this like really easily in a WAY simpler way but the accuracey can be changed in a for() loop. This is good mathematicalled but when you make games using tiles how are you supposed to use this code?  
I like the player movement though i would like to have a closed look at this, but using bitmap is all too easy.  
Good job anyway 😛

---

<div class="post-metadata">

**Author:** ![icio](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/icio/32/484_2.png) [@icio](https://forum.kirupa.com/u/icio)\
**Post date:** [April 23, 2006, 6:07pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/6 "2006-04-23T18:07:41Z")

</div>

The function is really easy to use in a game. As are tiles.  
Plus, the tile-based option allows for easy making of a 3D engine.

And would you care to share your code with us?

---

<div class="post-metadata">

**Author:** ![pips](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/pips/32/941_2.png) [@pips](https://forum.kirupa.com/u/pips)\
**Post date:** [April 24, 2006, 9:49am UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/7 "2006-04-24T09:49:07Z")

</div>

great!

---

<div class="post-metadata">

**Author:** ![GNXDan](https://avatars.discourse-cdn.com/v4/letter/g/f05b48/32.png) [@GNXDan](https://forum.kirupa.com/u/GNXDan)\
**Post date:** [April 24, 2006, 1:03pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/8 "2006-04-24T13:03:09Z")

</div>

I dont really want to post my code cos it suks compared to yours. Im only 14 and unlike you I dont know loads of maths and stuff so mine is made up more of if() statments :P. I hope to post it once i finish my game which is called uNatural 😃 tile based heaven

---

<div class="post-metadata">

**Author:** ![icio](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/icio/32/484_2.png) [@icio](https://forum.kirupa.com/u/icio)\
**Post date:** [April 24, 2006, 10:25pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/9 "2006-04-24T22:25:08Z")

</div>

Meh, age doesn’t have anything to do with it. I’ve only just turned 17.  
And I made the function so that it’s easy to incorporate into any tile-based game, by the way.

---

<div class="post-metadata">

**Author:** ![GNXDan](https://avatars.discourse-cdn.com/v4/letter/g/f05b48/32.png) [@GNXDan](https://forum.kirupa.com/u/GNXDan)\
**Post date:** [April 25, 2006, 5:35pm UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/10 "2006-04-25T17:35:06Z")

</div>

omg this is imbarrising (OMFG i need to learn to spell :s) but your code is simillar mine in that you use a while loop like me! 😃  
I will post my code now yay! I assumed cos you have all this maths and stuff that it was complicated but I read through it in detail and found its really simple. Im sorry for being a noob and not looking before i open my stupid mouth.

```auto

map = [[1,1,1],[1,0,1],[1,1,1]]
function checkCollision(){
var radians = Math.atan2(_root._ymouse-start._y, _root._xmouse-start._x);
//angle in degrees (only if you need it, not used in rest of code)
var angle = (radians/Math.PI)*180;
var i:Number = 1;
var j:Number = 0;
while (j != 1) {
//xpos/ypos are exact possitions, make 5 smaller for even more accuracy
var xpos = plr._x+Math.cos(radians)*(5*i);
var ypos = plr._y+Math.sin(radians)*(5*i);
//xpos2/ypos2 are the possitions used when checking again map array
var xpos2 = xpos-(xpos%game.tile);
var ypos2 = ypos-(ypos%game.tile);
i++;
//
var mapCollide = map[ypos2/tileHeight][xpos2/tileWidth];
if ((xpos<0) || (xpos>stageWidth) || (ypos<0) || (ypos>stageHeight) || (mapCollide == 1)) {
//do you code for what happens when its off the stage or hits a block
j = 1;
}
}
}

```

Im sorry that mine is not so user friendly because I like re-wrote it from my code in the lil text box thingy here, so any mistakes will be contributed to that. Its wierd cos I like saw this post a day after i had just worked everything out! Cos i couldnt find anywhere to tell me, this sucks but shows me I can do it too 😃 yay!

---

<div class="post-metadata">

**Author:** ![icio](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/icio/32/484_2.png) [@icio](https://forum.kirupa.com/u/icio)\
**Post date:** [April 26, 2006, 6:53am UTC](https://forum.kirupa.com/t/point-to-point-line-of-site/165548/11 "2006-04-26T06:53:43Z")

</div>

Nice code … but it is pretty much the same code that I posted at the start …
