# How to make a reflecting (bouncing) laser?

25 replies to this topic

GMC Member

• GMC Member
• 383 posts
• Version:GM8

Posted 02 July 2012 - 09:51 PM

In the laser object (or the object that shoots the laser), I have the following code:

`beamDir = scrModulo(2*mirrorCollision[i].image_angle - beamDir,360)`

Here mirrorCollision[i] returns the (i+1)th id of the mirror that the beam collides with (there can be many mirror reflections in a row, like you see in the picture I posted). ScrModulo is just a basic modulo function with the exception that it handles negative values differently from GM's own modulo. For example, scrModulo(600,360) = 600 mod 360 = 240, but -60 mod 360 = -60 while scrModulo(-60,360) = 300 (returning argument0 to interval [0, argument1) ). Not sure if you need to use this new modulo function, but it worked in the context of my code.

A block that is laying horizontally has image_angle of 0 in my code, where are a straight vertical block has image_angle of 90, so you have to modify this a bit to fit your code, I suppose.

Note that this will not work for all edges of the rectangle. In Another Pathway (my game), the short edges of the mirror block won't reflect anything, but that's how I wanted it to be.

Edited by Koaske, 02 July 2012 - 09:55 PM.

• 0

GMC Member

• GMC Member
• 383 posts
• Version:GM8

Posted 02 July 2012 - 10:05 PM

For the direction of the reflecting surface, I make use of image_angle, since all my mirrors are rectangles.

How exactly are you using the image_angle? How does the program know which object to look for?

You can get the image_angle of the mirror with the ray-tracing method I explained above. I didn't look at your gmk to check how you implemented the laser, but with the method I explained, you just check of the line segment from the starting point of the beam to the ending point of the beam is free and then move the ending point step by step to the direction the laser is going to. When the ending point is not free anymore, collision_line(startX,startY,endX,endY,objWall,true,true) will return the id of the object it colllides with. If there are many collisions with objWall, the id returned will be one of those, but you can't really choose which.
• 0

### #23 zeninja

zeninja

GMC Member

• New Member
• 32 posts
• Version:GM8

Posted 03 July 2012 - 07:01 AM

For the direction of the reflecting surface, I make use of image_angle, since all my mirrors are rectangles.

How exactly are you using the image_angle? How does the program know which object to look for?

You can get the image_angle of the mirror with the ray-tracing method I explained above. I didn't look at your gmk to check how you implemented the laser, but with the method I explained, you just check of the line segment from the starting point of the beam to the ending point of the beam is free and then move the ending point step by step to the direction the laser is going to. When the ending point is not free anymore, collision_line(startX,startY,endX,endY,objWall,true,true) will return the id of the object it colllides with. If there are many collisions with objWall, the id returned will be one of those, but you can't really choose which.

I'm sorry to keep asking, I'm really new to Game Maker and really appreciate your help.

Could you go through it a bit slower for me?

What exactly does the collision_line function return? The ID of the object it is colliding with? And once I have that object's ID, could I just specify the arg0 value as that_object.image_angle?

Right now I'm using the Move to Contact dragndrop function and specifying the direction as point_direction(x, y, mouse_x, mouse_y) with that x, y value being the center of the player's sprite. Could I just take the position that it contacts and find the reflecting surface's angle from that?
• 0

GMC Member

• GMC Member
• 383 posts
• Version:GM8

Posted 03 July 2012 - 05:33 PM

If you're using the other formula (not mine), then you can use that_object.image_angle as arg0, but you might have to add 90 degrees to it to make it work.

The function collision_line does indeed return the an id of the object it's colliding with. If there's no collision it will return -4, which will be interpreted as "false" if you write something like "if collision_line...". If there are multiple collisions with the line, then one of them gets returned. (I haven't really figured out which one, seems to be somewhat arbitrary...)

It seems like you're not using the collision_line method, but I don't see why "move to contact" wouldn't work as well. If you can figure out the point where the beam contacts with the wall, you can use collision_point for this contact point to return the id of the wall. Then you can pass image_angle (+90?) of this wall object as a parameter to the reflection script.
• 0

### #25 zeninja

zeninja

GMC Member

• New Member
• 32 posts
• Version:GM8

Posted 03 July 2012 - 08:31 PM

If you're using the other formula (not mine), then you can use that_object.image_angle as arg0, but you might have to add 90 degrees to it to make it work.

The function collision_line does indeed return the an id of the object it's colliding with. If there's no collision it will return -4, which will be interpreted as "false" if you write something like "if collision_line...". If there are multiple collisions with the line, then one of them gets returned. (I haven't really figured out which one, seems to be somewhat arbitrary...)

It seems like you're not using the collision_line method, but I don't see why "move to contact" wouldn't work as well. If you can figure out the point where the beam contacts with the wall, you can use collision_point for this contact point to return the id of the wall. Then you can pass image_angle (+90?) of this wall object as a parameter to the reflection script.

Okay, I think I've got the collision set correctly, I'm getting the ID for the object it's colliding with and I think I know what the next problem is:

When my laser collides with the wall, each wall is set to have an image_angle of 0 because they're all squares facing the same direction. Is there a way to rotate sprites when you're placing them in the room? I guess the other solution is just to make separate objects for each angle but that's obviously not a long term solution.
• 0

GMC Member

• GMC Member
• 383 posts
• Version:GM8

Posted 07 July 2012 - 11:26 AM

In my game, if there are some mirrors that are already in place when the level starts, I'm using only one object type and setting their image_angle in the room editor by using each object's "creation" code. Of course, this might not be a good idea if a you have a lot of walls where the reflection can happen, since you have to set it manually each time, but that depends on your game. If this doesn't work well with your game, then you have to come up with something else to find the angle of the object.
• 0

#### 0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users