# Raycast at Angle

##### Game Dev by Career, no idea what I'm doing
Hi all!

I'm making a stealth script because there wasn't any that fit my particular needs. The "does the NPC detect the player" part is all taking place in common events because I'm too lazy to make an actual script.

As is usual with game development, vision is three checks: a distance check, an angle check, and a raycast check (in that order, due to how expensive each operation is). If one doesn't pass, you cancel out. If it does, you move onto the next step.

I've got the first two implemented, but it's the last one that I'm struggling with a little. This is my current thinking: the raycast will go from the npc event to the player event. Picture a line drawn through every single square between the two. If any of those squares are "not walkable", the raycast check fails.

What do people think of this? Fortunately it won't be too many squares due to the distance check previously. I still need to think of the math of "getting every square in a line between two squares", as well as actually learn how to get the collision details from a map through JavaScript. If anyone has any knowledge of these, I would love to hear it! (I come from a Unity background, so my knowledge of interacting with RPG Maker's internals is still very fuzzy).

#### gstv87

##### Veteran
I seem to remember a function involving basic Pythagorean math, some angle calculations, and intersections of sets of tiles.
I used it for a projectile function, but wasn't my code originally.... I think it was Victor Sant's, or GubiD's... I have it somewhere.
it shouldn't be that hard to process when implemented, it's basic math 2000 years old.

too tired to really look for it right now, so here's another suggestion, as I think about it:
you propose a line, but given that the engine always counts tiles from the left, how about tracking the center of each tile within the area marked by the extremes of the tiles conforming the end points? (the center can always be written based on the coordinate and the tile size, both of which are known)

if the center of the tile is out of the rectangle, then the direct line is also missing the tile entirely.
I came up with this because I couldn't write it as a function of angles (brain.exe not working).
but it should be doable directly with angles and proportions.

Last edited:

#### caethyril

##### ^_^
Should be possible, yes. I think I encountered a couple of problems when I tried this (gave up on it after a while)...
• Check tile-by-tile: careful of rounding errors, special cases for flat lines, etc.
Could check pixel-by-pixel, but that'd be very inefficient.
For the line-to-tiles thing (discretisation) you may want to look at anti-aliasing algorithms.

• Left-handed coordinate system! (I'm used to right-handed, careful with the angles etc...)
Here's my failed attempt in case you're interested (I think it's an angle-to-direction issue, but couldn't nail down the cause):

More recently I discovered Galv's Event Detectors plugin, which says it has line-of-sight...haven't investigated it yet:
https://galvs-scripts.com/2016/08/01/mv-event-detectors/

#### gstv87

##### Veteran
here's *kind of* what I had in mind initially:

if one could define the area swept under the vectors |ae and |gc as defined by points aegc, and use those vectors as reference for the angles alpha and epsilon, and gamma, kappa and pi, then, IF, point p2 could be written in function of pi and alpha, then p2 would be outside of the area aegc, by being it's angle pi greater than kappa, but it's angle alpha lesser than epsilon.
likewise, since point p1 could be defined by angle gamma being lesser than kappa, then that point would be within the area swept of |ae, but outside the area swept by |gc

see each point as it's Cartesian components, and from there, it all turns into triangles.

grabbing the area to be swept, is not hard either.... a simple radius check of distance (this square's position - that other square's position), for both end points, and then intersect both sets.
*to those resulting tiles*, you apply this process, and find which is within the area seen by both end points.

Last edited:

##### Game Dev by Career, no idea what I'm doing
Thank you both! This is good food for thought. I'm going to bring up the idea with my coworkers on Monday and see what they say. I'll keep you updated!

Last edited:

#### gstv87

##### Veteran
As for distance and angle calculations, I already have those working.
> M A T H ! <

you can't fail, with math.

##### Game Dev by Career, no idea what I'm doing
Alright, I have it all mostly working! Slightly basic question - if I have the coordinates for a tile I want to check, can I check if the tile has collision or not?

#### gstv87

##### Veteran
Code:
``````Game_Map.prototype.isPassable = function(x, y, d) {
return this.checkPassage(x, y, (1 << (d / 2 - 1)) & 0x0f);
};``````
be mindful, that any B-E tiles on top of the A map tile can override the passability.

##### Game Dev by Career, no idea what I'm doing
I got it working! Thanks to everyone who helped out!

For those wanting to take a look, here is a link to the Json Map: https://www.mediafire.com/file/s8h23abtbsp6c47/Map001.json/file

I did it all through events, all the code is contained in there too. I'm sure there's a better way to do it, and lots of optimizations and more proper ways to do things, but this is not bad for a first pass. I'm planning on making it into a common event with better labeling of variables and the like.

EDIT: for those who happen to stumble upon this post and want to take a look, you want to place Map001.json in the file path: YOUR_GAME_NAME/data/ - make sure that there is no Map001.json there already otherwise it will overwrite that map. If there is one, replace the 001 with a number that isn't taken (i.e. Map005.json)

### Latest Profile Posts

Trying to create a diagonal sprite, by following through GrandmaDeb's tutorial here.
(Basically, cutting up and resizing parts from the down and left version of the sprite.)

I've been reworking some old sketches, there's definitely a change on the artwork

Drawing a character who fight with his dog in battle is an interesting yet difficult affair.
Trying to get my good habits back again after this year... I need to go back to the gym, but Brazil is still in a bad situation of Covid-19, so I will try to work out at home!
I need to become a better battery.