Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers AppGameKit Corner / [SOLVED] checking sprite is within 30 degree angle of another sprite. problems near 1 and 360

Author
Message
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 3rd Jul 2018 04:16 Edited at: 3rd Jul 2018 04:17
Hey guys. Im back after a few months off programming. Currently working on a game that requires players to rotate a sprite to the same orientation(or angle) as another sprite. I am allowing a 30 degree window of accuracy. my checker works fine, but gets glitchy when the sprite is almost straight up. The math doesn't account for "around the corner" calculations between 1 and 360 (or is it 180 and -180?)



For the life of me I can't figure out a calculation to consider if getspriteangle(hole) is 2 and getspriteangle(player) is 359, a good formula to consider that within the 155 over and 15 under allowed...

As always, any ideas are greatly appreciated. You guys are awesome!
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...

The author of this post has marked a post as an answer.

Go to answer

smallg
Valued Member
18
Years of Service
User Offline
Joined: 8th Dec 2005
Location: steam
Posted: 3rd Jul 2018 10:10
You need to check your over and under values so that if if they go below 0 or over 360 you reset them to 360-value or value-360
Where value is the amount they are out of range.
life's one big game
spec= 4ghz, 16gb ram, AMD R9 2700 gpu
TomToad
6
Years of Service
User Offline
Joined: 6th Jan 2018
Location:
Posted: 3rd Jul 2018 11:22
Haven't tried this out yet, but couldn't you just use something like
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 3rd Jul 2018 20:48 Edited at: 3rd Jul 2018 21:00
Just so I understand correctly, do you want sprite A's direction to be within 30 degrees of the angle that sprite B is looking? Or just be within 30 degrees in the direction of sprite B itself? For instance, the player is looking to the right and sees the other sprite directly in front of it. But that sprite is looking straight up. Looking at the pic below, their respective views have a 90 degree difference.



If this is what you're after then you'll need to wrap your values. I'll see if I can come up with a function for you.


Or, do you want to know the angle of sprite A looking at B as in my illustration below? The red arrows point in the direction the sprite is facing. The green represents 30 degree tolerance, or in this case field of view (FOV). The blue line is the angle of sprite B from A's direct line of sight.



If the second method is what you're after, atanfull() is the command you want.
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds

Attachments

Login to view attachments
IronManhood
9
Years of Service
User Offline
Joined: 6th Feb 2015
Location: US
Posted: 3rd Jul 2018 21:07
This function may help you. It tests an angle to see if it is within a range that's relative to a second angle. Also, it takes into account if the range extends above 360 or below 0.

Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 3rd Jul 2018 21:10
Wrote this quicker than I expected. Very simple function will return the difference between two angles, returning the shortest angle between the two as if visually seen lying on a circle. So if one angle is 300 and the other is 2, it'll return 62 degrees and not 238.

Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 4th Jul 2018 01:45 Edited at: 4th Jul 2018 01:47
First of all, you guys are awesome! Thanks so much for taking the time to help. I wrote something to help describe the issue a little better


if you paste this into a blank file and run it, you will see there is a difference of 9 degrees which is less than 15 but shows no . I just cant get my head around the wrap around math at 360-1

I just finished a 12 hour day of work and have to put my 2 year old to bed before I can read through the responses more thoroughly. I appreciate the help!
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
IronManhood
9
Years of Service
User Offline
Joined: 6th Feb 2015
Location: US
Posted: 4th Jul 2018 04:35
Check this out. It illustrates the inrangeAngle() function.

Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 4th Jul 2018 04:59 Edited at: 4th Jul 2018 05:00
I will look at it right now Iron. I just tried to caveman my way though it and came up with something that works for the 360-1 issue, but creates the same problem at the 180 area. I could use it conditionally just to cover angles close to 1 or 360

here it is if you are curious



Looking at your code now. Thanks!
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 4th Jul 2018 05:06
I just ran it, and your program looks great! Im going to go get a very very large cup of coffee and try to breakdown your code and learn what I can from it!

Thank you

