Arcing Projectiles

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

User avatar
Soule X
Red Slime
Posts: 86
Joined: Wed Sep 19, 2012 4:18 pm
Location: Indianapolis

Arcing Projectiles

Post by Soule X »

Another request for projectiles.
Currently I'm using TMCs code from gohrillas and it works pretty decent but I would like to have more precice control. I want a Projectile, an arrow, that arcs. I would like to be able to pass it only a distance and a height to travel, with which it would reach the height in half the distance and descend to the maximum distance. I know it's probably complicated but I'm ready to try. My first attempts weren't what I would have liked.
User avatar
Gizmog
Metal King Slime
Posts: 2622
Joined: Tue Feb 19, 2008 5:41 am

Post by Gizmog »

Not a math guy, but I believe what you are describing is a parabola.

EDIT: But, that's terribly unhelpful, isn't it? I'll try to talk through the problem and see if I can understand it.

So, what we have are some known values.

You know A) Where your arrow is starting. B) Where your arrow is ending up and C) where it wants to be in the middle.

So, let's assume for the moment that horizontal speed isn't going to change. Let's assume that the arrow moves horizontally 4 pixels per tick.

Let's assume too, that point B is 100 pixels east of Point A. That means the arrow is going to be moving for 25 ticks, which means about the thirteenth tick is where it reaches point C and starts downwards.

I wish I had some graph paper for this.. anyway! So let's say Point C is 48 pixels above Points A and B. That means that it has twelve ticks to go up, 1 tick to hang even in the air, and twelve ticks to come back down. BUT, if you just tell it to go 4 pixels at a time, it's going to do a pyramid shape rather than an arc. You could try figuring fractions like, at an 8th, a quarter, a half, etc. but then you end up in Zeno's Paradox where you're always halfway away from where you really want to be.

Again, nto very good at maths. I think we're going to end up doing Squares and Roots and all of that.
Last edited by Gizmog on Wed May 06, 2015 8:34 pm, edited 1 time in total.
User avatar
Soule X
Red Slime
Posts: 86
Joined: Wed Sep 19, 2012 4:18 pm
Location: Indianapolis

Post by Soule X »

Yeah I just really need a starting point. It's complicated when you add variables. If it was a set thing I could just trial and error it until it came out right. But the math is gonna be pretty intense I'm thinking. I'm not bad at math with a little direction lol
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

