WEBVTT

00:00.020 --> 00:05.930
All right, so now that we've learned all about inheritance, it's time to apply the theory to our snake

00:05.930 --> 00:06.380
game.

00:06.380 --> 00:10.070
And we're going to use it to detect collision with food.

00:10.280 --> 00:15.650
Our snake should be able to hit a piece of food, which is just going to be a blue circle.

00:15.650 --> 00:21.680
And every time it touches the food, the circle moves to a new random location on the screen.

00:22.160 --> 00:27.830
If we take a look at our code, you can see that the Main.py controls the entire game.

00:27.830 --> 00:32.810
It dictates how the screen should behave and how the snake behaves.

00:32.840 --> 00:39.680
Now, everything that's to do with the snake, its appearance and behavior is all captured inside a

00:39.680 --> 00:40.370
class.

00:40.370 --> 00:44.150
So everything snake related is inside the snake class.

00:44.150 --> 00:51.110
So what we want to be able to do is to create a new food.py file.

00:51.110 --> 00:55.520
And this foo.py is going to be its own class.

00:55.520 --> 01:02.310
And the food class is going to know how to render itself as a small circle on the screen, and then

01:02.310 --> 01:09.330
every time the snake touches the food, then that food is going to move to a new random location.

01:09.360 --> 01:13.530
So let's create the initializer for this food class.

01:13.650 --> 01:19.920
And one of the things that we're going to need to do is we're going to need to import turtle.

01:19.950 --> 01:24.150
So from the turtle module let's import the turtle class.

01:24.150 --> 01:31.020
And this piece of food that we're going to see on screen is going to be a turtle object.

01:31.050 --> 01:34.290
Instead of creating it as an attribute in this class.

01:34.290 --> 01:36.870
So self dot food equals turtle.

01:36.870 --> 01:37.770
Like this.

01:37.770 --> 01:45.000
What we want to be able to do is we actually want this class food to inherit from the turtle class.

01:45.000 --> 01:51.750
So that way this food class is going to have all of the capabilities of the turtle class, but it's

01:51.750 --> 01:57.750
also going to have some specific things that we're going to tell it how to do, so that it behaves like

01:57.750 --> 01:59.230
an actual piece of food.

01:59.230 --> 02:02.680
Here's a quick challenge from what you learned in the last lesson.

02:02.680 --> 02:07.720
Can you figure out how to make this food class inherit from the turtle class?

02:07.750 --> 02:09.760
Pause the video and give that a go.

02:12.700 --> 02:15.970
All right, so we mentioned that there's only two steps we need to do.

02:16.000 --> 02:22.270
First is after the name of the class, we add some parentheses and then put in the name of the class

02:22.270 --> 02:23.920
that we want to inherit from.

02:23.920 --> 02:26.260
So in this case it's the turtle class.

02:26.260 --> 02:34.060
And then the next thing we need to do is we need to call the turtles init method inside the food's init

02:34.060 --> 02:34.810
method.

02:34.810 --> 02:41.710
And you can see that as soon as you've added this inheritance here, this init starts giving us a warning.

02:41.740 --> 02:47.440
And when you click on it, you can see it says call to init of superclass is missed.

02:47.440 --> 02:49.960
So it actually knows what we need to do next.

02:49.960 --> 02:55.390
That means if we click on the light bulb, we can actually automatically just add in the Superclass's

02:55.390 --> 02:56.890
call this.

02:56.920 --> 03:00.080
Of course, you could just type it out and it's good for practice.

03:00.080 --> 03:05.900
But in case you're ever wondering if you get these warnings, you can always take a look at what PyCharm

03:05.900 --> 03:07.130
is recommending.

03:07.340 --> 03:13.400
Now we've actually created our food class and we've inherited from the turtle class.

03:13.400 --> 03:18.860
What that means is we can now start using things that are from the turtle class.

03:19.130 --> 03:24.560
For example, I can straight up say self dot shape and it knows what shape is.

03:24.590 --> 03:30.260
This is a method that the turtle class has that I'm now going to modify in my food class.

03:30.260 --> 03:36.380
So when I initialize a new piece of food, I'm going to make sure that it has a circular shape.

03:36.410 --> 03:41.030
And I'm also going to get it to pen up so that it doesn't draw.

03:41.060 --> 03:44.180
And then I'm going to define its size.

03:44.180 --> 03:47.450
And there's something called shape size which I can use.

