Two Guys Arguing

mario math – part 2

Posted in java, mario, math by youngnh on 08.14.09

To calculate Mario’s position with KEY_RIGHT pressed down continuously for n frames:

let a = 0.6

at frame 1:
\begin{align} & v_1 = a \\ & p_1 = a \end{align}

at frame 2:
\begin{align} & v_2 = a(.89) + a \\ & p_2 = a + [a(.89) + a] \end{align}

at frame 3:
\begin{align} & v_3 = (a(.89) + a).89 + a \\ & p_3 = a + [a(.89) + a] + [(a(.89) + a).89 + a] \end{align}

at frame 4:
\begin{align} & v_4 = ((a(.89) + a).89 + a).89 + a \\ & p_4 = a + [a(.89) + a] + [(a(.89) + a).89 + a] + [((a(.89) + a).89 + a).89 + a] \end{align}

If you multiply everything through, a pattern starts to emerge:
\begin{align} p_4 & = a + a(.89) + a + a(.89)^2 + a(.89) + a + a(.89)^3 + a(.89)^2 + a(.89) + a \\ & = 4a + 3a(.89) + 2a(.89)^2 + a(.89)^3 \end{align}

So we can say that in general, Mario’s position after n frames will be:
p_n = \sum_{i=0}^n(n-i)a(.89)^i

But we’d like a formula we can evaluate in O(1), so massaging the equation a bit we get:
\begin{align} p_n & = a * \sum_{i=0}^n(n-i)(.89)^i \\ & = a * \sum_{i=0}^n n(.89)^i - i(.89)^i \\  & = a \left ( \sum_{i=0}^n n(.89)^i - \sum_{i=0}^n i(.89)^i \right ) \\ & = a \left ( n * \sum_{i=0}^n n(.89)^i - \sum_{i=0}^n i(.89)^i \right ) \end{align}

Both of sums in the above equation, we have identities for:
\sum_{i=0}^n x^i = \frac{1-x^{n+1}}{1-x}       and       \sum_{i=0}^n i x^i= \frac{x}{(1-x^2)}(x^n(n(x-1)-1)+1)

Of which the second one is kind of convoluted, but allows us to come up with:
\begin{align} p_n & = a \left ( n * \frac{1-(.89)^{n+1}}{1-(.89)} - \frac{.89}{(1-(.89)^2)}((.89)^n(n(.89-1)-1)+1) \right ) \\ & = a \left ( n * \frac{1-(.89)^{n+1}}{.11} - \frac{(.89)^{n+1}(-.11n-1)+.89}{.2079} \right ) \end{align}

Which can then write in Java as:

public float positionAfter(float accel, int nFrames) {
    float term1 = n * (1 - Math.pow(.89, nFrames + 1)) / .11;
    float term2 = (Math.pow(.89, nFrames + 1) * (-.11 - 1) + .89) / .2079;
    return a * (term1 - term2);
}

The (.89) term is friction (I think?) and on the ground the code uses that value. In the air, the dynamics and equations are the same, but use a different coefficient of friction: (.85). The initial acceleration of a jump is vastly different, though, so I’ll tackle that in the next Mario Math installment.

Tagged with: , , ,
Follow

Get every new post delivered to your Inbox.