If you want a projectile to follow a perfect parabola there's a very simple (non-mathematical) way to do it. Say for example you want the "arrow slice" to move 5 tiles to the east following an arc. Just spawn an NPC who is invisible at the origin of where the arrow should start. Create the arrow at that origin and parent it to the NPC you just spawned. Have a arrow slice move north at a set velocity, then south at a set velocity once it reaches it's peak (This can be done simply using a timer which has two phases represented by a variable being on or off (see my boomerang script). Then all you have to do is have the NPC move east 5 tiles at a set speed. Since the arrow is parent to the NPC, the arrow will appear to move up and down along an arc as it moves eastward to it's destination. Alternatively if you want to get more discrete than using an NPC you could parent the arrow slice to an invisible eastward moving slice.

If you wanted to even do more super crazy unorthodox movement you can simply parent that invisible slice to another moving invisible slice, hence any shape of arrow path is easily possible if you plan it out right.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Soule X
Red Slime
Posts: 86
Joined: Wed Sep 19, 2012 4:18 pm
Location: Indianapolis

Post by Soule X »

That actually seems like a really nifty trick. I'm not using any npcs just because it's easier keeping track of all the slices since they are numbered and grouped in an organized fashion within the script, so I would go with a slice. But I never would have thought to have an invisible patent control the entire horizontal movement. In my head that seems like it would really work well. I'm thinking I can set the speed by a combination of the distance and height and then it's just a matter of percentages and velocity to get the arrow to reach max height at a realistic looking velocity at the midway point.
I'll try that when I get home.
User avatar
msw188
Metal Slime
Posts: 787
Joined: Tue Oct 16, 2007 1:43 am
Location: Los Angeles, CA

Post by msw188 »

You cannot get the speed just by knowing the distance and the height. You will have to give the speed as a third input. Most likely the horizontal speed is the easiest.

So three inputs:
d=distance (pixels)
h=height (pixels)
v=horizontal velocity (pixels per tick), should divide total number of pixels in a tile (and thus evenly divide d)

You will also have two additional 'automatic' inputs:
xi=initial x coordinate
yi=initial y coordinate

Then you would like to program a parabola knowing three points: the start, the halfway point, and the finish. This is not hard. Pseudocode below

Code: Select all

variable(x,y,t) #t will act as a parameter measuring ticks

for(t,0,d/v),do
begin
x:=xi + vt
y:=yi + h - 4h/(d^2)*(vt-d/2)^2

#command to put your graphic at coordinates (x,y)

#command to check whether or not the arrow has struck any obstacle, and if so, turn on a tag to stop the for loop

wait(1)

end
The hard part, as far as I can tell, would be deciding how to deal with:

1. Can the arrow be interrupted by other things (walls, other NPCs, etc)?
2. Can more than one arrow be onscreen at a time?
3. Should the graphic of the arrow change as it flies through the air?
4. Can other scripts interrupt this script?

I can't remember enough about how to handle these sorts of issues.
Last edited by msw188 on Thu May 07, 2015 4:56 am, edited 1 time in total.
I am Srime
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Yeah it's the simplest way I know, I plan to continue using this concept for the rest of my own game. Another great thing about using a timer with phases is that you can increase the number of phases and update the arrow's sprite art each phase, thus making it look like the arrow is always tangential to the arc.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

(Mogri created Gohrillas, I only wrote the sine/cosine script it uses).

sheamkennedy describes that slice-parenting-trick as moving in an arc, but it's actually a triangle. For an arc you definitely need to use a for loop rather than a timer, so it only complicates things to use parenting and additional slice.

I slightly rearranged msw's psuedocode into a working script so that you won't have problems with the calculations being performed using integers:

Code: Select all

for(t,0,d/v) do, begin
    x := xi + v*t
    y := yi + h -- (v*t--d/2)^2 * 4*h/(d^2)

    #command to put your graphic at coordinates (x,y)
    put slice(slice, x, y)

    #command to check whether or not the arrow has struck any obstacle, and if so, turn on a tag to stop the for loop

    wait(1)
end
You could also make the for loop be over horizontal distance travelled rather than time.

However, the other option is the give the strength of gravity as the additional input, rather than the initial vertical and horizontal speeds. That's obviously the physically correct thing to do (do you want projectiles fired at different angles to appear to accelerate under gravity at different rates?) However the fact that you're specifying the height as an input is odd, indicating that the height and distance aren't both going to vary freely according to player input. So there wouldn't be any point in using anything more complicated than msw's parabola equation.
Last edited by TMC on Thu May 07, 2015 10:53 am, edited 1 time in total.
User avatar
msw188
Metal Slime
Posts: 787
Joined: Tue Oct 16, 2007 1:43 am
Location: Los Angeles, CA

Post by msw188 »

What is this arrow arc for, anyways? The formula I wrote assumes that the arrow starts and ends at the same y-coordinate. So it doesn't work for, say, shooting someone up on a hill. It also assumes the playing field is two dimensional (like a sidescroller). If you meant something else, the math gets slightly trickier, but still easier (in my mind) than deciding what to do with multiple arrows, collision detection, etc.
I am Srime
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Yeah I assumed 2D coordinates too. My method will work for shooting enemies up on a hill, it just requires a collision detection script in the autorun script's while loop, which checks for collisions between the arrow and the enemy each tick. I think using a collision detection would make msw188's script work as well since it would just cut the original script short of finishing. One thing I find that you will have to tweak a lot when making a collision detection script is the slice's velocities. If the arrow is moving too fast it can essentially "pass through" an enemies collision box, and same goes for if the enemy is moving too fast. I think this is the most involving part of making these types of scripts.

My method could be expanded in to 3D coordinates also just by adding a second invisible slice in which the first invisible slice is parented to. This second invisible slice would just move along the z-axis (whatever that may be since it will depend for each game). This sounds like it could get really messy fast so I don't suggest it unless your game is going to be fairly minimal.

Also when I say "my method" I should actually give credit to TMC who first showed off this type of method. It's called a bezier curve if you want to look it up on wikipedia, TMC performs these curves using formulas in his scripts I think, but I soon figured that it worked the same way using a parenting technique as I've described.
Last edited by sheamkennedy on Thu May 07, 2015 5:55 pm, edited 2 times in total.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Bob the Hamster
Lord of the Slimes
Posts: 7658
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

I seem to remember BMR had a pretty nice curved projectile script, allthough I don't remember his method. I think he was using it for spell animations in Legacy, but I don't know if it was in a released version.

There were some videos of the curves in action here:

http://www.slimesalad.com/forum/viewtop ... &start=240

Soule X, I am not sure exactly what game you are working on, but it is possible that the simplest way to get curving projectiles will be to implement gravity exactly like how a Sidescroller would do it.
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Oh my bad, I got TMC and BMR mixed up. The guys with the 3-Letter names, I mix them up all the time.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

It's easy to use the parabola equation if the ground isn't level, just replace the for loop with a while loop and add a test for hitting the ground as sheamkennedy said.

The easiest way to solve the problem of fast moving projectiles moving through targets is simply to calculate the position and do collision testing in smaller steps, moving forward multiple times for tick. Easier done than said: skip the wait in the loop e.g. 3/4ths of the time.

Using gravity is indeed very simple to script. But if you want to specify the start and end then you need to calculate the velocity to fire at, which means solving the equation for a parabola as msw did. In other words there's no difference except whether the math is inside or outside the for loop.

BMR used bezier curves, which aren't suitable for projectiles unless they're rockets or some kind of magical projectile. Yes, that sort of curve is a linear interpolation of simpler (lower order) curves. Oh! I completely forgot about the movesliceto command. That can be used to move in curves rather than straight lines (like slice velocity). I don't know whether bezier curve movement is possible using that.
Last edited by TMC on Thu May 07, 2015 7:32 pm, edited 1 time in total.
User avatar
sheamkennedy
Liquid Metal Slime
Posts: 1110
Joined: Mon Sep 16, 2013 9:29 pm
Location: Tama-shi, Tokyo, Japan
Contact:

Post by sheamkennedy »

Hmm that movesliceto function seems useful, I'll have to keep that in mind for my own game.

Thinking further on this I think doing this mathematically may have some advantage. If for example you're making a tank game in which players take turns shooting projectiles through the air at one another then math is better. This could allow the formula to account for wind speed which would just be represented by a variable which adds/subtracts a value from the x-velocity each tick. On the other hand if you always want the projectile to arc in to your target then either math or gravity or slice parenting can be used, depends what you are most comfortable with. No matter what I think all of these will require a collision detection to cut-off the scripts before they reach their natural endpoint thus making the projectile always end at the target.
⊕ P E R S O N A L M U S I C: https://open.spotify.com/album/6fEo3fCm5C3XhtFRflfANr
� C O L L A B M U S I C: https://dustpuppets.bandcamp.com/releases
User avatar
Soule X
Red Slime
Posts: 86
Joined: Wed Sep 19, 2012 4:18 pm
Location: Indianapolis

Post by Soule X »

I guess the details were a little unclear. The arrow is fired from an npc on a flat surface. The player can be at any height. That's why I want to specify a height coordinate. I actually stayed up pretty late last night testing and I used steamkennedy's idea. I tweaked the y movement to be faster at the beginning of the upward movement and the end of the downward movement so it moves in an arc, slowing at the peak. A little crude maybe but I actually like the look better than the gohrillas code I had before and I have much better control now.
Everything in my game is controlled by timers. I can't have any wait commands because they will interrupt movement. I feel timers are easier for me to work with.
Also hit detection is not a problem. All hit detection is called from a single script depending on if it's the player or npc so it's all organized nicely. I already had the hit detection worked out from the previous code I was using so it won't be a problem with this one.
I'll post the script later when I get home.
Post Reply