WEBVTT

00:00.120 --> 00:00.690
Hello again!

00:00.960 --> 00:05.400
In this video, we are going to look at how to make the ball interact with the bricks, in our game.

00:07.900 --> 00:11.630
The idea is this when the ball hits a brick, that brick

00:11.630 --> 00:17.440
will be destroyed. And the ball will bounce off the brick, at a physically credible-looking angle.

00:18.670 --> 00:22.300
So to do that, we are going to delete the brick object from the vector.

00:22.570 --> 00:26.260
You remember that the program has this vector of brick objects.

00:26.830 --> 00:31.420
And every time it displays the window, it goes through this vector and displays each brick.

00:32.050 --> 00:37.540
So if we delete a brick from the vector, then that brick can never be displayed again.

00:39.760 --> 00:43.300
To implement this, we need to make some changes to the entity hierarchy.

00:43.900 --> 00:47.470
We need to make the ball move down, as well as up and sideways.

00:47.980 --> 00:52.330
So we add a move_down() member function to the moving_entity class.

00:53.830 --> 00:57.770
We also need to know whether the brick has been destroyed.

00:57.790 --> 01:03.580
So we are going to add a member, to store that status. And also member functions, for accessing the

01:03.580 --> 01:04.100
status.

01:05.020 --> 01:11.410
And for reasons which I will explain in a moment, we need to be able to find the edges of the sprite.

01:14.690 --> 01:20.000
We have looked at handling collisions before, between the ball and the paddle, and that was fairly straightforward.

01:20.510 --> 01:25.220
We could assume that the board was only come from above the paddle, and we only cared if the ball hit

01:25.220 --> 01:29.030
the left side of the paddle, or the right side. With a brick,

01:29.040 --> 01:30.050
it is more complicated.

01:30.320 --> 01:37.970
The brick has four edges, and also the ball can come from any one of four different directions.

01:38.570 --> 01:43.790
The solution I am going to use is to look at the overlaps between the edges of the ball, and the edges

01:43.790 --> 01:44.540
of the brick.

01:45.470 --> 01:51.200
So, for example, we have an overlap between the left edge of the brick and the right edge of the ball.

01:52.220 --> 01:56.510
There is also the overlap between the left edge of the ball and the right edge of the brick.

01:57.440 --> 02:01.910
And this left overlap is much smaller than the right overlap.

02:02.510 --> 02:07.460
So this tells us that the ball hits the left edge of the brick, and not the right side.

02:07.970 --> 02:10.220
And we can use similar logic for the top and the bottom.

02:12.050 --> 02:14.570
So we need to calculate all these overlaps.

02:15.290 --> 02:22.400
The left overlap, the right overlap. The top overlap, from the top of the brick to the bottom edge

02:22.580 --> 02:29.450
of the ball. And the bottom overlap, from the top edge of the ball to the bottom edge of the brick.

02:32.670 --> 02:37.200
And then if the left overlap is less than the right overlap, we know the ball hit on the left. And

02:37.620 --> 02:38.460
so on, for the others.

02:39.840 --> 02:46.230
However, it is possible for the ball to hit two sides, if it comes in to one of the corners.

02:46.830 --> 02:52.200
So in this case, we look at the left/right overlap and the top/bottom overlap, and the left/right overlap

02:52.470 --> 02:53.250
is smaller.

02:53.670 --> 02:58.110
So we regard this as a hit on the left side, and not a hit on the bottom.

02:58.890 --> 03:01.950
So when the ball bounces, we expect the ball to go to the left.

03:06.230 --> 03:12.290
I have made a change to constants, which is just for this video. It is just to slow the ball down, so

03:12.290 --> 03:13.790
I can talk between collisions.

03:14.450 --> 03:19.130
You do not need to make this change in your own code. In the entity class,

03:19.140 --> 03:23.330
we have this member which will tell us if the brick has been destroyed.

03:24.890 --> 03:30.560
We have these helper functions for getting the edges of the sprite, and we also have the accessor

03:30.590 --> 03:31.850
functions for the status.

03:33.820 --> 03:35.650
In the entity implementation.

03:37.040 --> 03:39.680
We have the implementation of these member functions.

03:40.250 --> 03:45.980
So we get the bounding box. And then we go, from the centre of the box, to the edge that we want.

03:47.000 --> 03:53.570
Remember that I redefined the origin, so the origin returned by x() and y() is the centre of the bounding

03:53.570 --> 03:53.900
box.

03:54.680 --> 04:00.120
So if we go from the centre of the box and we move left, by half the width of the box, then we get

04:00.120 --> 04:01.490
to the left side of the box.

04:02.480 --> 04:06.960
If we start in the middle and move right by half the width of the box, then we get the right edge

04:06.960 --> 04:07.430
of the box.

