I assume that archer game was 2-dimensional, and the targeting actually worked?
Here's a diagram I made to show how you calculate this in two dimensions. Add in a parabolic curve from applying gravity to the arrow and a third dimension (Z), and I honestly wouldn't even know where to start.
The simplest way would be guess and check for lining different target points until the flight time matches the predicted time of occupation for the target spot. You should be able to zero in with only a handful of guesses. Alternatively, you can write the system as a set of differential equations, but since Minecraft Physics are non-Newtonian, I don't really want to do that. Guess and check is good enough.
Aiming on an arch, predicting where the player will be, and combining them are fairly trivial from a coding perspective. I have personally coded path prediction, including travel time on the bullets, with great success. My AI's could snipe you from across the map if you weren't careful. Figuring out how to arc a shot is also easy. It is very simple, middle school algebra.
agreed. leading is fairly simple. even games as old as Quake had it in some cases, but mostly didn't use it as it was too annoying.
usual strategy is to just guess how long it will take the projectile to reach the target, and assume they keep moving the same direction at the same speed. if a target is running and the projectile is not dead-slow, it usually works fairly well (annoyingly well, actually).
tracing out an accurate arc would be awkward and expensive, unless the arc were subdivided into a few linear segments (a raycast in Minecraft should be a fairly simple case of Bresenham's algorithm, so not likely too expensive). raycasting probably already exists anyways, since it would be relevant to both visibility and lighting calculations (trying to always draw every cube in the scene would likely be slow even for drawing cubes...).
so, probably something like (pseudocode):
bool checkTraceLine(vec3 src, vec3 dst)
{ ... bresenham... }
bool checkTraceArc(vec3 src, vec3 dst, float h)
{
if(checkTooFarArray(src, dst)) return false;
if(checkArrowWontReach(src, dst, h)) return false;
subdivide arc into, say, 4, 6, or 8 lines:
if(!checkTraceLine(segSrc, segDst))return false;
return true; //assume it will go
}
so, the default strategy would likely be to start with a default arc height for the distance, and check upwards by some number of fixed steps until either a trace succeeds, or some max height or distance is reached.
some sane limit though is that the skeleton "should" be able to reasonably have some idea where the player is.
granted, the leading prediction would possibly need to be recalculated per-arc, but this would not be all that expensive (or a single lead prediction could be used for sake of simplicity).
but, yes, it would be annoying, and likely something better reserved for harder difficulties.
In a purely 2D case, aiming at a moving target is pretty trivial. In a 3D case with gravity affecting the projectile it's only slightly less trivial.
It is very simple, middle school algebra.
I'm not buying it. Solving the system for the launch angle requires knowing a couple trig identities that aren't particularly well known (especially not at middle school level). The system of equations goes like this:
v cos(A) t = dx
v sin(A) t - g/2 t² = dy
You solve the first for t, plug into the second and then have to turn the sec²(A) into 1 + tan²(A) and then use the quadratic formula to solve for tan(A) which gets you (after simplification):
tan(A) = [v^2 ± sqrt(v^4 - 2 g dy v^2 - (g dx)^2)]/(g dx)
Or, if you make the quantity v²/g a fundamental parameter (I'll call it nu):
tan(A) = [nu ± sqrt(nu² - 2 dy nu - dx²)]/dx
Obviously this is for a projectile of fixed speed (allowing the speed of the projectile makes every calculation here extremely trivial; just assume the target is stationary, compute the firing velocity, then add the target's velocity to what you computed).
So there are two solutions to our problem, which makes sense. There's a high angle shot and a low angle shot. If you let nu tend towards infinity (the speed of the projectile goes to infinity or gravity goes to 0), one solution tells us to fire practically straight up in the air (the + solution) while the other tells us to fire straight at the target (the - solution), so the + solution gives a high angle shot and the - solution gives a low angle shot. It also tells you how to change projectile speed if you change gravity by remember the parameter nu is v²/g (so if we raise gravity by a factor of 4, we have to double velocity to keep everything the same).
We can also get time of flight:
t = dx/(v cos(A)) = dx/[v sqrt(1 + ([nu ± sqrt(nu² - 2 dy nu - dx²)]/dx)²)]
This result can be used in 3D for shots that even need to lead the target. In this case dx and dy are functions of the aiming angle and the target's initial position and velocity. You would need to find an aiming angle such that the flight time of the projectile matches the travel time of the target. You could find an algebraic solution to this, but at this point it because pretty silly to do so and numerical methods could end up being faster.
But what I'd propose for this is rather than having skeletons shoot virtual arcs, just use the actual arrows that they fire to improve their aim. No need for ray tracing when arrow firing essentially already does that. Just have them keep track of where their last arrow ended up.
Rollback Post to RevisionRollBack
Never attribute to malice what can adequately be explained by incompetence.
the above is if you try to solve it "properly"...
rarely in gaming is all the actual math used, rather it is more common to just use a simple approximate.
this way, nearly all of physics and geometry is linear equations...
as with many things, a simple approximate is likely good enough, say:
height=k*sqrt(distance(source, dest)); //rel height of parabola at midpoint
where k is a constant, say:
k=gravity/firingVelocity; //assume here that both are linear, probably good enough
if an angle is needed, this can use atan or atan2, but more likely a vector is used rather than an angle anyways.
as for ray casting, this shouldn't be all that expensive either (raycasts are cheap in small numbers, especially since the world is voxel based, rather than using CSG or polygonal geometry, so it is mostly a matter of 3D bresenham, rather than checking line/face intersections or similar...).
tracking an arrow and using feedback would likely be more complicated and expensive, since it would involve a multi-event process, rather than a few calculations and checks which can be done all at once.
Wuss
So let me get this straight, you want the skeletons to be able to ambush you at any moment?
This would just be annoying. It would not add to gameplay, it would simply put off new players.
Sissy.
The simplest way would be guess and check for lining different target points until the flight time matches the predicted time of occupation for the target spot. You should be able to zero in with only a handful of guesses. Alternatively, you can write the system as a set of differential equations, but since Minecraft Physics are non-Newtonian, I don't really want to do that. Guess and check is good enough.
Add a roof. OH LOOK THEY CAN'T DO ANYTHING NOW. /cruisecontroloff
usual strategy is to just guess how long it will take the projectile to reach the target, and assume they keep moving the same direction at the same speed. if a target is running and the projectile is not dead-slow, it usually works fairly well (annoyingly well, actually).
tracing out an accurate arc would be awkward and expensive, unless the arc were subdivided into a few linear segments (a raycast in Minecraft should be a fairly simple case of Bresenham's algorithm, so not likely too expensive). raycasting probably already exists anyways, since it would be relevant to both visibility and lighting calculations (trying to always draw every cube in the scene would likely be slow even for drawing cubes...).
so, probably something like (pseudocode):
bool checkTraceLine(vec3 src, vec3 dst)
{ ... bresenham... }
bool checkTraceArc(vec3 src, vec3 dst, float h)
{
if(checkTooFarArray(src, dst)) return false;
if(checkArrowWontReach(src, dst, h)) return false;
subdivide arc into, say, 4, 6, or 8 lines:
if(!checkTraceLine(segSrc, segDst))return false;
return true; //assume it will go
}
so, the default strategy would likely be to start with a default arc height for the distance, and check upwards by some number of fixed steps until either a trace succeeds, or some max height or distance is reached.
some sane limit though is that the skeleton "should" be able to reasonably have some idea where the player is.
granted, the leading prediction would possibly need to be recalculated per-arc, but this would not be all that expensive (or a single lead prediction could be used for sake of simplicity).
but, yes, it would be annoying, and likely something better reserved for harder difficulties.
I'm not buying it. Solving the system for the launch angle requires knowing a couple trig identities that aren't particularly well known (especially not at middle school level). The system of equations goes like this:
v cos(A) t = dx
v sin(A) t - g/2 t² = dy
You solve the first for t, plug into the second and then have to turn the sec²(A) into 1 + tan²(A) and then use the quadratic formula to solve for tan(A) which gets you (after simplification):
tan(A) = [v^2 ± sqrt(v^4 - 2 g dy v^2 - (g dx)^2)]/(g dx)
Or, if you make the quantity v²/g a fundamental parameter (I'll call it nu):
tan(A) = [nu ± sqrt(nu² - 2 dy nu - dx²)]/dx
Obviously this is for a projectile of fixed speed (allowing the speed of the projectile makes every calculation here extremely trivial; just assume the target is stationary, compute the firing velocity, then add the target's velocity to what you computed).
So there are two solutions to our problem, which makes sense. There's a high angle shot and a low angle shot. If you let nu tend towards infinity (the speed of the projectile goes to infinity or gravity goes to 0), one solution tells us to fire practically straight up in the air (the + solution) while the other tells us to fire straight at the target (the - solution), so the + solution gives a high angle shot and the - solution gives a low angle shot. It also tells you how to change projectile speed if you change gravity by remember the parameter nu is v²/g (so if we raise gravity by a factor of 4, we have to double velocity to keep everything the same).
We can also get time of flight:
t = dx/(v cos(A)) = dx/[v sqrt(1 + ([nu ± sqrt(nu² - 2 dy nu - dx²)]/dx)²)]
This result can be used in 3D for shots that even need to lead the target. In this case dx and dy are functions of the aiming angle and the target's initial position and velocity. You would need to find an aiming angle such that the flight time of the projectile matches the travel time of the target. You could find an algebraic solution to this, but at this point it because pretty silly to do so and numerical methods could end up being faster.
But what I'd propose for this is rather than having skeletons shoot virtual arcs, just use the actual arrows that they fire to improve their aim. No need for ray tracing when arrow firing essentially already does that. Just have them keep track of where their last arrow ended up.
rarely in gaming is all the actual math used, rather it is more common to just use a simple approximate.
this way, nearly all of physics and geometry is linear equations...
as with many things, a simple approximate is likely good enough, say:
height=k*sqrt(distance(source, dest)); //rel height of parabola at midpoint
where k is a constant, say:
k=gravity/firingVelocity; //assume here that both are linear, probably good enough
if an angle is needed, this can use atan or atan2, but more likely a vector is used rather than an angle anyways.
as for ray casting, this shouldn't be all that expensive either (raycasts are cheap in small numbers, especially since the world is voxel based, rather than using CSG or polygonal geometry, so it is mostly a matter of 3D bresenham, rather than checking line/face intersections or similar...).
tracking an arrow and using feedback would likely be more complicated and expensive, since it would involve a multi-event process, rather than a few calculations and checks which can be done all at once.