This video belongs to the openHPI course Programmieren lernen mit Python. Do you want to see more?
An error occurred while loading the video player, or it takes a long time to initialize. You can try clearing your browser cache. Please try again later and contact the helpdesk if the problem persists.
- 00:00Welcome to our final project.
- 00:02Today we want to continue the tradition of the eighties Program computer game Snake.
- 00:06A snake runs across the screen and tries to get a good result, to capture their food, in this case the red circle.
- 00:13Every time she has eaten a meal, she gets longer, so the goal is to become as long as possible.
- 00:18But you can also lose, exactly then, when you walk off the sidelines or whatever, when the snake runs inside itself.
- 00:26So that means when the black head runs into the yellow body.
- 00:29If you look at that, at first glance it looks very difficult.
- 00:32But we will program it piece by piece, and then the whole thing is very doable.
- 00:36To achieve this, we will define small building blocks step by step, that we're going to end up putting together.
- 00:41That means that after the lessons you always have small tasks for the Snake game and almost always programs parts of the whole game.
- 00:48Therefore there are no self-tests after the lessons.
- 00:51So we start first, by creating the first element for our game.
- 00:58For this we would like to represent the snake's head by a black square and again use the well-known turtle library for graphics.
- 01:07We will start right away by lifting the pen in line 6, to make sure that as soon as our snakehead moves, we don't draw a line behind us.
- 01:17So the whole thing looks like this: We have added a coordinate system to some of the explanations below, so that we can better respond to each step of the movement.
- 01:28So this coordinate system looks like this, and our coordinate system itself goes again from -200 to +200 in any orientation.
- 01:39Let's take a closer look at the whole thing.
- 01:41So we see that we are right in the middle, that means the center of our black square has the coordinate 0, 0.
- 01:49To the side, to the left and right, we can walk 10 steps, to really get to the edge of the nearest neighboring field.
- 01:57So that means that if we now want to move up one field, so you want to run into the field where the gray square is,
- 02:04we need to change the y-coordinate, so if we want to know the coordinate of the gray square.
- 02:12So let's look again, how exactly do the coordinates of that gray square look?
- 02:17Nothing changes on the x-axis, so also that grey square is like the black left and right surrounded by 10 and -10 ten and it stays that way.
- 02:25But on the y-axis something is changing, because we're going up on the y-axis.
- 02:30So that means our coordinate changes from 0 to 20, and so our final coordinate for the gray square is 0 and 20.
- 02:40Running is a good keyword here, let's take another look at how the movement works.
- 02:45If we start like we just did with the black square in the middle and move this to 0.20, then we'll see in the magnification
- 02:55that we have a continuous movement, so how to really walk the grid completely.
- 03:01But for the familiar look from the Snake classic it is desired, that we're practically jumping from one field to the next field,
- 03:09so that there's a quick movement and this is just not visible in single steps.
- 03:13For this purpose there is the function speed, this takes a value between 0 and 10, where 0 stands for the fastest possible animation.
- 03:23And if we set speed 0 before the goto call then we notice that the square actually jumps from one field to the next and we won't see that intermediate step again.
- 03:37So now we have seen, we have defined our snake head as follows, So, as we have already said, we have established a shape, a colour,
- 03:47lifted the pin before we walked to a spot and so we made sure that speed was set before.
- 03:53But now we want to add one more thing, which is a direction for the head.
- 03:59In Turtle there is the so-called direction for this, which we have now set to stop in this case.
- 04:05What we will do with it later will be explained to you when the time comes, first we set it to stop, which is, as I said, already so predefined, we'll discuss what to do with it later.
- 04:14We want to quiz them later, so to speak, but you'll see.
- 04:18Exactly, which means that so far we have defined this little black square, see this in the middle and have thus already defined our first building block, namely the one with the different graphics.
- 04:29And there we see, there's our snakehead.
- 04:32Next, of course, we still need the individual food, that we can just collect with the snake's head, so that we also become longer and the game is also fun.
- 04:41We use a red circle for example and you want to create it again in the same way, so make sure you do,
- 04:49that we move fast, pick up the pen and put it in the 0-100 position.
- 04:55But if we do the whole thing one by one and take a look at the intermediate results, for example after line 13,
- 05:04then we have created the red dot and also move it upwards with line 16.
- 05:10But we find that our black square, our snake's head, is no longer there.
- 05:16This is because all function calls that write like this can be executed on the same picture element.
- 05:25That means we either have a black square or the red circle, and it's very impractical for our game right now.
- 05:32So that's why we need the option, that we can represent two forms.
- 05:37Right. So we need more than one turtles, for this there is the function Turtle in Turtle.
- 05:42We have to make sure that the T is written in capital letters, we see the whole thing in line 3 and line 11.
- 05:48So we now create two different turtles by calling this function, eat the head once, eat that once.
- 05:55We can then use what we have called up there, simply really assign the different variable names
- 06:02and can then continue to do all kinds of things with the Turtle as normal and set different properties as before.
- 06:08We just have to be careful, that now we get through a dot notation just separate the different calls from the variable.
- 06:15We see, so we really need Turtle for every one, that we want in our game, a variable of its own.
- 06:20So we also see that we have solved our problem in the end, now we can really see our snake head and also the food and then act with both of them differently in the game.
- 06:32And so we have come to our first building block already added the second small piece, namely now the graphic for the food.
- 06:40Now let's take a look at how the controls work, because, after all, we want the snakehead to come to dinner, so we can grow.
- 06:48We use green triangles for this, that we want to move to the lower right corner of the image, so we can use it to map the controls.
- 06:57Creating a green triangle is quite simple.
- 07:01We did it here once for the right example, but the positioning is just not that easy.
- 07:06So our goal is to move them to the bottom right, but let's take a closer look at this place.
- 07:12Exactly, so if you zoom back in there now, we'll see, that we're back at grid 200, -200 on the lower right.
- 07:21Let's take a look at each other now, how exactly the triangle is defined for the right-hand movement.
- 07:26So here we see that on the x-axis we are surrounded by 170 and 190, therefore the green triangle to the right has the x-coordinate 180,
- 07:36and in the same way we can then determine that the y-coordinate of this triangle is -160.
- 07:42We can then add the whole thing to our code with the goto command, we see that now here in line 8, and in the same way we can then proceed for the lower triangle.
- 07:54The important thing here is that we add a twist, because we want to, that the triangle with the apex always points in exactly the same direction, who is later responsible for the control system.
- 08:05Therefore we turn the triangle downwards, i.e. 90 degrees to the right, and that's what we're doing here, so that it appears accordingly below.
- 08:15As you have already noticed, we do not need to give any direction here either, because this is only necessary for the snake's head.
- 08:22We have thus added the third element to the building block, namely the introduction of the control elements.
- 08:30Right, now we also want to see if any of the triangles have been clicked and if so, to what exactly,
- 08:38and for this we define the function interpret_input, which takes the two coordinates x and y.
- 08:44So we want to see if the coordinates of the mouse click really coincides with one of the centers of our triangles, which we have just defined and which we know as well.
- 08:55So let's first look at the downward movement again, there we see where the triangle is positioned.
- 09:02Thus, we can see here that the triangle lies within the range of 150 to 170. and this is exactly the range we want to intercept.
- 09:11So we want to make it possible for the user, that it doesn't have to hit the exact center just before the green triangle,
- 09:16but the entire area in which the triangle is located, if we go back to our cell pattern, our grid.
- 09:22Exactly, so we just query x >= 150 and x <= 170 here.
- 09:31It's the same for y and only, if all the conditions are true, so here's the and link, then let's move in that direction.
- 09:41In this case we want to call the function point_down_align, what this is all about, we'll get to that too.
- 09:47Do exactly the same for the triangle to the right, there we see again the coordinates we have defined for it,
- 09:54and that is exactly how it results in the different conditions for this very elif condition,
- 10:01and in the same way we can also call a certain function at this point, which we will discuss in a moment.
- 10:07And then there are other elif conditions for the various other triangles.
- 10:11At the end of all this we always want to call the function with the correct coordinates when the screen is clicked.
- 10:19For this there is the function onclick, so we are now passing a function to it.
- 10:24This is pretty new, we haven't done this before, but this is what it looks like.
- 10:29So you have to be careful about that, that you do not somehow pass on the round brackets or x and y nor extra onclick with, but you really just write the function name in it,
- 10:38and then onclick automatically passes on the screen when you click interpret_input the x- and y-coordinate of our function.
- 10:47Right. And thus we have defined our last or next building block, namely onclick (interpret_enter).
- 10:54But now we want to take another look at what this function to_down_align or even to_right_align actually does.
- 11:02Let's look at the case, that we'd like to align ourselves with the bottom.
- 11:06We determine here that the direction of the head should be evenly downward and in line 3,
- 11:14and to make sure we don't make a 180-degree turn, let's check line 2 first, that we're not about to run upstairs right now.
- 11:24Because we want that only if you go right or even left at the moment, that you then have the chance to orientate yourself downwards as well, because otherwise we would collide with our own bodies again later,
- 11:36that is, with the remaining segments, and that's what we're trying to avoid here.
- 11:40Just as we defined the function to_align_down, then the other three functions follow, so that we can orient ourselves in the respective direction.
- 11:50We pay attention here that we only have to align the head accordingly, because the other parts of the body will follow the head later and therefore need not be aligned.
- 12:01So for that we need the direction, which we defined at the very beginning.
- 12:07So now this is set correctly, and now we can just use it to move the head.
- 12:13We also define a function for ourselves, which has the same name, move your head,
- 12:17and I want to take a look first of all, what does it look like if we want to walk upside down right now?
- 12:23So we just put that one down.
- 12:25Then let's start by getting the current coordinate from the head, we can do that with the ycor function.
- 12:33We simply call them up again on our Turtle, separated by a dot and then get the y-coordinate back from the head.
- 12:41And then we want to take this coordinate and change it, depending on how we're about to walk.
- 12:46At the moment we want to run down, which means that we can see that here, that we want to change the y-coordinate by -20.
- 12:54This is what we use to create this down movement, so that means we take the y-value we just got and increment this one by 20.
- 13:05Of course we want to set the whole thing back to the y-coordinate of the head, and for this, as the name suggests, there is the function sety, so to set the y-value of the head evenly.
- 13:17We'll call him back to normal as you know it.
- 13:20And then we have actually already done everything we want to do, in order to be able to move the head when the direction is set to "down".
- 13:27In the same way you can then continue for the other directions, here for example for right.
- 13:32You'll have to be careful, that we no longer took the ycor and sety function, but did the whole thing with x, so xcor and setx
- 13:42and you didn't do -20, you did +20, because we want to move to the right on the x-axis.
- 13:50So we have to be a little careful with the other conditions, a minus must use a plus, and what kind of functions I really want to use.
- 13:58Right. And that's how we got... defines the next block again and we are done, namely move_head.
- 14:05Let's take a look at each other, what we've accomplished so far.
- 14:08In particular, we would like to move our snake head, so we can see that everything's working okay.
- 14:15And if we go back again to the function definition of interpret_input, then all we have here is the alignment
- 14:24downwards, to the right or even in the other directions and hasn't moved his head yet.
- 14:29That would be nice, though, if we were doing this right now, directly.
- 14:33Therefore we supplement, and only for in between, here in line 9 the call of move_head.
- 14:40So it's like this, if we can get into this building block from the call onclick and interpret_input
- 14:47in the meantime insert the new block move_head, to use this one, and then take it out later.
- 14:56And when we watch this on video, then we'll see that our movement is already working,
- 15:02we can call up the arrow keys can move our snake's head across the field,
- 15:08but so far not collecting the food or check that we collide with the edge because we haven't done that yet.
- 15:17But that is exactly what we want to look at later.
- 15:19Right. So, to recap, that we have defined various building blocks for our game.
- 15:25For one thing, a big building block, that summarizes the various graphics we see on the playing field.
- 15:31And on the other hand we have defined quite different functions, of which we are particularly interested in the calls onclick, interpret_input and just want to remember to move the head.
- 15:40And perhaps also briefly emphasized again, head_moving we have just inserted temporarily into interprete_input, but we want to take it out again later and use it individually.
- 15:51In the next video we will then go into that, how we handle the first collision.
To enable the transcript, please select a language in the video player settings menu.
About this video
Hinweis zur Richtung (direction) des Kopfes:
Die Variable direction
, die wir auf Folie 5 anlegen, ist eine ganz normale, lokale Variable vom Typ String, die nicht von der Turtle-Bibliothek bereit gestellt wird. Das haben wir im Video ungenau erklärt. Wir hätten dieser Variable folglich auch jeden anderen Namen geben können. Wenn wir kopf.direction = "stop"
schreiben, weisen wir der Turtle kopf
diese Variable dynamisch zu. Das bedeutet, dass kopf
nun die Variable direction
besitzt, mit der im Folgenden gearbeitet werden kann.