# How to implement throw curve with virtual height in a 2D side-view game

I am working on a 2d side-view soccer game that looks like this image: But now I stuck on how to implement parabola pass ball. I have found many questions corresponding to my problem:

But they all just tell how to draw parabola in simple 2d space. In my game, except for the normal x,y there is also a virtual height coordinate, so the final viewing position of the ball is:

world position + current_height * Calc_Scale. (Calc_Scale is 0.3f)

Currently I did it the following way: I calculate the pass time(T) and distance(D) from point A to B

the pct = current_time / T
current_height = D * (4* pct - 4 * pct* pct)


UPDATE: @ashes999 I tried quadratic equation like current_height = D * (4* pct - 4 * pct* pct), it is not good(I am continuing to try different factors).I am pretty sure sin/cos can not work here, for example, player A is in(300, 200), B is(300, 800), the ball will make a direct line beyond B's head then drop to B's feet(or head), and this can not be done by cos/sin way, And I am thinking can this be done by some sort of projection, I just calculate the x,y,z then project z value into y axis?

void RSSoccerBall::Pass(const vector2d& target, double force)
{
vector2d DistVec(target - m_vPosition);
m_PassDistance = DistVec.getLength();
if(m_PassDistance > MaxShortPassDistance)
{
m_CurrentPassTime = 0.f;
m_PassTime = TimeToCoverDistance(target, m_vPosition, force, true);
}
}

{
//for parabola calc
if(m_CurrentPassTime < m_PassTime)
{
m_CurrentPassTime += dt;
float pct = m_CurrentPassTime / m_PassTime;

m_Height = m_PassDistance * 0.7 *  (4 * pct - 4 * pct * pct);
}
vector2d    exactViewPos = m_vPosition; //m_vPosition is the 2d world position
exactViewPos.y += m_Height;
//render football at exactViewPos;
...
}


@Mario, These are my code ,I have used an extra variable to store height. - Determing an object's position along a curve over time this is where the equation from

I do not want the top of the arc always to be at 50% distance traveled, because player A and B probably not in same Y value, if B's Y value is higher than A's Y, the top of the arc will be exceed 50%. I found a wiki link: - http://en.wikipedia.org/wiki/Range_of_a_projectile describe Ideal projectile motion on uneven ground, but the formulas are complicated for me to convert into current situation(we have start point, end point, start velocity, travel time)

Can anyone give me some pointers how to accomplish that?

• You can probably use a quadratic equation (y=x^2 ...) or sin/cos) to make it work. – ashes999 Aug 26 '13 at 8:50
• After rereading your update I'm no longer sure what exactly you're looking for. Do you have problems calculating the ball's flight path or do you have problems projecting your game to your screen? Either way it sounds like you're making things more complicated than they should be. – Mario Aug 26 '13 at 10:38

Your actual view of the ball or playing field shouldn't really matter in this.

• First of all, you'd mostly want a constant/fixed horizontal velocity for the ball. You can add air resistance to this, but it wouldn't really change anything, as you'll just have to add it to the equation.
• Ignore the actual height of the shot for now.
• Having a target distance as well as a velocity, it's rather trivial to calculate the travel time of the ball: t = d / v
• Now for making a nice arc you'll just have to set your initial vertical velocity right. You'll want the top of the arc to be at 50% distance travelled.
• To achieve this you'll need your gravity to completely negate that velocity once you arrive at half the distance. So for this you'll have to apply the max velocity the ball may achieve when falling down for the time it needs to travel there: vy = -g * 0.5 * t

Here's a simple jsFiddle showing you the overall idea. Note that the height of the arc depends on the time the ball needs to reach its target. Click anywhere in the playing field to kick the ball at that position. For a bit more accurate model (with friction), click here.

In case I haven't been clear enough:

• Behind the scenes your playing field should be a real 3D representation of the playing field.
• Only for drawing you collapse everything to the 2D representation that is shown on screen.
• This way you won't have to worry about any weird side effects, like doing complicated math, and you won't have to worry any fake height for your ball.
• Since the ball is the only element that can go into third dimension, you can simplify the whole game to be 2D (top-down playing field; only behind the scenes) and store your ball height in an extra variable.
• sorry for delayed reply, I know how to get vertical velocity but,I still have question projecting 3d position to 2d screen, as my screenshot , it uses Oblique projection, after we achieve the the ball height, how to project world X,Y,Z(ball height) into 2d screen?(now I simply add height directly to y value, and it looks fine) – Captain Sep 23 '13 at 9:12
• That's a perfectly valid approach - it really depends on the perspective you'd like to achieve. Probably the soccer game I've played the most in my childhood, Nintendo World Cup, used a simple transformation using something such as x_2D = x_3D; y_2D = y_3D + z_3D;, which is similar to what you do. If it looks odd, try creating a different angle, for example cut your y in half: y_2D = y_3D / 2 + z_3D; Overall this really requires some experimentation till you find the perspective that's fine for your game. – Mario Sep 23 '13 at 17:56
• If you'd like some perspective (e.g. like in the screenshot above), you'd simply modify the scene where you move the x coordinate towards the center of the screen the further away it is (y coordinate). – Mario Sep 23 '13 at 17:58
• Yeah, I still play Nintendo World Cup sometime, Great game.Thank you for your help me stop making simple thing complicated. – Captain Sep 24 '13 at 1:31