03:47.480 --> 03:54.050
And what this allows me to do is to stretch the turtle along its length and along its width.

03:54.080 --> 03:56.940
Now I'm not actually going to stretch it bigger than it is.

03:56.970 --> 04:03.060
It's normally 20 by 20 pixels, but I want to turn it into ten by ten pixels.

04:03.060 --> 04:06.120
So I'm going to stretch the length by 0.5.

04:06.120 --> 04:07.950
So I'm basically going to halve it.

04:07.950 --> 04:11.430
And then I'm going to stretch the width also by 0.5.

04:11.460 --> 04:18.750
So now it should be a ten by ten circle which I've created by defining the shape size.

04:18.780 --> 04:24.570
Now remember all of these methods shape size pin up shape comes from this turtle superclass.

04:24.570 --> 04:29.580
And we're only able to use it because we're inheriting from the superclass.

04:29.580 --> 04:36.690
So that our food class is now also sort of a turtle, but it's more like a souped up turtle.

04:36.990 --> 04:41.820
Finally, let's go ahead and define the color, which I'm going to set as blue.

04:41.820 --> 04:44.790
But of course, feel free to set it as anything you like.

04:44.820 --> 04:50.460
And I'm also going to set the speed of my turtle to a fastest.

04:50.460 --> 04:56.230
This way I don't have to look at the animation of the food being created at the center of the screen

04:56.230 --> 04:59.230
and then moving to the location that I want it to.

04:59.440 --> 05:06.910
Speaking of moving, we're going to need to use the go to to get it to go to a random XY location.

05:06.910 --> 05:16.360
So let's import the random module and let's create a random x which is going to be random.randint.

05:17.050 --> 05:20.290
Remember that our screen is 600 by 600.

05:20.290 --> 05:24.850
So that means that our x axis goes from -300 to positive 300.

05:24.850 --> 05:29.680
And our y axis goes from positive 300 to -300.

05:29.710 --> 05:34.930
Now we don't want our food to be right at the edge of the screen, because it will be really hard to

05:34.930 --> 05:37.420
get the snake to go to right at the edge.

05:37.420 --> 05:39.580
It'll probably just die on the wall.

05:39.580 --> 05:46.630
So we want to maybe subtract this a little bit so we can go from -280 to plus 280 and the same on the

05:46.630 --> 05:47.680
y axis.

05:47.680 --> 05:53.950
So let's generate a random integer from -280 to positive 280.

05:53.960 --> 05:59.480
and let's generate a random y integer in the same range.

05:59.480 --> 06:05.840
So now we can tell our food to go to a random x and a random y.

06:05.870 --> 06:12.620
All of this is going to happen as soon as we create a new food object from the food class.

06:12.620 --> 06:20.390
Remember, whenever you initialize a new object from the class, the init gets called back in our Main.py

06:20.420 --> 06:23.180
right below where we initialized our snake.

06:23.180 --> 06:25.280
We're going to initialize our food.

06:25.280 --> 06:29.960
So food equals the food class and then parentheses.

06:29.960 --> 06:37.760
And of course we need to get hold of our food class from the food file like this.

06:38.000 --> 06:43.880
Another thing you'll notice is that this turtle is now grayed out, because we're not using that class

06:43.880 --> 06:45.950
anywhere inside the main.py.

06:45.980 --> 06:49.850
So we can delete that, which gets rid of all our warnings on this page.

06:49.850 --> 06:51.890
And we get the green check mark.

06:52.070 --> 06:54.200
Our food up high looks good.

06:54.230 --> 06:56.450
Our snake up high looks good.

06:56.450 --> 07:00.320
And we're now ready to go ahead and run this code.

07:00.470 --> 07:04.790
Notice how we've got our snake moving around on screen.

07:04.790 --> 07:10.400
And at this point it doesn't really matter about the walls, it's just moving around anywhere it likes.

07:10.400 --> 07:16.880
But more importantly, we've got our food being randomly generated on the screen right here.

07:16.970 --> 07:24.620
Now the next step is how can we detect when the snake and the food have come into contact, and then

07:24.620 --> 07:29.000
to tell the food to move itself to a new random location?

07:29.030 --> 07:36.200
Well, we're going to do that inside our main.py right after we've got our screen updating, our snake

07:36.200 --> 07:36.890
moving.

07:36.890 --> 07:42.620
Then we're going to detect collision with food.

