First, we need to update utils.js with functions for converting degrees to radians and back alongside with two functions for arrays operations.
We will use vectors heavily to update the state, so we need to have a few more methods in Vector class.
If you are not comfortable with basic vector operations, you can check this story covering basics with JS examples. In the examples below, you can see what other methods are doing.
Now we are ready to develop the core. At the start of the file, we declare a few more variables.
DISTANCE_IN_MS tells how far can ball and paddle go in one millisecond with speed equal to one. MOVEMENT object is like enum in other languages it helps to reduce the probability of making a typo.
After hitting an object like wall or paddle, we want the direction of the ball to be reflected with some added distortion to make the game more interesting. Distortion will add a small random vector to the direction and then normalize the result.
On every update, we will check if the player wanted to move the paddle, and in such case, we will calculate a new position. If it doesn’t cross left and right boundaries function will return new vector, otherwise it will return adjusted one.
Next, let’s write a small function that will be used for the ball — block collision detection.
It checks if at least one side of the object inside boundaries. For example, we can pass to it the top and bottom of the ball and block, to check if the lower or upper part of the ball inside of a block.
We want to escape the situation when the ball goes back and forth between walls since it makes the game boring.
This happens when the angle between normal of the wall and direction is close to 0 or 90 or -90 degrees. Right after calculating the new direction, we will adjust it.
Finally, we are ready to write a function that will create a new state. It receives old state, movement of the paddle, and timespan between last update and now.
4: // We calculate the distance that both ball and paddle went. Here we can see how the speed parameter affects the game. Then we call the function to get a new version of the paddle.
8: // To calculate a new ball position, we add a direction vector scaled by distance. Then if a player missed the ball, we call a function that returns initial paddle and ball.
19: // We declare a few functions by calling which we can return state with an updated ball.
40:// Then we check if a ball hits paddle or one of the wall. In such a case, we only need to pass the direction of normal to withNewBallDirection to return a new state with an updated ball and paddle.
51:// If the ball has a collision with one of the blocks, we return updated blocks and ball with direction bounced from one of the block sides.
Reach the next level of focus and productivity with increaser.org.