04:08.270 --> 04:12.110
And if we move up by half the height, we get the top and so on.

04:14.180 --> 04:21.830
We need to implement this move_down() member function in the moving_entity objects. So that is ball and

04:21.890 --> 04:25.590
paddle. In ball, we just do the opposite of moving up.

04:25.610 --> 04:31.490
So instead of making the "y" member of velocity negative, we make it positive.

04:33.780 --> 04:37.780
And in paddle. The paddle, cannot move up and down.

04:37.800 --> 04:40.110
So these are both empty functions.

04:43.090 --> 04:44.380
In the interactions header,

04:44.380 --> 04:47.140
we need to add the overload for the ball and the brick.

04:47.890 --> 04:52.600
This can modify the brick object, so we just use a reference, and not a const reference.

04:54.430 --> 05:00.970
In the main function, we do the updates. And then we handle the collision between the ball and the paddle,

05:01.420 --> 05:06.850
and then we iterate over all the bricks. And we handle the collision between the ball and each brick.

05:07.750 --> 05:13.420
And we need to use a reference for the loop variable, because we want to modify the actual brick, and not

05:13.420 --> 05:14.590
a copy of the brick object.

05:15.610 --> 05:20.740
So if there are any collisions, then the brick objects in this vector will be marked as destroyed.

05:21.910 --> 05:27.650
And then we need to remove all these destroyed bricks from the vector. So we can call the remove_if()

05:27.650 --> 05:32.080
algorithm. We provide the begin() and end() for the vector

05:32.080 --> 05:36.940
as the iterators. And then we have a predicate which returns the destroyed status.

05:37.720 --> 05:43.930
So this will move all the destroyed bricks to the end of the vector, and it will return an iterator

05:43.930 --> 05:45.820
to the first destroyed brick.

05:46.510 --> 05:52.500
And then we can use the return value as the first iterator to a call to erase. And then we can pass end()

05:52.510 --> 05:53.740
as the second iterator.

05:54.220 --> 05:57.630
And that will actually delete the brick objects from that vector.

05:58.780 --> 06:03.100
So when we draw the window, the destroyed bricks will no longer appear.

06:05.630 --> 06:07.910
For the actual collision code.

06:08.600 --> 06:13.970
Again, we first check if there is a collision. And if there is no collision, then we return straightaway.

06:17.780 --> 06:23.690
If there is a collision, then we mark the brick as destroyed and then we calculate the overlaps.

06:24.080 --> 06:31.280
So the left overlap is from the right edge of the ball to the left edge of the brick. And the same for all

06:31.280 --> 06:31.700
the others.

06:33.080 --> 06:38.390
And if the left overlap is less than the right overlap, then we struck on the left, otherwise the

06:38.390 --> 06:40.460
right. And the same for top and bottom.

06:44.370 --> 06:51.720
And then, if we have an ambiguous case, if the overlap at the side is less than the overlap at the top

06:51.720 --> 06:54.840
or bottom, then we make the ball move to the side.

06:55.080 --> 06:59.940
So if the ball came from the left, we make it bounce to the left, otherwise it bounces to the right.

07:01.020 --> 07:07.800
If the top or bottom overlap is smaller, then the ball bounces upwards, if it came from the top, and

07:07.800 --> 07:09.950
it bounces downwards, if it came from the bottom.

07:12.750 --> 07:16.680
So here we are, with the ball moving at sixth of the normal speed.

07:17.340 --> 07:21.200
It looks like we are playing this on the moon! But it does give us time to see what is happening.

07:21.210 --> 07:21.780
So there we are.

07:21.780 --> 07:22.740
The ball came in here.

07:23.610 --> 07:24.720
So that was on the bottom.

07:26.960 --> 07:33.350
So it bounced downwards. The bottom overlap was the smallest, not the left or the right or the top.

07:34.070 --> 07:39.050
That one came in from the right, so it bounced to the right. And there were some others, which I missed,

07:39.050 --> 07:40.340
because I was too busy talking!

07:42.610 --> 07:43.840
And then down we go.

07:44.200 --> 07:44.890
And back.

07:46.390 --> 07:47.680
And where is this one going?

07:49.290 --> 07:49.830
So.

07:51.320 --> 07:53.870
That was over there.

07:53.870 --> 07:54.890
So that was on the bottom.

07:54.890 --> 07:55.760
So that bounced downwards

07:55.760 --> 07:56.150
again.

08:01.840 --> 08:02.320
And so on.

08:02.710 --> 08:02.980
Okay.

08:02.980 --> 08:03.850
I think you get the idea.

08:03.880 --> 08:05.260
So that is it for this video.

08:05.740 --> 08:06.580
I will see you next time.

08:06.790 --> 08:08.920
Until then, keep coding!
