Currently when an Archer or Arrow Tower shoots an Arrow, the Arrow does properly rotate in the x-y plane so that it's facing its target, but it doesn't handle the other ones (yaw? pitch? roll?). So it doesn't point up when its z-velocity is positive, nor down when it's negative. It also doesn't appear shorter when flying more parallel to the camera's line of sight than it does when flying orthogonally.
I think one would just need to do some math to update the Arrow Thang's CocoSprite imageObject transform properties or their shorthands (scaleX, skewY, rotation, etc.) according to the velocity of the Arrow and the Camera's view. I was trying to do it but got confused. If you like affine transforms or computer graphics, you might have some fun with this one!
It's easy to test: just play Zone of Danger and get the arrows looking good. You might want to make the arrows travel a lot slower by editing their maxSpeed in their movement.Moves Component, which would emphasize their arcs. One of the reasons arrows travel so fast now is that they don't look good when actually needing to arc.
The code to write may be in or related to app/lib/surface/CocoSprite.coffee in the updateScale and updateRotation methods.
added perspectivizion for arrows (issue #46)
Hey there! I've been looking into this issue for like 5 hours in a row today.
So you can't just migrate to different arrow speed that easily. At least, when affecting all levels. Maybe do this in some want-to-be-looking-good ones?
I'll work out changes to updateRotation and updateScale methods in CocoSprite in order to arc properly, then test it against my implementation of combat.Arrow.launch, to ensure it works nice when arrows actually do move in large and visible arcs.
PS by the way, on the screenshot, I did not declare enemy, but it still works and shows victory. That's because I'm always attacking enemies actually. This is a poor solution and must not pass.
Wow, thanks for figuring all that out. I've pulled in your changes and now added a "maximizesArc" config property to the Arrow, so you can toggle the old behavior vs. the new behavior. Check it out in the Arrow code in the live site.
I liked how the arrows were arcing, but I realized that it had the same problem that everything else which arcs has: it looks too floaty. I think this is because we're using realistic world gravity of 9.82 m/s^2, but everything in the game is kind of super-sized. I tried setting Zone of Danger's gravity to 30 m/s^2 and the arrow arcs and jumping looked much cooler. I might try this on some more levels, too. If you grab the latest DB, you can try toggling the maximizesArc on in the Arrow config to see how it looks.
I think that the change to gravity also made it so that attacking enemies fails once more–at least, when I just tried it, it loses, whereas actually hitting the nearest one does succeed.
done rotating, looks good in Zone of Danger (#46)
Now absolutely done scaling (#46)
also commented math's out.
Glad you liked!
After some more hours of trial-end-error, I've come up with a solution for arrows so they actually point along the arc, check this out, for example:
This is highly ad-hoc, because it works only with my combat.Arrow.launch and there are empirical constants involved. Tell me what we can do with that. I've pull requested in case you need my code, because it's 00:30 here in Russia and I'm going to sleep soon.
By the way, how can I update my DB when I already have one? Mongorestore errors that it can't add data cause of unique index, because it (obviously) interferes with existing data. I suppose there's another command to do that?
I like this for Dungeon Arena, and it works when we are using maximizesArc (which I sadly don't think we'll be able to use in existing levels without a lot of rebalancing, but can use going forward), but something is up when they're flying along a straighter path:
I'm merging it in, but only when maximizesArc is true for now.
We don't yet have a way to selectively merge in part of the new dump. If you need stuff from your current DB and also from the new DB, then it has to be a manual process, either of bringing forward your old things after restoring the new dump, or of manually grabbing the new part of the new DB.
Great! I hope that artisans will take this feature into account.
One can always change visual effects to fit the desired result by managing constants in updateRotation. For example, if you need less curving on a straight path, you change
Math.max(factor / 90, 0.4)
to something like
Math.max(factor / 90, 0.2).
In case of any questions, feel free to ask me! (it is addressed to anyone who wishes to make this more beatiful)
I guess the thing that is needed is to not just infer the arrow's position along its flight path by its z-velocity, because that only works if the arrow is shooting from a position with equal z to its target. It should take into account the difference between the start and end z-values.
"that only works if the arrow is shooting from a position with equal z to its target" - not correct.
Notice that in calculateArcVelocity we take the difference of pos.z and end.z: the denominator under Math.sqrt is distance - (targetPos.z - pos.z). Consider the following picture:
Denote d = targetPos.z - pos.z
Don't get me wrong: the code in combat.Arrow stands for 45 degree angle. But the hack I did on calculating arrow curve by looking at it's velocity.z is actually working independent of that (it's just an effect we see on the surface), with the help of gravity. Math and common sence prove it to be right.
Thanks for the diagram and for explaining it more. I played around with it and came up with something that appears to work almost perfectly in all the different cases I tried:
vz = @thang.velocity.z
if vz and speed = @thang.velocity.magnitude(true)
vx = @thang.velocity.x
heading = @thang.velocity.heading()
xFactor = Math.cos heading
zFactor = vz / Math.sqrt(vz * vz + vx * vx)
rotation -= xFactor * zFactor * 45
Now I don't know why the 45 isn't 90, which is what I thought it should be, but I'm always rusty at these things.
Pleasant to see that you could match your desires with my solution!
Concerning 45 instead of 90:
my original reasoning was that if you fire perfectly to the left, with the target having same z-coordinate as shooter, you should see the 45 degree arc at the start and -45 at the end (because combat.Arrow.launch was written with 45 in mind). That should happen when 'xFactor' (which handles position to camera) is fixed at 1 and 'zFactor' is 1 (or very close) at the start and -1 (or close value, same as at start) at the end point. But when z-coordinates are not equal, zFactor is not the same at endpoints, for example if end speed exceeds start speed, zFactor can come above 1 and that will result in > 45 degree arc.
These reasoning works if zFactor equals to velocity.z.current / 'some common value of velocity.z.start', which I was trying to simulate with velocity.z.current / 12.