Placeholder Image

Subtitles section Play video

  • right, Let's look what we're doing this week.

  • No, no.

  • Hello.

  • Let's make Flappy Bird.

  • Flappy Bird is a game where you control a bird that flaps on.

  • People paid thousands of dollars to buy phones with this pre installed when they could no longer bite on the APP store.

  • These people are suckers.

  • There is nothing to this game.

  • You press a key, the bird flaps, and you have to avoid an obstacle.

  • It's difficult.

  • It's designed to be difficult on.

  • The idea is to get a high score you possibly can.

  • And invariably, the highest score is a pathetically measly number of digits.

  • Actually, component, we tell already.

  • I'm not good at this game.

  • I don't like this game, but I feel it's got some necessary points, which may be useful for other game developers.

  • And as usual, you'll need nothing other than a Windows command prompt in order to implement this rubbish.

  • But he's got some interesting points, which I think it worthwhile learning in particular.

  • How do we create a level that never ends?

  • We've got to keep presenting obstacles to the player on some rudimentary physics.

  • That bird does actually obey the laws of physics and is exploiting these physics and exploiting some quirks of human nature that makes the game very challenging.

  • As usual, I'm going to use the one lone code, a console game engine, and I've derived a class from it called Flappy Bird.

  • And we're going to override the music crater on user Update functions when I create an instance of the council.

  • Curiously, it's going to be lower resolution than normal, so chosen for it to be 80 characters wide by 48 characters high, and each character is 16 by 16 pixels.

  • This is a nod to one of my favorite YouTube is who's just got a display that works in this resolution, and I'm hoping that it'll implement this rubbish on his display now.

  • There isn't very much code for Flappy Bird, so I think it's useful to understand what the code should do before we start coding it.

  • We'll start with the flappy physics.

  • This is a bird on our birds.

  • Position is represented by an X and A Y coordinate.

  • If we differentiate with respect to time the position of the bird we get the X and D y, which is also velocity, and if we take the second derivative off the position I d Squared X and D squared y We have the acceleration and I've covered position, velocity and acceleration at great length in the much more interesting code it yourself asteroids video.

  • So I suggest you go and have a look at that.

  • If you're not familiar with these terms, we can simplify this further because our bird isn't actually going to move along the X direction.

  • It's only going to fall down due to gravity or get pushed up when the user presses the key because the bird flaps its wings so we can do away with the ex components and use single floating point scale of values to represent the white components.

  • So starting with acceleration, we can integrate back up the chain to work out the position of the bird.

  • On one acceleration force that's always being applied to the bird is gravity, which pulls the bird down on when the user presses the key.

  • Intermittently, we apply a little bit of acceleration, which is the flap, and this is in the opposite direction of gravity.

  • To pull the bird up, we restrict the bird to quite a complicated trajectory in that it has to be falling before you can flap the wings again.

  • And we know the bird is falling because the birds velocity will be positive.

  • And in fact, we want to emphasize this because the velocity becomes positive at about this point.

  • So it would be possible to have a trajectory which looks like this, which is no good.

  • It's too easy for the player to understand what's going up.

  • So instead we wait for the velocity to be positive and over a certain threshold.

  • And it's this discontinuity in trajectory, which is very difficult for our primate brains to understand and predict.

  • And that makes the game difficult.

  • As the bird has no physics in its ex direction, the world moves around the bird, and we want to create an infinitely long world for the player to try and fly through, avoiding obstacles.

  • And I'm going to borrow an idea that we used for the code it yourself Frogger game.

  • This rectangle represents the console viewing area on our bird is in a fixed position along the X axis is allowed to move up and down in the Y axis to stall the world.

  • I'm going to break the visible space into sections.

  • In this case, four sections can be seen on screen.

  • I'm going to have a hidden fifth section just off the screen.

  • Each section is going to hold a single value, which stores the height of an obstacle.

  • And for my simple implementation of flappy birds, the obstacles are really just a gate.

  • I only need to store the lower half of the obstacle because the upper half is always going to be the lower half, offset by a fixed amount to represent a portal.

  • I even have an obstacle ready for the off the screen section.

  • And as time progresses, I offset the starting points for each of the sections to give the impression that the bird is flying through the obstacles.

  • This, of course, moves the section off the screen on when the whole of the section is off the screen.

  • I remove it from the front of the list, create a new section and add it on to the back of the list.

  • And then I reset the section off.

  • Seth.

  • This technique means I need few resources to store a world that is infinitely large.

  • So let's start coding things up.

  • I'm going to have three floating point variables to represent the position, velocity and acceleration of the bird.

  • And I'm going to start by just making sure that we get the physics right.

  • So let's draw the bird onto the screen, calculate its offset in the ex direction is just being the width of the console, divided by three.

  • So it's always in the same place.

  • I'm just going to use the drawstring function provided by the game engine to draw the bird, and we can see it is too wide.

  • Character strings on different rose and I choose a different set of strings, depending on the birds.

  • Velocity, because if the birds velocity is positive, the bird is falling, so its wings are going to be up on.

  • When the birds velocity is negative, it's just flapped its wings.

  • It's moving up the screen.

  • You'll notice the birds aren't identical, and that's because I'm using the slash character as the escape character.

  • In this instance, the physics is quite simple.

  • To update the position, we integrate the velocity with respect to elapse time, and we need to update the velocity with respect to acceleration on the elapsed time, there's only two factors that effect acceleration on one of those is gravity I'm going to store.

  • This is a constant, and the acceleration is decided by whether the user has just pressed the space key for this frame.

  • So if they press the key, the bird is going to flap its wings.

  • Else the bird is going to fall due to gravity, and this is where we'll change the acceleration by the gravity constant.

  • With respect to elapse time, the physicist among you might be thinking, Well, hang on.

  • That's not quite right.

  • In this instance, F gravity is considered jerk or jolt, depending on where you film on, because we don't want the bird getting out of control.

  • I'm going to put in a hard constraint that if the birds acceleration is ever greater than gravity, because this is an accumulation off some force, then I'm going to cap it to be gravity.

  • However, when the bird flaps its wings, I'm going to set the acceleration to zero.

  • But I'm going to set the velocity directly to be a proportion off the gravity, and you can see I've included a minus.

  • Sign here to make sure that the velocity is going up the screen.

  • This, in effect, removes any falling due to gravity and artificially forces the bird in a upward thrust.

  • Before we do any drawing, I'll clear the screen.

  • Let's have a look how this feels so the bird falls and it accelerates its falls on.

  • As I smashed the space key, the bird flaps its wings and it increases its distance off the screen.

  • The downside is I can repeatedly press space and we could see the bird moves smoothly upwards.

  • This is too simple for the player, So let's make this more difficult by adding an additional clause that the space keep press is only valid when the birds velocity is greater than a proportion of the gravity falling down.

  • Now.

  • When I smashed the space key, we can see the bird has to fall a little bit before it continues on its upward journey.

  • Now we've dealt with the physics.

  • Let's deal with world.

  • I'm going to create two variables F section width, which just defines the width of the section in the floating point domain on a list off inter juice, which are the obstacle heights on.

  • I'm calling this list section in the unused create function, I'm going to initialize my list to all zeros.

  • This gives the player a bit of a chance at the start because there's no obstacles.

  • But it also allows me to set the F section width durable, depending on the size of how many elements air in that list.

  • And this means just by how we initialize this list, we can change the density of obstacles that the player has to avoid in order to give the appearance that the bird is moving smoothly through the level.

  • I'm going to cut the variable called level position, which stores the offset to the first section on just after our bird physics section.

  • I'm going to update this level position variable.

  • I've chosen the value 14 here because it seems about right for the speed.

  • If you increase this value, the level will move faster, and if you decrease it, it'll move slower.

  • And of course, this is with respect to every last time.

  • This allows us to make sure the algorithm will run on multiple computers, but all of the players face a consistent challenge.

  • We know we need to create a new section toe add to the list when the level position variable exceeds the section with variable.

  • So we'll test for that with an if statement.

  • And the first thing we'll do is we'll.

  • We don't want to set our level position back to zero, but we'll subtract from it the section with.

  • And that's because depending on the speed of the platform level position may have increased in a step size sufficient enough to make this reset look a little bit jerky.

  • At this point, the section at the front of the list will have gone off the left hand side of the screen, so I'm going to pop it from the front of the list.

  • We're done with it, then going to choose a random value to represent the size of the obstacle.

  • And I don't want my obstacles to be precisely on the zero row or the screen height row.

  • So I'm adding a minus 20 in here to make sure that there is always some obstacle on the screen, and then just to make it interesting for the player I'm going to test, for if the random number is less than or equal to 10 in this case, I'm going to set the height of the obstacle to zero, which means we won't draw an obstacle.

  • It all this will give an empty space for that section.

  • This allows the player to have a bit of a rest recuperate or get out of a particularly awkward trajectory, although it is completely random, which means there's no skeletal to this horrible game.

  • Once I've decided what the new sections obstacle should be added to the back off the list after we've cleared the screen is time to draw the sections.

  • I always use a little for Luke to do this, because all I need to do is automatically iterated through the list.

  • And if the value of that section in the list is not equal to zero, then we're going to draw it.

  • Otherwise, we're not remember there is going to be blank obstacles.

  • I'm going to need to know which section of the list I'm currently in.

  • So I'm going to create a temporal variable called End section, which are looked eight per reiteration.

  • And this is because I need to relate the lists current section position to a physical coordinate on the screen.

  • Given a section we need to see how we're going to draw it.

  • These are, of course, going to be filled in rectangles over green characters.

  • But that means we've got some sort of offset here, aunt here within the section.

  • We don't want to fill in the hole section because it'll be too difficult for the bird to fly through, and we need to have a gap for the bird to fall or rise in between.

  • And I'm going to start by drawing the bottom rectangle.

  • So I need the coordinator this point on the coordinates of this point.

  • So this is the code used to draw the bottom rectangle.

  • Let's see how it's constructed.

  • We take our current section on.

  • Multiply that by the section with so that will give us an offset into the console screen before we want to draw the green pipe, for example.

  • We also want have a little offset of 10 on this.

  • Make sure that the rectangle doesn't fill the whole section, and then we want to offset the whole thing by the current level position, and this will give the impression that the level is scrolling smoothly passed the bird.

  • The height is simply the height of the council, minus the value that was storing for the obstacle in the list.

  • The bottom right coordinate is much the same, except this time we just go to the screen height.

  • We're going all the way to the bottom.

  • But I'm using Sully characters that a green and to create the top rectangle in exactly the same way.

  • Except this time I'm drawing from the very top of the screen, and I'm drawing, too are stored value minus 15.

  • And that means that all of the portals, all of the gaps in between the obstacles will be 15 characters.

  • Hi, There's a lot of Constance in my code here, which could be variables, and they could change over time to change the challenge for the player.

  • But if you implement this, I'll let you play with those.

  • Let's see how this works.

  • So I've heard it's falling and here comes out first obstacle.

  • Now there's no collision detection at the moment, so the bird can simply fly through everything and we can see there's an empty space there, which was nice, and this time we're gonna run of three obstacles, four obstacles, and there's a gap in between each one.

  • I mentioned earlier that we could change the density of the challenge by changing the number of elements in this starting list.

  • So whoever increased it from 4 to 6 and when we run it now, we can see that the obstacles are much closer together, increasing the challenge considerably for the player.

  • I want to leave that back it fall because I think that's a reasonable challenge, right?

  • Thankfully, we're almost done.