Phaelax, I looked at AGK's documentation of atanfull, it seems a little out of my league still. Im still planning to look into that snippet you sent.
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
TomToad
6
Years of Service
User Offline
Joined: 6th Jan 2018
Location:
Posted: 4th Jul 2018 08:36
This post has been marked by the post author as the answer.
Don't know why everyone is overcomplicating this. Just do this:

Works fine.
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 4th Jul 2018 13:16
TomToad, take a look at my function and you'll see why an extra step is needed for your method.


Vladimuffin, my function will do what you want, you'll just need to rewrite how you check it.

Instead of:
if GetSpriteAngle(spriteB) > spriteAunder and GetSpriteAngle(spriteB) < spriteAover

Use this:
if getAngularDifference(GetSpriteAngle(spriteB), GetSpriteAngle(spriteA)) <= 15

My function will also work in place of Ironmanhood's inRangeAngle() function.
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 4th Jul 2018 14:08
Phealax, I will try implementing your function this morning, and see what I come up it.
TomToad, I tried the script above and it looks like it works, and I can understand it,.
Ironmanhood, Im still trying to figure out that program you wrote to see what I can learn from it!

You guys are so awesome. Thanks again for all the help. Im just not that experienced with coding, so its going to take me a long time to evaluate the data you guys have given. Wish I could mark multiple responses as the answer because I learned quite a bit from each.
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
TomToad
6
Years of Service
User Offline
Joined: 6th Jan 2018
Location:
Posted: 4th Jul 2018 15:16
@Phaelax: In order to solve Vladimuffin's problem as stated above, the extra step is not necessary. Every convex angle less than 15 degrees is also a concave angle greater than 345 degrees. My method just checks for both in one simple If statement, eliminating the need for an extra calculation. Now if he needed the actual value of the convex angle, say for additional computations or to print out the result, then yes, the additional step is needed. As Vladimuffin seems to have accepted Ironmanhood's solution, and that does not return the difference, but rather a boolean, then it is easy to assume that whichever angle you compare against is not important as long as you get the desired results.

Ironmanhood's solution initially appears to be the least efficient of the three, but can have its use if the window is not to be centered. for example, if you want to test within -10 to 20 degrees instead of ±15 degrees.
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 4th Jul 2018 16:12 Edited at: 4th Jul 2018 16:27
Oops I meant to mark Tom toads answer as the solution not my own. Sorry Tom, I'm a forum nub. You guys are all light years ahead of me in terms of programming, so I don't actually know which method is the most efficient. Tomtoads solution is the only one I fully understand as he has appeared to dumb it down to my level. Haha. Thanks again guys
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 4th Jul 2018 21:51 Edited at: 4th Jul 2018 22:09
I missed the part where you were checking two angle values, but I'd find that a bit more tedious than just having to check one value.

By all means, go with the solution you understand. But work on understanding the others to determine which you feel is more efficient. I'll try to explain mine.


Given two angles, imagine them pointing to two points on a circle. Assume 0 and 360 are straight up and the angle increments clockwise. If you could only travel from one angle to the other in a clockwise fashion around the circle, then subtracting the two angles would give you the difference between them. But, in your case, we want the small angle of difference between them as see from either direction on the circle. Think of a circular race track. You just crossed the start/finish line but the other guy is still behind you before the finish line. He might be 100ft behind you but in the race you'd have to go the distance of the track again to get where he's at. That's what I mean by traveling in one direction only.

So first step is get the difference of angles, simple enough just subtract them.

d = abs(a - b)

If B happens to be bigger than A then we'll get a negative number, so wrap it with the absolute value function so we'll always have a positive integer.

Now here's the trick for dealing with values like 350 and 10. This method alone would return 340 but in actuality we know it's really only 20 degrees apart. Place two points anywhere on the circumference of a circle and they'll never be more than 180 degrees apart. It's geometrically impossible. So, if our result is greater than 180 we'll subtract that value from 360 to get the smaller difference.

