TLDR: Check out the youtube video for a more in depth guide of implementing dynamic
collisions into our pong game.
The simplest form of dynamic collision for our paddle is to translate the contact point of the ball
and paddle into a range between positive and negative values.
To implement this you will need to understand basic vector math.
Vector Scaling
One technique of vector manipulation we will be doing is vector scaling.
All vector scaling does is increase or decrease the magnitude of our vector without affecting
rotation.
This is great as in some cases, we may need to only change the speed, not the rotation.
changeMagnitude(original: Vector2, scale: float) ->Vector2:
var v_scale: Vector2
v_scale.x = original.x * scale
v_scale.y = original.y * scale
# In gdscript, we can apply the scale to both x & y in one line of code# therefore omitting the variable v_scale# return original * scale # one line solutionreturn v_scale
Vector Rotation
The next technique we will be implementing is the vector rotation.
Vector rotation affects the direction of our vector without
It’s a liitle bit math heavy and in some game engines may need to be done in radians.
Regardless the code for vector rotation looks something like:
rotate_vector(original: Vector2, degrees: float):
var v_rotate: Vector2# new vector to return# game engines provide some method of changing degrees -> radians
radians = degrees_to_radians(degrees)
sin = sin_func(radians)
cos = cos_func(radians)
# simple formula of changing the direction of our vector# formula is based on the cartesian graph, not the game engines graph# this means that the y-value is reversed and needs to be flipped# the flipping of the value should be done outside this class
v_rotate.x = (original.x * cos) - (original.y * sin)
v_rotate.y = (original.x * sin) + (original.y * cos)
# outside this class and function# v_rotate_.y = -v_rotate.yreturn v_rotate
Keep in mind that the vector rotation formula is done in the cartesian graph, not the Godot Game Engines
graph.
If you do not flip the y-axis value, your ball will go in the opposite direction than intended.
Best to check out this video’s episode to see what I mean as I go over it thoroughly.
Transcript
Godot Tutorials is not sponsored by or affiliated with the game engine. Before I begin, I just want you to know that this episode's coding example will be uploaded to get up in the description link down below. So if you don't want to sit through this episode, feel free to check out the link to Github coding changes from the last episode. It will be under the folder pong-08.
Let's get straight into it.
The simplest form of dynamic collision that we can allow in our game for our player Paddle is translating the contact point of the ball and paddle into a range between positive and negative values for our speed vector on the Y axis where zero is the middle of the pedal. In this case, you need some basic math and it is OK if you are unable to get the math down. Most people find the mathematical formulas from Google in most cases, but the most important thing is trying to understand what the math is doing.
And with learning anything new, it's OK that you don't understand what it's doing in the beginning because at some point it will just click.
In this case, let's take a look at the warm up method in this case, we have four different points on our player panel that we use to detect the ball collision with the player pedal. But when it comes time to reacting, all we really need are the Y values along the single axis.
In this case, we have our range, which includes y one to Y two, and those values can be anything as long as Y one is less than Y two. And we do have a Y three value, which is the center of our pedal, which equals zero. And we have a ball which also has an X Y value. But for the ball we only care about the Y value. And that's because.
When the ball moves and makes contact with our paddle wherever it
lands, based on
where our paddle makes contact with the ball, we need to determine what direction it moves. For example, if we make direct contact with the center of our pedal, we would like to move straight.
And in this case,
if our contact points is closer to Y one, we would like to move at a high angle, at an
upwards direction.
And if our contact point is closer to Y two, we would
like our angle and
direction downwards
at a high angle and anything
in between center and Y to the angle goes downwards, but ever so slightly as we get closer to the center. And same thing for our contact point with y one the farther away from the center we are and closer to Y when we get the higher our angle is.
And from this contact point, wherever it lands between one and two, we would like to convert that into a new
range where, again,
the center of our range is zero and this is for our Y value in our vector speed.
And so to clean it up a little bit, this is what we have, we have a range from Y one to Y two, and we would like to convert that range into the values of Y four and Y five. On top of that r y three, wherever it lands in this range, also needs to be converted into our new range, which will be Y six.
Now, in this case, we are solving for why six and so let's plug in some values. Let's do this by hand.
So in this case, we
have a value why one equals one hundred y two, which equals to two hundred. So in this case, our panel is one hundred pixels long and it is one hundred pixels away from the top of the screen and ends two hundred pixels away from the top of the screen. And of course our ball made contact on the panel at the center, which has a value of one hundred fifty.
Now we would like
to convert this range into our new range where Y four is negative four hundred, which means that our ball is going up. Y five equals four hundred, which means that our bow is going down. And notice here that the length of our new range is eight hundred, but we don't know what y six is.
And so let's go
ahead and create that formula.
So first, we must get why one and why four to zero?
And you can think of this as sliding or range to zero while keeping the length the same. And so in this case for why one or range one, what we do is subtract everything by y one's value. So in this case, y one equals one hundred minus
positive, one
hundred y three equals one hundred and fifty minus positive. One hundred and Y two equals two hundred minus positive one hundred. And what this does is we slide our new range so that Y starts at zero. Now once we've gotten our new range to
start at the value
of zero while keeping the link the same. So length one is still one hundred. Now we need to get y four to zero while keeping the length. Eight hundred.
And so we do the same thing in this case,
except we
don't know why six is
yet. And so what we have
is why four equals negative four hundred minus negative four hundred, which turns this to zero and why five equals four hundred minus negative four hundred, which turns into eight hundred.
And so that's what we get here. So now that we have y one equals zero and Y four equals zero while keeping the links the same, now we can start trying to figure out what why six equals. And to do that or we have to do is expand our old range until it equals our new range. And so think of multiplication as growing or shrinking our numbers.
So in this
case, all we have to do is divide Y five by Y two. In this case, eight hundred divided by one hundred gives us eight. And then we take that eight value and multiply it every value in our old range. So zero times eight is zero, fifty times eight will be four
hundred and one
hundred times eight equals eight hundred.
So in this case, by multiplying, we are stretching our old paddle
range to give
us our new value for the speed on the y axis. And so you can see here why three is four hundred y, two is eight hundred. And it looks exactly the same as our new range. However, we are not done yet. Yes, y six equals Y three in this
case because we've converted
our old range into the new Range Rover. We need to get back to the original range that we had at the beginning, which was negative. Four hundred through positive. Four hundred.
And that's actually quite simple, all we have to do is subtract our old range by the original value of Y four, which was negative four hundred and in this case, zero plus negative four hundred, four hundred plus negative four hundred, eight hundred plus negative four hundred will give us the new range we wanted. And so in this case, when we do everything we get why three equals zero, therefore, why six equals zero.
And so when Y three was one hundred fifty between the ranges of one hundred and two hundred, that converts into zero on the range of negative four hundred and positive four hundred. Now when we plug in the zero for our vector speed on the Y axis, what we get is a ball
moving in a straight
line either left or right, depending on X's direction, positive or negative. And so if we plug everything we did earlier into a formula, what we get is why six equals Y three minus Y
one multiplied
by, linked to, divided by, linked one plus Y for. And of course if we get linked to and linked one, what that turns into his wife, five minus Y four and Y two minus Y one. And that is our simple range conversion formula. So in this formula you can see that we
need five
values. And so in this case we do have five values. First, we have the paddle, the paddle points, then we have the contact or both made with the paddle. And all we really need to do encode is have the values of our speed on the y axis. Now, in this case, what we have is a range conversion for controlling magnitude and direction, and this is the simplest solution to add dynamic collision reaction to our player pedal and the ball and the paddle and the ball as well. Now, keep in mind that having a range that
dictates the speed on
the y axis, we are both controlling the magnitude and direction of our ball. And so let's go ahead and take a look at an example here we have our Bowlsby vector and of course, when our ball makes contact with the paddle, we would like to flip the speed on the x axis and we would like to have our new range on the Y. And so in this case, if our ball hits the top portion of our player pedal based on our formula that we just created our range conversion formula in this case, let's pretend our speed is four hundred.
Now, in this
case, our movement on the Y axis is small
because our numbers
are small. So negative. Three hundred twenty. Now let's go ahead and change our range and you'll notice that when our range changes in this case, we doubled the range. Even when our ball hits the same part of our player
pedal, our
velocity in the Y axis
doubles. And so instead of
negative three hundred twenty, what we have is negative six hundred forty. And so just on the Y axis alone, we've doubled the speed along the Y axis.
And so in this
case, if our speed never changes value but our Y value grows and shrinks, then we are both changing the magnitude on the Y axis along with the direction of our speed vector, which is just basically a
velocity. Regardless, let's say our ball hits
the bottom of our player pedal. Notice that now our ball is moving downwards. And so this is the beauty of having a range conversion of our player pedal to some
value on the Y
axis for our ball speed.
And if we hit the center of our player pedal, notice that there is
no speed on the
Y axis because the value is zero.
Regardless, range
conversion is the simplest and most effective solution to our dynamic reaction for our player pedal and the ball, if you wanted dynamic collision reaction between ball and player pedal, converting the numbers or using a built in game engine specific function to convert ranges is the easiest
method. You have the
ability of converting different paddle sizes to different speeds on the y axis. That means that no matter how big or small your pedals are, the range it converts to will never change.
And in this
case, player skill is now involved when playing our game, despite our range conversion or min max conversion. Being the simplest and most effective method does come with negatives as is. The first negative would be that editing both our men and max values will increase or decrease both the rotation and magnitude. And that's because we tied our new range to the Y axis value for our ball speed value on the y axis. And so increasing that or decreasing that will change both the rotation and magnitude that our ball takes.
The second problem is that it's hard to visualize results again, because if you're zero on the Y axis but positive on the X axis, you're moving in a straight line
to the right. And if the X
axis is negative and Y is still zero, you're moving to the left. However, if you're moving four hundred pixels to
the right and four hundred
pixels up, then you are essentially going forty five degrees. But what happens if four hundred going up now becomes eight hundred going up. And so technically you'd be in between ninety degrees and forty five, whatever value that may be, which is probably around sixty six degrees. And so you can see that it's hard to visualize what our direction and magnitude looks like when we're just dealing with our ball speed vector value. And the less negative is that you have no real control over the direction or magnitude
separately from the ball
speed. And so you are reliant on controlling the ball speed vector values to determine direction and
magnitude and
changing our speed vector, which is just
velocity, has the
potential to change both the direction and magnitude to give us independent control over the rotation and magnitude. Separately, for the ball speed vector, we need to use vector. And so in this case, it's a slightly more complex process for changing direction and magnitude. However, the benefit is that we can control them
separately, independent
of each other. On top of that, this gives us the most control over reaction of the paddle and the ball. In my personal opinion, this is unnecessary complexity, considering we are making a simple pung game that will not utilize this feature of changing angles and changing magnitude.
But regardless, in the sense
that we want to add these features later in the future outside of this
series, this is perfect
for giving greater control of both rotation and magnitude for future power ups and penalties to our both speed and direction.
In this
case, the only two vector math we really need to understand is vector scaling and vector
rotation.
Vector scaling changes are magnitude only and does not change direction and vector rotation changes direction without changing our magnitude.
In a sense,
the math is quite simple. You may need just a little bit of knowledge when it comes to trigonometry. However, you can get away from copy and pasting whatever you find through online searching. The real complexity comes from translating the math into code to fit the needs of our game. So let's just go over the math now.
In my mind,
I'm thinking the following to keep things simple for the series. First, start the vector at a straight line with a base velocity, in this case. Four hundred on the x axis, zero on the Y. The next step will be to convert the range of our ball padel contact to a rotation value between positive ninety and negative ninety and apply that to our base line velocity, which is four hundred on the X, zero on the Y. Once we have this new vector value, we will then convert the range of the ball padel contact again to a scale range, in this case positive three and negative three.
However, we will be needing to use the absolute value to turn that into a positive, to make sure that our final value is on the positive X axis. Lastly, to determine whether we go left or right will depend on what the last or in this case the current X value was.
In this case,
was it going to the right or going to the left and apply that negative value onto the x axis of our value? And that will be the final direction and magnitude for our new ball vector speed.
And this case, let's
go over the vector scaling first. It's actually quite easy. Again, vector scaling increases or decreases magnitude without affecting rotation and all. We really need to. Do is take our original vector value, multiply our scale value on the X and Y axis
values, return that
back into a new vector value and then return the new vector value. And that's pretty much it
for scaling our vector. By doing this, we
are able to increase
magnitude or decrease
magnitude without changing direction because we are applying the scale value equally among the X and Y axis
values.
So remember, multiplication is growing or shrinking. Anything over one will grow anything under one and more than zero will shrink. And of course, of scale equals one. Nothing changes. Let's go ahead and take a quick look at Victor Skillings, so in this case, why three equals negative one hundred ten. When we apply the conversion formula, what we get is why six equals two point three and so are scaling value. In this
case, the maximum
amount we will want to scale our vector speed will be between zero and three. However, for our conversion formula, we need to have negative three and positive three. However, let's say our pedal hits up here, negative one hundred ninety, the complete opposite of negative. One hundred ten. Well, our white six equals negative two point three. However, when we make that value absolute, what we end up getting is positive. Two point three. And so whether we
hit on top or whether we
hit on bottom, notice that the closer we get to the edge of the pedal,
the closer
we want to apply the value three to whatever our speed value will be after rotation. And so, in a sense, if the player hits closer to zero, we don't want to apply a scaling value. However, the closer we are to the top or bottom, we want to reward the player and increase the speed to something faster. And of course, if we hit the center, even though this value will be zero, we need to make sure that in our code the zero value needs to be won.
And so anything less than one in our scale value needs to be won. Again, the reason we need a value of one is because if we multiply anything less than one in more than zero, anything between one and zero, we actually make our scaling smaller. And that's
not what I am
looking for right now. And if our value is zero, then our ball just is still because it's not moving in any direction or with any magnitude. And of course, we can use some if statements to make sure that our value is at least one. Now, the beauty of what we have is that we can change our magnitudes. So notice how it's three and three. If we wanted to, we could change this into ten, for example. So any value between zero and 10 to scale on our ball
vector and depending
on what your base speed is, maybe this is something you want and maybe it's something you do not want.
Now, let's take a look at vector rotation, which is slightly harder to implement
mathematically, but just slightly. Now, first, vector
rotation affects the direction without changing the magnitude. Now, keep in mind that our formula needs to be done in radians or an extra step of converting degrees to radians is needed. Now, in this case, we can do the same thing. Notice how down here y three equals negative one hundred, ten and over here you can see that we are going to use eighty nine
degrees and zero.
So basically anything between eighty nine degrees and zero will be applied to our ball speed value. In this case Y six equals negative seventy one point two, which is great because we would like our ball to go downwards. And so as you can see here, the closer we are to the bottom, the more angle or bull will have. And it's better if we just add the degree cymbal just to show that we are dealing with degrees and not just numbers or these numbers represent degrees. And of course, if we hit towards the top where y three equals negative one hundred ninety, this is positive seventy one point two degrees, which is upwards.
And as you can see here, the closer we get to the top of the paddle, the closer we are to wanting our ball
to change
to eighty nine degrees positive.
And if we hit the exact center of our pedal, we would like to apply zero degrees enterable, which means that our ball moves in a straight line because we are playing rotation to the base speed, which again is four hundred on the X axis and zero on the Y.
And the best part of this conversion formula is that we can change the values of our rotation, so instead of eighty nine degrees, we can change it to anywhere between 10
degrees and negative
10
degrees. And so just
by separating our magnitude and rotation, we can visualize better what our panel will do. So in this case, we're eighty nine degrees is basically a full 180 on the right side by having 10 degrees. We have a cone of a total of 20 degrees total. And so you can see that the more we increase the degrees, the more our paddle is able to move or change rotation. And so this is what I'm talking about. When it's easier to visualize the lower our degrees are the lower ranges for our degrees, the smaller our boat is able to move.
And so instead of eighty nine degrees, which is almost 90 moving like
this, what we get is
a ball that can either go straight or it can just go ever so
slightly. And so you can see
the value of separating magnitude and
rotation using
vector math. Now let's go ahead and see what we need to do for vector rotation. And it's actually quite simple. What we have is an original vector with an X and Y value and based on the amount of
degrees or in this case
theta, which we need to convert to radians, we can actually change the rotation of our vector without changing the magnitude. And the formula is on the screen. So our new rotated value on the x axis will equal to X original multiplied by cosine theta minus Y original multiplied by sine theta and our new Y value will be X original multiplied by sine theta plus Y original multiplied by cosine theta.
And that is how we are able to change, or in this case, rotate our original vector value to a
new rotated
vector value, keeping its magnitude. And over here I have a pseudocode of our vector rotation, and even though it's slightly more complicated, it's actually quite easy now that we're just converting our math formula into code. In this case, we take in an original vector value, we take in the degrees we wish to change, whether it's positive or negative. We create a new variable that holds our vector to value. We make sure to convert the degrees to radians and pass that into, in this case, a variable for radians. Then we have a signed variable, which we need to use a built in function to take in our ratings and convert that into a sign value.
So in this case, this would be our sine theta. We do the same thing with cosine, in this case cosine theta. And right here is where we rotate our original vector. And in this case it's the same thing we had in our previous slide. Take the original X, multiply it by cosine minus original on the Y, multiplied by sine and original X multiplied by sine plus original Y multiplied by cosine. Four are rotated Y value and then we return back the rotated value and that's basically it.