Sunday, 6 March 2016

Retronoid Update XIV

Ooh, time for another update methinks!

Despite a pretty busy week at work, decorating & a little Kerbal Space Program time to get back into shape for the 1.1 release - got some coding done.

Doesn't seem like much, but this week I've been focusing on adding ball spin to the game. Not having done such a thing before, I decided to go the "simple as I can" route and only aim to change the deflection angle on the ball when it hits the bat.

This presented a number of challenges:

  • getting the speed of the bat at the point of ball / bat collision
  • working out what direction to deflect the ball 
  • working out how much to deflect the ball by based on min / max bat speeds
  • applying the deflection change & amending based on certain limits

So, how did I do all this?

First off, getting the bat speed.
The bat itself actually moves at a constant speed - which makes it a little tricky. However, the bat doesn't necessarily move position in each game loop / cycle.
So what I did was to record difference in bat position between the previous & current cycles in a very small array covering 10 cycles (approx 0.17 of a second at 60 fps).
This gets reset if the player changes direction. At bat / ball collision using only the upper surface of the bat, I check what position in the array we are at, and work out an average speed based off the array values & position in it.
This also gives me bat direction (moving left gives a negative value, right a positive).

Working out deflection direction.
OK, now we have a bat speed to actually give us some spin momentum, how do we work out what way its going to deflect the ball?
If the bat is moving left it will apply clockwise spin on the ball, increasing the deflection angle.
If the bat is moving right it will apply anticlockwise spin on the ball, decreasing the deflection angle.
This applies regardless of whether the ball itself is moving left or right.

The ball is coming in at a heading of 135 degrees on screen (down / left at 45 degrees)
If the bat is stationary it will deflect at heading of 225 degrees (up / left at 45 degrees)
If the bat is moving however it will apply spin,changing the deflection heading by X amount (from 225 degrees to 265 degrees for example) - based on how much momentum we transfer from the bat to the ball & in what direction (clockwise or anticlockwise)

Working out how much to deflect the ball
Right, so we know have some momentum and we know what direction to apply it - next up is what limits do we apply on the change in angle, how much momentum do we convert to spin, and how does that change the angle.

First off, I needed to decide what my maximum allowed deflection range would be. This was pretty easy, and I settled on 35 degrees maximum change on either side of a 45 degree incoming ball angle. This means that if the ball comes in at 135 degrees (down / left), the bat is moving right (inducing anticlockwise spin) and spin is applied changing the angle downwards, the exit angle shouldn't go through the bat.

Next, how much momentum to use - I did a bit or reading but the physics sort of went over my head - so I winged it.
I started out by applying a 30% limit - so if the average speed of the bat at point of impact is less than 30% of its maximum speed - don't apply any change to deflection angle.
Then for every % over that initial value, apply a portion of a degree as a change in angle.
So, 30% of max speed equals no change, 100% of max speed would equal 35 degrees of change.
Given our maximum limit either way is 35 degrees, this works out at 35 (degrees) divided by 70 (%) - or 0.5 degrees for every 1% over the 30% limit.

Now its just a case of amending the deflection angle of the ball by that value, in the direction we worked out earlier.

The ball is coming in at a heading of 135 degrees on screen (down / left at 45 degrees)
If the bat is stationary it will deflect at heading of 225 degrees (up / left at 45 degrees)
The bat is moving left as well, applying upwards spin, increasing the angle of deflection
The bat is moving at 50% of its maximum speed - which gives a deflection angle change of 20 * 0.5, which equals 10 degrees. (50% - 30% limit = 20%, multiplied by 0.5 degrees per 1%)
This is applied as an increase in angle, so the new deflection angle would be 235 degrees.

Hang on though...
We still have a problem - if the ball comes in at a shallow angle it could still deflect through the bat. As we don't want this I applied minimum allowed deflection angles of 190 degrees if the ball is moving left, and 350 degrees if its moving right - amended after the angle change is made, but before the change itself is passed back to the ball object.

The ball is coming in at a heading of 160 degrees on screen (down / left at 45 degrees)
If the bat is stationary it will deflect at heading of  200 degrees (up / left at 45 degrees)
The bat is moving right, applying anticlockwise spin, at maximum speed
This gives a deflection angle change of 35 degrees (70*0.5), as a decrease in angle.
If this is applied it gives a deflection angle of 165 degrees - which would pass right through the bat - so we limit the change to 10 degrees, giving a new exit of 190 degrees (our limit).
This is just for gameplay purposes so it doesn't give us yet another issue to deal with.

In conclusion..
So as you can see, for something which looks simple on the face of it - actually pretty complicated. In testing these values actually seemed to work out about right for what I wanted to achieve though, which was nice.

Now, I could also use this and make a change to ball speed as well (actually considering it) using the 30% limit as my portion of spin momentum that affects speed, but that's for later on.

What Else Happened?
Finally, I also worked out on paper how I want the ball to appear at the start of the game / on reset when you lose a ball. Its a little 2 stage animation across 18 frames, with some particle effects. Fairly simple, but should look good enough.

I think that's enough for one week, time to launch a rocket or two..

No comments:

Post a Comment