# SOLVEDHelp required with rotating laser beam.

#### Appletreeman

##### Member
I have an object that is sat in the centre of the room which slowly rotates whilst firing a laser beam. I'd like the laser beam to keep going until it hits the wall around the edge of the room so in effect it sweeps the entire room over the course of its rotation.
To start with I'm just drawing a line from the object but can't figure out how to only draw as far as the wall. I'm guessing I need a combination of point_distance and collision_point (maybe?). I feel like it should be fairly straight forward but I can't for the life of me figure it out.
If anyone could give me some help it would be gratefully received.

#### Pixel-Team

##### Member
What is your wall made of? This matters because it will determine how you make the laser collide with the wall. Is it a tile? Is it simply the edge of the room? The edge of the camera? Is it a instance with a sprite?

#### Appletreeman

##### Member
What is your wall made of? This matters because it will determine how you make the laser collide with the wall. Is it a tile? Is it simply the edge of the room? The edge of the camera? Is it a instance with a sprite?
Ah, It's an object so things can collide with it.

#### Pixel-Team

##### Member
If I were me, what I would do is starting at the origin of the laser, do checks every few pixels in the laser's direction, and put this coordinate in a variable called check_pos. This would be an array containing an _x and _y. The two cases where the checks prove true is either the laser reaches it's maximum distance, or your check_pos finds an object. Once either of these two conditions is true, you draw the laser from origin to it's check_pos. This would guarantee that only so many checks would happen per frame. I hope this makes sense.

#### Appletreeman

##### Member
Yeah, I think it makes sense. Gonna head off now to have a play and see what I can come up with.

#### Nocturne

##### Friendly Tyrant
Forum Staff
Moderator

That might be what you're looking for?

#### Appletreeman

##### Member
OK, so I'm having problems with this...
I've set up a test project (so I don't break anything else) of a single room with a wall on each side (oWall).
A single object in the centre with the following code...

Create
GML:
x = room_width*0.5;
y = room_height*0.5;

rot = 0;
_tx = 0;
_ty = 0;
Step
GML:
var _xx = lengthdir_x(1000, rot);
var _yy = lengthdir_y(1000, rot);
var _wall = collision_line(x, y, _xx, _yy, oWall, 0, 0);

if _wall != noone {
_tx = _wall.x;
_ty = _wall.y;
}

rot += 1;
Draw
GML:
draw_line_width_color(x, y, _tx, _ty, 3, c_yellow, c_yellow);
but when it is run the line is drawn from the centre to the wall but then then jumps 90 degrees. I know my knowledge isn't brilliant but I can't figure this out for the life of me.
Could someone please point out what I'm doing wrong

#### Nidoking

##### Member
I've set up a test project (so I don't break anything else) of a single room with a wall on each side (oWall).
Four walls? One along each side of the room? 90 degrees apart?

jumps 90 degrees
What's the problem? It's doing what you want it to do.

#### Appletreeman

##### Member
Nope. I want the beam to go from the centre out to the wall and sweep around the room (like the second hand on a clock).

#### Nidoking

##### Member
Well, then, you'll have to either recalculate your _tx and _ty when you want the beam to move, or actually use the rot variable to determine how to draw it. You're only ever drawing to the wall's x and y, which is one point per wall. Four walls, four points, 90 degrees apart.

#### Nocturne

##### Friendly Tyrant
Forum Staff
Moderator
Here:

GML:
/// @function collision_line_first(x1,y1,x2,y2,object,prec,notme)
/// @param    {real}        x1           first X value on collision line, real
/// @param    {real}        y1           first Y value on collision line, real
/// @param    {real}        x2           second X value on collision line, real
/// @param    {real}        y2           second Y value on collision line, real
/// @param    {real}        object     which objects to look for (or all), real
/// @param    {real}        prec        if true, use precise collision checking, bool
/// @param    {real}        notme    if true, ignore the calling instance, bool
/// @description        Returns the instance id of an object colliding with a given line and
///                     closest to the first point as well as the x/y position of the collision,
///                     or noone if no instance found.
///                     The solution is found in log2(range) collision checks.

function collision_line_first(x1,y1,x2,y2,object,prec,notme)
{
var sx, sy, inst, i;
sx = x2 - x1;
sy = y2 - y1;
inst = collision_line(x1, y1, x2, y2, object, prec, notme);
if (inst != noone)
{
while ((abs(sx) >= 1) || (abs(sy) >= 1))
{
sx /= 2;
sy /= 2;
i = collision_line(x1, y1, x2, y2, object, prec, notme);
if (i)
{
x2 -= sx;
y2 -= sy;
inst = i;
}
else
{
x2 += sx;
y2 += sy;
}
}
}
var _a = array_create(3);
_a[0] = inst;
_a[1] = y2;
_a[2] = x2;
return _a;
}
I've been using this function for years... It returns an array where the first entry is the ID of the instance found, and then the second two values are the EXACT x/y position of the collision. You would use it like this:

GML:
var _xx = lengthdir_x(1000, rot);
var _yy = lengthdir_y(1000, rot);
var _wall = collision_line_first(x, y, _xx, _yy, oWall, false, false);

if _wall[0] != noone
{
_tx = _wall[1];
_ty = _wall[2];
}

rot += 1;

Hope that helps, and save the function for other games, it's one of the most useful functions in my inventory.

EDIT: Fixed an error in the function.

Last edited:

#### Appletreeman

##### Member
Thanks for the replies guys.
I find it really difficult to comprehend things (not just programming) just by reading them, whereas if something is explained to me I can more often than not pick it up quite easily.
@Nocturne Thank you so much for that. I'm looking at the code trying to understand exactly what it is doing but to be honest I'm struggling. It doesn't help that maths is one of my major weaknesses.
In the function you say it returns the ID of the object and the precise x & y of the point of the collision, but I can't see where you're getting the dx and dy from.

Forum Staff