Could anybody give any tip about how a running and shooting animation for a sprite is done? I mean, how to sincronize it with the running animation to make the transition running -> running + fire -> running smooth without glitches.
I have been studying a bit metal slug. This game has a walk animation, and a walk + shoot animation and it is really smooth. Could it be they have legs and body separated?.
Thanks in advance.
The way I would implement it is have an array of images containing the walking animation, and an equally large array containing the walking + shooting animation, and then keeping track of the state with an enum (e.g. WALKING and SHOOTING).
That's assuming the difference between sheathed and unsheathed weapon is quite small in terms of distance. Optionally the setState-method in your animation-class could queue a third array of images where the weapon is being brought into position.
STATE(image index)
WALKING(1) -> setState(SHOOTING) -> TRANSITION(2) -> SHOOTING(3) -> SHOOTING(4) etc
The additional transition-array just adds complexity and can often be omitted since the distance usually isn't that large.
Related
The best example of what I am trying to achieve is on this youtube video
http://www.youtube.com/watch?v=53Tk-oGL2Uo
The letters that make up the word 'Atari' fly in from the edges of the screen spinning and then line up to make the word at the end.
I know how to make an object move across the screen, but how do I calculate the spinning so that when the object gets to its end position it's facing the correct direction?
The trick is to actually have the object(s) in the right position for a specific time (say t=5.0 seconds) and then calculate backwards for the previous frames.
i.e. before 5.0 seconds you rotate the object(s) by [angular velocity] * (5.0 - t) and translate by [velocity] * (5.0 - t)
If you do this, then it will look like the objects fly together and line up perfectly. But what you've actually done is blown them apart in random directions and played the animation backwards in time :-)
The CORRECT way of doing this is using keyframes. You can create the keyframes in any 3D editor (I use MAX, but you could use Blender). You don't necessarily need to use the actual characters, even a cuboid would suffice. You will then need to export those animation frames (again, in MAX I would use ASE - COLLADA would work with Blender) and either load them up at runtime or transform them to code.
Then it's a simple matter of running that animation based on the current time.
Here's a sample from my own library that illustrates this technique. Doing this once will last you far longer and give you more benefits in the long run than figuring out how to do this procedurally.
So I have a ship, that has thrusters at the bottom and that can only use these to move forward. It can also rotate itself around its center. Its thrusters gives it acceleration, so it doesn't move at a constant velocity. What I want to do is to tell it "move to point B".
I have come up with a solution but it doesn't work very well and it doesn't rotate smoothly, it moves jerkily and it doesn't end up exactly where it should be, so I have to have a big margin of error.
Is this a normal problem, and if so is there a "standard" way of doing it? Is this an easy problem? I want to make it look like the ship is steering itself to that point, using the constraints (thrusters, rotation) the player has. This excludes just lerping it from point A to B. Or does it?
I'd love some help in solving this problem. Positions are stored in vectors, and it's a 2D problem. Just for reference I'm including my solution, which basically is accelerating the ship until and rotating it to point to the point. I think my implementation of this idea is the problem:
Vector diff = vector_sub(to_point, pos);
float angle = vector_getangle(diff);
float current_angle = vector_getangle(dir);
float angle_diff = rightrange(angle) - rightrange(current_angle);
float len = vector_getlength(diff);
// "Margin of error"
float margin = 15.0;
// Adjust direction, only if we're not stopping the next thing we do (len <= margin)
if ( len > margin && fabs(angle_diff) > 2.0 )
{
dir = vector_setangle(dir, current_angle + (angle_diff)*delta*(MY_PI) - MY_PI/2);
}
else if ( len > margin )
{
dir = vector_normalize(diff);
}
// accelerate ship (if needed)
acc.x = acc.y = speed;
acc = vector_setangle(acc, vector_getangle(dir));
if ( len <= margin )
{
// Player is within margin of error
}
If you are not looking for a very general solution that works online, then there is a simple solution. What I mean by online is continuously re-calculating the actions along the complete trajectory.
Assuming the ship is at rest at start, simply rotate it towards your target point (while still at rest). Now, your ship can reach the target by accelerating for t seconds, rotating back while in motion (for 0.5 seconds as per your constraint), and decelerating for another t seconds. If the distance between current point and destination is d, then the equation you need to solve is:
d = 0.5*a*t^2 + 0.5*a*t + 0.5*a*t^2
The first term is distance traveled while accelerating. The second term is distance traveled while rotating (v*t_rot, v=a*t, t_rot=0.5). The final term is the distance traveled while decelerating. Solve the above for t, and you have your trajectory.
If the ship is moving at start, I would first stop it (just rotate in opposite direction of its speed vector, and decelerate until at rest). Now we know how to reach destination.
The problem with offline trajectory calculation is that it is not very accurate. There is a good chance that you will end up in the vicinity of the target, but not exactly on top of it.
Let's make the problem a little more interesting: the ship cannot rotate without acceleration. Let's call this acceleration vector a_r, a vector that is at a certain angle against the ship's direction (somewhat like having a thruster at an angle at the back). Your task now is to rotate the ship and accelerate in such a direction that the speed component perpendicular to the vector connecting the current position to the target is canceled out. Instead of trying to calculate the vectors offline, I would go with an online approach with this.
The easiest thing to do would be to add the following algorithm calculated at every time interval:
Calculate the vector pointing from ship to destination.
Split your current speed vector into two components: towards the destination, and perpendicular to it.
If perpendicular speed is zero, skip 4
Start rotating towards the negative of the perpendicular vector's direction. If already looking away from it (not exact opposite, but just looking away), also fire main thruster.
This will oscillate a bit, I suspect it will also stabilize after a while. I must admit, I don't know how I would make it stop at destination.
And the final approach is to model the ship's dynamics, and try to linearize it. It will be a non-linear system, so the second step will be necessary. Then convert the model to a discrete time system. And finally apply a control rule to make it reach target point. For this, you can change your state-space from position and speed to error in position and (maybe) error in speed, and finally add a regulation control (a control loop that takes the current state, and generates an input such that the state variables will approach zero).
This last one is fairly difficult in the maths compartment, and you'd probably need to study control engineering a bit to do it. However, you'll get much better results than the above simplistic algorithm - which admittedly might not even work. In addition, you can now apply various optimization rules to it: minimize time to reach target, minimize fuel consumption, minimize distance traveled, etc.
I've looked for quite some time now to find a nice math solution for my cannon firing a projectile at a moving target, taking into account the gravity. I've found a solution for determining the angle at which the cannon should be fired, based on the cannon's position, the target's position and the start velocity. The formula is described here: http://en.wikipedia.org/wiki/Trajectory_of_a_projectile#Angle_.CE.B8_required_to_hit_coordinate_.28x.2Cy.29.
This works perfectly. However, my target is moving, so if I shoot at the target and the projectile takes a few seconds to get to its destination, the target is long gone. The target's x position can be determined from the time. Lets say that: x = 1000 - (10 * t) where t is the time in seconds. The y can be described as: y = t.
The problem is, that t depends on the angle at which the cannon is fired.
Therefor my question is: How can I modify the formula as described in the wiki, so that it takes the moving target into account?
Additionally, I might have been looking at the wrong words here or on Google, but I didn't find any solution describing this exact problem.
Thank you in advance for your braintime!
As a reply to your comments. I want to fire it now and the target is in range given the speed. I think that are all constraints that are applicable to this problem.
As a reply to the answer, lets take a look at this example:
The cannon is at {0, 0} and isn't moving.
The start speed is 100 m/s.
The target is at {1000, 0} and is moving with 10 m/s towards the cannon (v = -10 m/s).
What angle should I use to hit the moving target, when I want to fire at t=0 (immediately)?
If I shoot without taking the target's speed into account, I would aim at {1000, 0} and the angle could be calculated using the mentioned formula. But it will miserably miss the target because its moving.
As Beta suggested, I could aim at i.e. {500, 0}, calculate what time it takes for the projectile to arrive at those coords (lets say 5 seconds) and wait until the target is 5 seconds away from {500, 0}, being {550, 0}. But this means that I have to wait 450m or 45 seconds before I can fire my cannon. And I don't want to wait, because the target is killing me in the mean time.
I really hope this gives you enough info to go with. I'd prefer some math solution, but anything that would get me really close to firing "right away" and "right on target" is also much appreciated.
The problem is underconstrained, which means that you will have some choices. You can track the target through the air for a while, and the choice of when to fire is up to you.
If you know the target's trajectory, and you know how to hit a stationary target, then you can choose where you want the impact to occur. Just pick a point on the trajectory (comfortably far ahead of the target) and aim there. Then all you have to do is decide when to fire. It is easy to calculate how long the cannonball will take to reach the point of impact; it is easy to calculate where the target will be, that much time before it reaches the point of impact; when the target is there, pull the trigger.
I suspect finding a formula will be quite difficult. However the error in the iterative scheme below will go down by roughly a factor of v/V (v the target speed, V the projectile speed) each step.
start by taking the time of flight to be zero
Repeat
calculate the distance to the target (using time of flight)
calculate the time of flight from the distance.
Until two successive times of flight are close enough
i am playing around with the rotationX/Y/Z properties available in flashplayer since version 10. for testing purpose i created a cube and put canvas objects on three sides of it (top, front, bottom) and created a tween to get the values required for turing by 90 deg. turning the cube (a canvas) using rotationX = xx works well when the three side-canvas objects are small and filled with a not-to-complex element hierarchy. when using larger and more complex content it slows down. the next idea was to remove the canvas elements content and replace it by a snapshotimage of the content instead before starting the turn, after the turn is performed the original content is put back on the sides again. this results in a good perfomance increase. using a tween the last step of rotation is done in the function that is called as the tweenEnd handler. in this function also the process of copying the canvases content back is performed. unfortunately this results in a short hang of the cube right in that last rotation step, the reason for which is that rotation and copying back takes place at the same time.
so i could wait for some time after having called cube.rotationX = endValue by using a timer or setTimeout(func, 500), but this is ugly.
so my question is: after having called cube.rotationX = endValue a period of time is required to calculate data for the rotation and do the rotation itself. is there a way to find out the point in time when the rotation has ended, so that then the copying can be started ?
thank you in advance
tyler
There's no any default event, dispatching when rotation is completed. But I think of using callLater() function to copy back content. Try it.
that is exactly the point, there is not an event indicating the end of the rotation. the solution using callLater() instead of using setTimeout() appears to be an improvement however since waiting for a certain amount of time is always invloving some 'hope it works on machine x'. thank you very much for the hint !
greetings
tyler
I'm looking for information on how to move (and animate) 2D sprites across an isometric game world, but have their movement animated smoothly as the travel from tile to tile, as opposed to having them jump from the confines of one tile, to the confines of the next.
An example of this would be in the Transport Tycoon Game, where the trains and carriages are often half in one tile and half in the other.
Drawing the sprites in the right place isn't too difficult. The projection formula are:
screen_x = sprite_x - sprite_y
screen_y = (sprite_x + sprite_y) / 2 + sprite_z
sprite_x and sprite_y are fixed point values (or floating point if you want). Usually, the precision of the fixed point is the number of pixels on a tile - so if your tile graphic was 32x16 (a projected 32x32 square) you would have 5 bits of precision, i.e. 1/32th of a tile.
The really hard part is to sort the sprites into an order that renders correctly. If you use OpenGL for drawing, you can use a z-buffer to make this really easy. Using GDI, DirectX, etc, it is really hard. Transport Tycoon doesn't correctly render the sprites in all instances. The original Transport Tycoon had the most horrendous rendering engine you've ever seen. It implemented the three zoom levels are three instanciations of a massive masm macro. TT was written entirely in assembler. I know, because I ported it to the Mac many years ago (and did a cool version for the PS1 dev kit as well, it needed 6Mb though).
P.S. One of the small bungalow graphics in the game was based on the house Chris Sawyer was living in at the time. We were tempted to add a Ferrari parked in the driveway for the Mac version as that was the car he bought with the royalties.
Look up how to do linear interpolation (it's a pretty simple formula). You can then use this to parameterise the transition on a single [0, 1] range. You then simply have a state in your sprites to store the facts:
That they are moving
Start and end points
Start and end times (or start time and duration
and then each frame you can draw it in the correct position using an interpolation from the start point to the end point. Once you have exceeded the duration, the sprite then gets updated to be not-moving and positioned in the end point/tile.
Why are you thinking it'll jump from tile to tile? You can position your sprite at any x,y co-ordinate.
First create your background screen buffer and then place your sprites on top of it.