if d > 180 then d = 360 - d

Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
IronManhood
9
Years of Service
User Offline
Joined: 6th Feb 2015
Location: US
Posted: 4th Jul 2018 21:56 Edited at: 4th Jul 2018 22:00
Quote: "Ironmanhood's solution initially appears to be the least efficient of the three, but can have its use if the window is not to be centered. for example, if you want to test within -10 to 20 degrees instead of ±15 degrees."

Lol. It's not the most efficient but it gets the job done.


Quote: "My function will also work in place of Ironmanhood's inRangeAngle() function."


Could you provide an example?


How could we optimize my inrangeAng() function?





This is my minimum angle difference function:

Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 4th Jul 2018 22:09 Edited at: 4th Jul 2018 22:10

Quote: "Could you provide an example? "

Sure. Here's your code snippet with my function added. There's a slight difference between ours right at the edge of the boundary lines, but I believe that's due to precision of floats over integers.

Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds
IronManhood
9
Years of Service
User Offline
Joined: 6th Feb 2015
Location: US
Posted: 4th Jul 2018 22:58 Edited at: 4th Jul 2018 23:11
Quote: "Sure. Here's your code snippet with my function added."



Oh I see. Return true if the minimum difference is less than the range. I approached this from the wrong ..... angle. (kill me)

I condensed the code into a single function.
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 8th Jul 2018 17:37
Just wanted to thank you guys again for all the info! This thread is already helping me again (on the same project) I am trying to shoot bullets in the direction my sprite (not a constant angle) is facing. I am reverse engineering IronManHood's program to calculate the x and y direction the bullet should travel based on the angle of the ship. Love this community, and hope one day I can be as helpful as you guys.
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 8th Jul 2018 21:58 Edited at: 8th Jul 2018 21:59
I am building a test program to learn about sprite placement based on angle. Everything was going smooth until I got stumped by this error:

main.agc:83: error: Unexpected token "bullet", variable must be followed by an assignment

line 83 is identical to line 82, but line 82 doesn't have this issue...



Like my other snippet, this doesn't require any images. If anyone can enlighten me I would appreciate it. isn't "= PlaceByAngY( ship.y#, ship.angle#, 12 )" an assignment?
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
TomToad
6
Years of Service
User Offline
Joined: 6th Jan 2018
Location:
Posted: 8th Jul 2018 23:55
You have a stray "_" at the beginning of line 83. AppGameKit sees _ as a variable integer and expects to see an = after it, hence the "variable must be followed by an assignment" error. Instead, it is followed by the variable "bullet", hence the "Unexpected token" error. The error seems a bit ambiguous, but makes sense when you know how the parser is seeing the code. This is one reason I prefer a language that forces you to declare variables before use. This can be accomplished in AppGameKit with the #option_explicit command. With that command enabled, you would get "main.agc:87: error: "_" has not been defined" which is much more helpful.
Vladimuffin
7
Years of Service
User Offline
Joined: 27th Nov 2016
Location:
Posted: 9th Jul 2018 03:41
Oh my.... I spent 2 hours trying to troubleshoot that.... That seems like a good indication that I should take a break and get some sleep... TomToad Thank you! I will try that option thing.
One smart fellow, he felt smart. Two smart fellows, both felt smart. Three smart fellows all felt smart...
Phaelax
DBPro Master
21
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 9th Jul 2018 12:58
Quote: " I am reverse engineering IronManHood's program to calculate the x and y direction the bullet should travel based on the angle of the ship."


angle = getSpriteAngle(spr)
dx# = cos(angle)
dy# = sin(angle)

Now you have a normalized direction vector. Move your bullets like this:

bulletX = bulletX + dx#*speed
bulletY = bulletY + dy#*speed


You'll have to store the DX/DY values for each active bullet, otherwise they'll start to curve as you rotate the ship lol.
Tiled TMX Importer V.2
XML Parser V.2
Base64 Encoder/Decoder
Purple Token - Free online hi-score database
Legend of Zelda

"I like offending people, because I think people who get offended should be offended." - Linus Torvalds

Login to post a reply

Server time is: 2024-04-25 00:11:45
Your offset time is: 2024-04-25 00:11:45