07:42.650 --> 07:48.560
And we're going to do that by using a method from the turtle class called distance.

07:48.770 --> 07:56.010
The distance method works by comparing the distance from this turtle to whatever it is that you put

07:56.010 --> 07:58.050
inside the parentheses.

07:58.050 --> 08:06.270
So the x could be a pair of numbers x and y, or it could simply just be a turtle instance.

08:06.270 --> 08:10.170
So you're comparing this turtle against another turtle.

08:10.170 --> 08:13.830
And you're trying to get hold of the distance between the two turtles.

08:13.860 --> 08:21.780
So what that means is we can check to see if the distance from the first segment of the snake.

08:21.780 --> 08:27.210
So remember that would be snakehead dot distance.

08:27.750 --> 08:34.470
And then the distance that we want to know is what is the distance from the snake's head to the food.

08:34.740 --> 08:39.360
At this point you can check to see if it is less than a certain amount.

08:39.360 --> 08:44.940
Then it's pretty likely that the snake head is now colliding with the food.

08:44.940 --> 08:48.300
So we know that the food is ten by ten.

08:48.300 --> 08:55.600
So if we add a bit of a buffer, Let's just say if the snakehead is within 15 pixels of the food, or

08:55.600 --> 08:56.830
even closer.

08:56.830 --> 09:02.890
So if the distance is less than 15, then we can be pretty much certain that they've collided.

09:02.890 --> 09:05.170
So let's go ahead and print something.

09:05.290 --> 09:06.400
I'll just write nom.

09:06.430 --> 09:07.150
Nom nom.

09:07.150 --> 09:15.490
So if we go ahead and run our code and let's just get our snake back into view, and if I now go and

09:15.490 --> 09:20.470
touch this piece of food, if I can, then you can see.

09:20.500 --> 09:23.020
Nom nom nom being printed in the console.

09:23.050 --> 09:25.090
Now let's go ahead and touch it again.

09:25.090 --> 09:32.110
You can see as soon as I collide with that food I get that print statement executing.

09:33.310 --> 09:39.190
So now instead of just writing nom nom nom, let's figure out what we need to do next.

09:39.190 --> 09:45.100
What we want to happen is the food should go to a new random location.

09:45.100 --> 09:48.910
And of course that comes from this part of the code.

09:48.910 --> 09:54.500
So why don't we go ahead and create a new method which will call refresh.

09:54.530 --> 10:02.660
And this refresh method is going to create a new random x, a new random y, and then get the food to

10:02.690 --> 10:05.300
go to that new random location.

10:05.360 --> 10:10.970
Then inside our init we can simply just call self dot refresh.

10:11.090 --> 10:16.550
So be careful that you didn't write reset, because that's one of the methods from the turtle class

10:16.550 --> 10:17.960
that we're inheriting from.

10:17.960 --> 10:24.740
But what we actually want is to call this refresh method so that the food goes to a new random location,

10:24.740 --> 10:31.790
and then back inside our main.py when the snake head collides with the food, then we're going to get

10:31.790 --> 10:35.330
the food to refresh its own location.

10:35.330 --> 10:36.770
So check this out.

10:36.800 --> 10:48.300
Now when I hit the food, then you can see the food now appears at a new random location like that.

10:48.330 --> 10:55.470
Now, depending on how accurate you want the snake to hit the food, so it might need to hit it dead

10:55.470 --> 10:55.920
on.

10:55.920 --> 11:02.880
Or if you're happy with it just gliding past and counting that as a collision, then you could decrease

11:02.880 --> 11:06.270
the number here from 15 to 10.

11:06.300 --> 11:12.540
Now I've done a bit of testing, and this number seems to be the best distance in order to get a valid

11:12.540 --> 11:13.320
collision.

11:13.320 --> 11:17.250
But feel free to tweak around with the number and see how it goes.

11:17.280 --> 11:18.000
There we go.

11:18.030 --> 11:23.010
We've managed to figure out how to create a piece of food by inheriting from the turtle class.

11:23.040 --> 11:30.930
Get the food to be generated, and then to move to a new random location every time the snake head collides

11:30.930 --> 11:31.800
with the food.

11:32.100 --> 11:39.000
Now, I know that in the snake game, the snake segments increase once it hits a piece of food, but

11:39.000 --> 11:44.970
we're only going to add that functionality at the very end of this project when we're detecting collision

11:44.970 --> 11:47.940
with the snake tail, so don't worry about that for now.
