Placeholder Image

Subtitles section Play video

  • Hello.

  • Let's make a simple title based platform game on as his customer like to start these videos by show you what we will be creating today and you'll notice that it's quite graphical today.

  • But that's the least important part of what will be working up.

  • Let me introduce to you, Jerry Oh, or Super Jerry.

  • Oh, he's definitely not in Italian plumber on, even though Jerry oh, obviously does not know how to run properly and floats all over the place, it has many similarities to his Italian counterpart on.

  • So the engine we're going to be working on today is a tile based and junior Cassie.

  • We can collect coins and things on.

  • It's really about how do we handle the collisions between the tiles in A in a sensible way?

  • And what I'd like to get out of the way right up front is this is not complicated at all.

  • In fact, we're not going to be looking at any physics or geometry into sections or anything like that.

  • It really does exploit A few little quirks are floating point numbers on to D it raise.

  • We'll also be looking at how the camera pans around the level so we could see here is we get towards the level boundaries.

  • Jerry Oh becomes off center from the screen, but the camera will follow Dario around as he moves around the level, just like we did in the Worms Game will also spend just a little bit of time talking about the dynamics of the character, getting the feel of the character correct.

  • So when he jumps, he jumps in a controllable, on responsive way.

  • But he doesn't sort of break all of the rules of physics, and this will encourage the player to develop a skill set in order to control Jerry Oh, properly.

  • Now you may have noticed the ominous number one at the end of this video title on DDE.

  • That doesn't imply, of course, that this is part of a greater Siri's and it will be, but not in the same way that the code it yourself worms games was a Siri's.

  • The reason being is I think platform games are an excellent vehicle for delivering all sorts of additional material about how to do other parts of the game, but this 1st 1 will be quite complete.

  • We will just talk about how we create tile based levels using a tile mapping strategy.

  • How we control the camera, how we control the player on how we handle the collisions between all of the above.

  • Let's get south it Now you may have noticed that all looks quite graphical on.

  • We'll make it look graphical towards the end of this video, but to start with where it's going to be drawing colored rectangles on screen on this is a simplification that I think is necessary to really understand what the engine is doing beneath.

  • As usual, I'll be demonstrating everything, using them one lone code, a console game engine, which you can download from the get hope.

  • The game engine is a simple class, which handles drawing to the screen and user inputs, and all we need to do is fill in these two methods on music create, which we can use to allocate resources.

  • Andan user update Where we do all of the fun stuff.

  • I'm creating an instance of my new class called Game on I'm creating a console which 160 characters wide by 120 characters.

  • Hi on each character is eight by eight pixels, but now When we talk about tile based games, we typically talk about a two dimensional array off something that represents a space, the two D arrays broken up into rows and columns.

  • As you can see here, I'm drawing them out to Syria.

  • 12345 On we fill a particular cell within the two D array with information that defines what we wanted that self.

  • So, for example, let's say I want a solid block here.

  • I'm going to use the hash symbol.

  • So here's a little platform off three solid blocks for empty space.

  • I don't want to use space.

  • I like to use the period character full stop, and that way I can count how many spaces I've gone across the screen.

  • And the nice thing here is that we know that all of the tiles lie on interview aligned boundaries.

  • So, for example, this point here would be 32 for two.

  • Make such a exacta on.

  • This implies that our tiles are one by one in size, and this is its unit less space.

  • But let's assume it's one unit that way on its one unit.

  • That way, working in a unitary space like this has lots of advantages.

  • Firstly, I don't need to store any of this geometry.

  • Everything is implied by its position in the array.

  • We can extract the location of where that tile is on.

  • We know its width and height.

  • Now let's say I take an arbitrary point.

  • Somewhere within the tile map, for example, I'm going to assume this one is about 2.43169 by 3.247 Clearly, this point is using some non into debates numbering format.

  • In fact, we'll probably be using the 32 bit floats Well, it's easy to work out which cell this point is in, because all we need to do is scratch out the fractional part.

  • And this is really nice, because we don't need a complex system of searches to work out where we are inside our tile map.

  • I think this approach is quite elegant, will be exploiting it for all aspects of our platform game.

  • For example, if I wanted to track a particle in and see if it collides at any point on the map, let's say it's moved to hear from one frame to the next, accessing that information is really trivial.

  • We just simply x and y into R two d array to extract whatever character is there.

  • So in this case of its equal to the hash symbol, a collision has occurred.

  • There are some caveats to this approach.

  • It does assume that each tile is a rectangle or square, and this boundaries are solid.

  • So if we wanted pixel perfect precision in our collision detection, we'd have to go one step deeper.

  • We're not going to do that in today's video.

  • So let's start by defining the level, and I'm going to represent my level as a string.

  • And I'm also going to store the wit on DTH e height off the level as in stitches.

  • I'll create the level in the on user, create function.

  • I'm going to declare the level for now to be 64 tiles wide, my 16 tiles high.

  • Don't forget a tile currently is unit lis, and the nice thing about using a string to represent your level is it can be quite graphical so that we've got 16 rose off level and I'm not created a to D array.

  • I'm just simply a pending it all to one big string now Designing the level can be quite fun using the insert key.

  • I can put in hashes wherever I need them.

  • Take that visual studio code and so I'm going to put in a ground plane.

  • So this is just a single plane going across the level that the character can't go below.

  • But in order to test collisions, we need to have some features in there.

  • So let's put in a small staircase of some description and you can see I'm being quite haphazard with this.

  • I'm not going into too much detail, but we don't want to design levels straightaway.

  • What we need is more of a playground that we can use to test the collision.

  • So I'm gonna put in a single block on its own on.

  • I'm also going to put in, Ah, a more complicated form here for the character to try and navigate.

  • And I always think it's useful to have some sort of tunnel as well, because this will really test the power of your collision detection routine and you'll notice that my tunnel is one cell wide.

  • And this is quite important because in some collision detection routines, you may find that things get stuck when the cells are just simply one space apart.

  • It's also quite important that we give an exit so that the player can get back out into the real world, so we'll just put that in, too.

  • Deciding which parts of the world we're going to be looking at requires a camera.

  • So let's add in a camera position X and Y variable.

  • And as the game progresses, the camera position is going to change, at which point we want to draw the level.

  • And it's during this drawer level phase that we give the world some scale.

  • We start to attribute size two things.

  • So to convert from my unitary tile map space into world space, I'm going to assume that each of my tiles are 16 by 16 pixels.

  • And this means that by using the screen width and screen height functions, I can work out how many tiles are visible on my screen on a computer display.

  • The top left is always 00 on.

  • We probably want the camera to represent the middle of the screen, so I'm going to create two more variables, which represents the offset from the middle of the screen to the top left, and this is simply taking our camera position and subtracting half the screens dimensions in both axes.

  • I go one the camera to disappear side of the level.

  • I wanted to stop when the camera position is close to the boundaries of the level, so I'm going to clamp it.

  • And in this case, if the new top left position goes less than zero, I fix it to zero, and I do the same for the other side.

  • But in this case, instead of checking for the level with, we're checking that the offset doesn't go beyond the level with minus the visible tiles on the screen for that access, because we want to display at least one whole screen on the screen.

  • Now we know where our camera is.

  • We want to draw tiles to the screen so we'll create two nested four loops for X and Y, and these are the same size as the number of visible tiles on the screen.

  • I feel at this point we're going to need a couple of little utility lambda functions and then to create one called Get Tile, which takes the X and y coordinate on returns the character in our string for that location.

  • But I'm going to do some boundary checking as well, because I don't want to get any invalid memory accesses, so we'll make sure it's in bounds in the Ex direction, and we'll also check the Y axis.

  • If it is within bounds, I'm going to return the character at that point in the string, simply by accessing the string is a single dimensional character ray using our good old favorite.

  • Why Times With plus X.

  • If we're not within bounds, I'm going to get it to return.

  • A space which represents our noble character is not quite the same as a full stop space, but perhaps we can use the space character to indicate an error has occurred.

  • Usually whenever there to get you also have an accompanying set.

  • So I'm going to create the same thing.

  • But to set a particular character within the two D location in the string, going back to our drawing routine, I can no extract a character from our string forgiven location.

  • I call it Tile, I d.

  • We'll use the Lambda function we just created on will pass into it the X on the Y coordinate and all we're going to do with this.

  • I d.

  • Is work out how to draw it.

  • So if it's a full stop, we probably want to draw some sky.

  • Come back to that in a minute.

  • If it's a hash symbol, we want to draw something that's solid.

  • And if it's anything else, we're just going to draw a black.

  • So if it is a period which represents nothing in our game, then I'm going to use the one Lakota Phil Command to draw a rectangle in that location.

  • So I'm taking the X and Y values, scaling it by the tile with and also taking the X and Y values plus one each and scaling those two.

  • Because we're going to be drawing a square from the top left to the bottom right of that rectangle on, I've chosen the color to be science.

  • Let's take exactly the same code for hash.

  • What I'll set the color to be read to indicate a solid surface.

  • You probably already thinking ahead that we can override these later on with spiked drawing routines, and we will let's now add in the ability to control the camera's position.

  • I'm going to add in something for the camera to follow, which will be a player.

  • So I'm going to create two variables Floating Point, which represents the position of a player on that we know for later on.

  • We're also going to need some velocity component as well to move the players position just before we draw.

  • I'm going to set the camera position to the player position.

  • You might think, Well, why we're doing this.

  • Why do we not just use the player position directly?

  • Well, the truth is, I don't know what we might want to do with the camera compared to what we want to do with the player, perhaps for a cut scene or something.

  • I want the camera to go somewhere else.

  • Perhaps I wanted to Georgia and shake around, but I don't want to change the place position in order to emulate this effect.

  • But for now, we'll just assume there's a 1 to 1 relationship between the two.

  • Handling input in the council game engine has always been quite simple, but I've made some modifications to make it even simpler on.

  • The first thing I've added isn't is focused flag, and this will check whether the command window actually is under focus.

  • Some of you may have been experimenting in the past and notice that when you typing things in a document, stuff is happening in your counsel game engine application.

  • You can still do that, but now you can filter out whether the window is highlighted and not by using this routine.

  • I'm going to aunt controls for the up, down, left and right directions.

  • We'll we'll add player physics in a bit.

  • But for now, I just want to test the collisions instead of using the M keys directly over Nice and tightly wrapped that up in a get key function.

  • So you just passed now which key you're interested in, and it works exactly the same as before.

  • It's just a little more consistent.

  • So if the player is pressing the key, I want to change my players.

  • Why Velocity?

  • And in this case I'm just going to set it to minus six.

  • Now you might think, wherever I got six from, well, these values I've tried and tested.

  • I don't want to show the experiments together in this video in a similar fashion.

  • Let's add in down, and I'll also cut and paste in for left and right.

  • But we'll make some changes.

  • They were working in the ex direction on for moving left.

  • We are going in the negative direction.

  • Change this to left, too, and for right, we're going in a positive direction.

  • What I will do for now is before any of this happens.

  • I'll send these velocity values 20 next time.

  • Why, and we'll use those velocity values to update the place position.

  • So the extraction becomes the ex direction plus the velocity times F elapsed time, which is the tolling between the last frame that was displayed on the screen.

  • And it's important to use every last time to smooth things out because we don't know how long it takes to update a single frame.

  • But we want the user experience to appear consistent after withdrawing the map.

  • We also they need to draw the player, and I'm using the Phil routine again to draw a green rectangle that represents the place position.

  • The main difference here, though, is you'll see that I'm subtracting hour offset position, which we calculated appear from the players current position, and this will neatly wrap up.

  • What happens when the player has approached the boundaries of the level.

  • So I've done that for both the X on the Y axis.

  • In contrast, when I'm getting the tile from the array, I want to add the officer.

  • So in this case, the offset is moving us further into the two D array, and in this case, the offset is pulling the player back into the screen, the viewable area.

  • So let's take a look and see what we're up to so you can see we've got the Scion background, which represents empty space, and I've got a green rectangle moving smoothly around representing the player with the arrow keys.

  • I can see a red rectangle and I can move around the level.

  • In fact, there's the level we can see.

  • We've decided on the string, so that should be a tunnel down here somewhere.

  • There it is.

  • We'll see.

  • Things aren't quite lining up yet.

  • Fair enough.

  • Fine.

  • We're not quite there.

  • But everything seems to stay wrapped around tile boundaries.

  • As in you can see, we've got this jerky movement.

  • We need to smooth out the map.

  • Moving around.

  • One final test is As the player approaches the edge of the level we can see he moves over to the side of the screen, not that impressive so far.

  • But let's see if we can make it a bit Tidier.

  • The first thing I want to change is the number of tiles that I've got on the screen.

  • But instead of changing the screen resolution for now, I'm just going to change this size off the tiles and everything that we made was adaptive and can accommodate that very nice.

  • The second problem we saw is that the background tiles only seem to move in interview values, and this is completely understandable because our X and Y location moves in.

  • Introduce.

  • We grab an interview tile from the array, and we're drawing out to interject clamped boundaries.

  • We had a similar problem with the code it yourself Frogger game, but in this case, what I'm going to do is calculate Cem offsets into the individual tiles toe, work out how much to displace them by when we draw them on the screen.

  • So let's see what this means.

  • We know that our map offset value in this case, F offset axe is continuous and can have decimal points quite legitimately.

  • After all, it just really tracks where the camera is.

  • This code here gives me the fractional part off the floating point number on because we know that we operate in unitary space.

  • This is very easy, then to map onto how much of a tile does that fractional component represent?

  • Because we simply multiply by the tile with So if we're up to 3.5 has an offset here, this becomes 0.5, and we know that we're half a tile into the offset.

  • I do this for both the X and Y axes.

  • Now that we know are tile offset.

  • We don't want to draw clamped to interview tile boundaries.

  • We want to apply the offset instead, too, when we draw the rectangles.

  • So in this case, I'm subtracting the offset from the X axis.

  • Do it again for the Y axis.

  • And with this Phil routine, you don't specify width and height you specified to absolute coordinates.

  • So we need to also add it to the next two parameters to make sure that so why?

  • And instead of typing all that out again, I'm just going to replace our solid block with same code unchanged the cooler to read.

  • So now we're drawing our rectangles.

  • Instead of being on interviewer line boundaries, they are interred your line boundaries, but also offset a little bit, depending on where the camera position it's.

  • So let's take a look.

  • As I move my green rectangle across the screen, we can now see we have reasonably smooth movement.

  • In fact, it's much smoother than it Waas, and it seems to work in both the X and Y axis.

  • The camera clamping is working nicely, but we can see it was the edges of the screen.

  • We've got information popping in and out.

  • She doesn't look quite right.

  • The boundary of the bottom seems a bit distorted on DTH.

  • E boundary on the right hand side doesn't seem very well, either.

  • Well, one way to approach this, and it's a little bit lazy is to simply overdraw everything that we need.

  • So instead of just drawing from the precise number of visible tiles, I'm going to draw to a plus one boundary of tiles around the visible screen.

  • So this has now got rid of all of the edge artifacts that we've just seen Right now, we have reasonable movements in camp control.

  • Let's handle what this video is really about.

  • That's the tile versus tile collisions.

  • Let's start by making some assumptions.

  • So here have the player character tile.

  • And in this case, he's one unit wide by one unit high, as evidenced by the coordinates in the Four Corners on.

  • We're going to make some assumptions, for example, everything in the map.

  • It's also a tile, so this time I will only be colliding with other tiles.

  • For example, we wrote have it colliding with some awkward shape.

  • And if this assumption is true, that means we only need to check the four boundary points off the player tile against the scenery tiles to see if there are any collisions.

  • We know the wheels have a velocity vector, associate it with the player tile.

  • We'll call this one of the axe and the wife, for example, so we can predict where the player will be on the next frame.

  • And in a typical collision detection routine.

  • This is exactly what you would do.

  • You would work out where the player potentially might be.

  • Check if there any collisions on resolve them.

  • However, treating the vector as a vector leads to some quite challenging problems to which there are no solutions.

  • Let me explain.

  • Let's assume that this top tile is my free moving player tile on that.

  • This tile is a static tile As part of the scenery, we've just updated the velocity vector on, then just updated the position vector, and it works out that we're going to be colliding with the diagonal corner off the scenery tile that's described by this image.

  • What is the correct course of action here?

  • Do we displace the player tile that way?

  • Do we displaced the play a tile that way?

  • Do we displace the player tile in both directions?

  • Some situations This may be more obvious than others.

  • Perhaps displacing by the minimum direction of overlap is a good strategy.

  • So we know how much.

  • Why has a CZ overlapped here and how much exes overlapped?

  • And perhaps, if D X in this case is less than D y, that's the minimum amount of movement.

  • So we choose to displace the player Sprite in the X axis, and this is also starting to bring in geometry on some real well, simple but still the mathematics, which I don't think we need to do.

  • In fact, I'm going to just exploit the fact that we can round floating point numbers to sort out our collision.

  • Let's go through this.

  • I'm going to create two new variables which our new player pas X on new player parts.

  • Why now?

  • You see why didn't add plus equals here before.

  • And so if unhindered, this is the location the player will end up in.

  • So at this point, we want to check the collision.

  • We've got some new positions.

  • I'm going to start with the X axis and I only need to check for collisions in the direction that I'm going in.

  • So if I'm moving to the left eye, either velocity is less than zero.

  • I want to do something.

  • Oils.

  • I want to do something else.

  • The players moving right on because my players a rectangle and I'm only doing sort of rectangle rectangle collisions.

  • I want to check two points on my rectangle, the top left on the bottom left.

  • In this case, the top left is given by the 00 coordinate relative to a player position.

  • But I also want to check for collision with the bottom left on, You may notice there's a whole lot of interesting things going on in this line.

  • This is one of those things.

  • It's easier for me to type it out first and then explain it in the event of either of those two points colliding.

  • What I'm going to do is set the expedition to be the requested position cast to an integer plus one.

  • We get rid of the fractional part and we add one to it.

  • I also going to stop the velocity.

  • So there are three things here which need a little bit of explanation.

  • Firstly, why are we using new player pas X on old player pass?

  • Why?

  • Secondly, why are we using the X coordinate zero and the y co ordinate 00.9 and thirdly, why are we casting to an interview?

  • Well, before we draw some more tiles, I'm just going to add in the code for when we're moving towards the right, which is very similar code.

  • Except our coordinate location is slightly different.

  • In this case, it's the opposite side so that it wants the new player position X in the event of colliding on the right hand side.

  • We still cast to an interview, but we don't add one to it.

  • Okay, Well, the first point there was Why are we using the new position X on the old position?

  • Why?

  • And that is simply to remove the Y component off my velocity vector.

  • So I really am only checking in one direction.

  • And this means has described before.

  • I technically can't ever have a diagonal intercept problem.

  • Well, I've got to choose between an X and Y axis all I'll ever have to sell exclusion problems.

  • So I'm retaining everything, just being in one axis, which is much simpler herself on.

  • If you do actually end up implementing things like conservation of momentum and stuff like that which were not for this video, this also makes things simpler too.

  • So 0.2 is when we're testing in the ex direction, why are we adding 0.9 to the Y instead of one?

  • Let me just fill these in so instead of out one that we're adding 0.9 on the same applies to that site.

  • Why are we doing this?

  • Surely this is untidy.

  • Well, let's consider a situation where I've got my spite tile of the player resting upon a scenery tile If the player is moving towards the left, I'm checking this point onto this point.

  • Don't forget all of our tile data is stored in a two D array.

  • So let's assume our P X on P Y values are equal to 3.2 comma five.

  • As I'm moving the character towards the left, I want to be checking these two points against my array, which would resolve to something like this.

  • So 3.2 five on without the 0.9.

  • Will we also be looking at 3.2 comma five plus one?

  • Well, of course, this 3.2 gets rounded down to three because of Ah, truncation.

  • That's fine.

  • That's great.

  • On this three represents which cell in the X axis are we in currently, However, for the white component of this map check.

  • We noticed that this actually trunk 8 to 6, which means our checkpoints are actually in two different cells in the Y axis.

  • But this is completely irrelevant because we're only checking in the X axis.

  • And in this situation, let's assume that this cell is indeed solid when this collision detection returns.

  • It'll return well, Yes, I'm in a solid cell on.

  • We've just checked that.

  • If either this point or this point are within a solid cell, then a collision has occurred.

  • But clearly in this scenario, it hasn't.

  • The player is walking across the surface.

  • So by adding 0.9 instead of 0.1, I mean, to be fair, this really public should be 0.99999 But it's okay.

  • Works out.

  • 0.9 is fine.

  • When this gets truncated instead of becoming six, it remains us five.

  • So we're making two points of check in the same cell.

  • So then your next question, maybe.

  • Well, why are we doing to checks?

  • Well, let's consider this situation where we've got a solid tile on the player is actually between two tiles, so he's not walking on the surface.

  • Perhaps they just jumped.

  • And we're checking for the ex direction along here.

  • So this point, the wise are separated, and this is an equally valid stop.

  • So in this in this situation, it may very well be that we're checking for two different why locations, but it's completely fair and valid.

  • So in effect, what we're doing is just shrinking the cell slightly so it doesn't get a false positive hit for the collision on will be changing which side of the cell we shrink, depending on which collision direction were checking for.

  • So the third point was, what's the deal with casting things to introduce?

  • Well, let's take this scenario where my player, Sprite, has collided with a solid tile in the ex direction.

  • We know that tiles lie on into dual line boundaries, so assume that wants for now wants five on somewhere.

  • We've got six in our extraction when we're checking for a collision along the left hand side will know that in this case P X may equal 4.8.

  • For example, it's overlap slightly into this four block.

  • We've already determined that a collision has happened.

  • So how do we correct?

  • Well, instead of calculating the 0.2 on displacing the player back along the X axis, it's very simple to truncate the floating point number.

  • Now you get rid of its fractional part, have one to it, and that gives us a precise boundary at where our player should sit that's moving left.

  • If we reverse the situation so just make this one a solid block on.

  • We know again that our players position is about 4.2 this time because it's overlapping into the fifth block along.

  • In order to align it to that boundary, we simply truncate.

  • We don't need to add one to it at all because we're moving right now.

  • We want it to clamp back towards the fourth boundary, and it goes without saying that all of these things that we're doing in the X axis applied to the Y axis.

  • So just to recap were using the new exposition on the old Y position to get rid of the Y component of the velocity vector.

  • We're checking with a plus 0.9 offset instead of a plus one offset to make sure that truncation doesn't catch is out.

  • And this will allow the character to fit in gaps that are only one units across and finally were using truncation again to align the player to a boundary in the event of a collision occurring.

  • I'm going to use very similar code now for the Y axis, except this time we don't want to separate the X and Y velocity component vector We have no resolved collision in X, so we're going to use the new exhibition and the new white position.

  • So that's handling velocity going book the screen.

  • I either lost his negative.

  • That's also handle velocity going down the screen.

  • Once you've handled the collision and we know that our collision detection routine has displaced the objects, we want to update the players position with the new player position.

  • So let's take a look.

  • Well, we can see now the green character cannot go below the red line, and we'll try against our single block trying to some diagonal collisions as well.

  • You see, it's quite robust against the single blocks.

  • Let's try it against the staircase.

  • That's fine, too.

  • Tries on all sides.

  • It's good to make sure that we come up with a proper testing ground for these things.

  • I want to fall into the gap.

  • There we go.

  • Did take a little bit of alignment to get right, but it's in there and we can follow the tunnel all the way around.

  • I'm trying to press different keys to make sure that the block doesn't get out of control.

  • We could say we can get back out again, lined up very nice.

  • So this is a really robust and pleasantly simple collision detection routine for a tile based game.

  • And I like it because we don't know geometry so far.

  • Now, let's have the fun stuff.

  • Well, the first thing our game is going to need is some gravity.

  • So I'm going to force some gravity by forcing the Y velocity to increase by certain amount, each frame.

  • And since we're going to be playing with velocities, I'm also going to clamp velocities to stop them becoming out of control.

  • So in this case, I want a maximum velocity of 10 in the Ex direction, minus 10 the other way around.

  • Answer for why 100 minus 100 now?

  • Because I want the character to accelerate in a particular direction instead of just fixing the velocity to a set amount.

  • I'm going to modify it in this case by F relapse time modulated by constant on.

  • If you familiar with some of the videos, you'll notice straight away that this is indeed a now acceleration.

  • I went to remove setting the Velocity X and Y components explicitly because now they're going to continue between frames.

  • Let's add in the ability for the character to jump.

  • He's going to jump on the space key, and it's when the key is pressed, not released or health.

  • So it's a single event, and I'm going to make a rather crude check that the player has no current y velocity.

  • I either not already jumping or they're not falling.

  • There is a small instance, maybe at the very top of a jump, you might be able to jump again.

  • But there's a way around that, and we'll see that later.

  • So in the case, off a player jumping, I am just going to physically force the Y velocity to be a set value.

  • I'm going to leave in the open down keys because it's useful, fantastic things, but functionally, they won't have anything to do with the game.

  • It will just be the left key, the right key on the space key to jump.

  • So let's take a look.

  • The characters fallen with gravity and he's been stopped by the collision detection routine.

  • I could make him jump with space key.

  • Hey accelerates very slowly and it doesn't feel as if everything is in ice physics.

  • It's all a bit slippy that said, Get him to full down.

  • This gap probably can't help.

  • There we go.

  • Yes, so we can, as long as he's going slow enough not to clip the other side to stop it.

  • Feeling is, if we're always floating around on ice, I'm going to have a flag which detects when the player is on the ground.

  • And we know when the players on the ground because there would have been a collision in the Y axis vertically.

  • So if that collision is true, I'm going to set this flag player on ground to true.

  • It's important that we remember to clear this flag before we do the test and just beneath well, we've put the code for emulating gravity.

  • I'm also going to put in some drag, so if the player is on the ground, I'm going to use a proportion off the current ex velocity toe work in the opposite direction of the current Ex velocity.

  • We're also going to check that if the velocity is near zero, it's actually clamp it to zero.

  • We want the player to be able to stop, so now I have the player on.

  • We're accelerating in the ex direction I let go and you see comes to a gradual stop.

  • It's a little bit more pleasing, however, when the players in the air the drag doesn't supply.

  • Speaking of which, I want the player to have some control whilst he is in the air, but I don't want them to have the same amount of control as when they're on the ground.

  • So I'm going to change this velocity vector component depending on the player on ground flag.

  • This allows me to have that Mario kind of feel that you've got lots of control, lost the players on the ground, and you've got a little bit of corrective control are you can slow the player down when he's in the air.

  • You can't make the player go back on himself, though.

  • I'm going to spend some time now turning the rectangles into imagery.

  • Hasn't we'll use some Sprite?

  • I'm also going to need to scale some of the velocities and the resolutions in order to make everything work well.

  • The original Nintendo entertainment system used to 56 by 2 40 pixels.

  • It's out.

  • I'm going to do the same and so I'll start by specifying the resolution for the council to be the same as the original Nintendo.

  • I don't think it's that necessary to talk through changing all of the rectangles into sprites because we've done that before in quite a few other videos.

  • So I'm just going to whiz through this quite quickly, right?

  • Just trust me.

  • There was nothing that interesting about any of the code that have just written, but now we can see we've got the character.

  • Now we've got the ability to jump because they have not quite set yet.

  • When he hits the ground, he doesn't stop jumping, But I've got a nice feel that the character is under control.

  • It's taken me a while to find the values, but it kind of works very nice.

  • Let's just see if we can make him put his legs down.

  • And the reason being when the player hits the ground, I need to tell it which row of the sprite sheet to use again.

  • And I'm using a variable ender mark X and ender mod y represent which Sprite off Mario to actually display.

  • Sorry, not marry a Jerry.

  • Oh, I have to get that right, Jerry of not marry a trial it again, so he jumps on Latin is very nice.

  • We'll add running, perhaps at a later Siri's of the video.

  • I'm I'm less bothered about Sprite animation stuff.

  • I've made a handful of changes in this case.

  • We can specify with a capital G, a ground tile on with the Capital B.

  • We can have some bricks and a question mark it clearly a question mark Block.

  • They don't do anything at the moment, but they look different.

  • You can't have a Mario game without some coins, so I'm going to use a lower case O to represent coins.

  • Firstly, let's just see if they draw properly.

  • Very nice.

  • But right now the coins behave like a solid object.

  • We want to check for pickup collection before we handle the collision, because we don't want the pickup to cause a collision.

  • If the player can actually pick it up.

  • So we take the new position X and Y on.

  • We're going to check the four corner boundaries, and in this case it will be plus zero on plus one, not 10.9, as it was before on doing this really, quite simply and naively, I'm just simply checking is that point a coin?

  • If it is, then set it to background space for now.

  • I'm not doing anything else.

  • I'm not increasing account or anything else.

  • This is just to show you that.

  • Yes, you can interact with the tiles that you hit.

  • Now we need to do that.

  • Check for all four corners.

  • Now, as the game increases its number of pickups, there'll probably be a much more elegant way to do this.

  • And we'll explore that in a later video.

  • But for now, I'm just setting the background tile to be equal to Skye.

  • Let's try that out.

  • He jumps up on, he can collect the coins, and so that's almost that will add one more little thing, though, and that is for the purists.

  • Currently, the council game engine uses the console US fonts, and I've chosen that because everybody has that front.

  • However, it's not always the best, and you may have noticed that in some of my videos there's a sort of a pixellated look.

  • Now I quite like that look, and that's why I keep it.

  • But there are some funds on your system you can choose.

  • You may not have this one, but that there will be something similar.

  • It might be worth trying a few different ones, which render it just like real pixels on.

  • This is where we start to see that the console really can be used as a complete game.

  • Engine in its own right might be a little limited on colors, but it certainly isn't limited on resolution on display on performance.

  • You'd be hard pressed to tell that this is, in fact, running in a command line, and so they have a very simple, tile based platform.

  • Game major.

  • I like the fact that it uses very simple tricks off computer numeric ce instead of relying on geometry to do the collisions.

  • I think this will be an interesting platform.

  • Excuse the Palm to move further on.

  • We're looking at how we do things in platform game.

  • So we've got enemy characters, add moving platforms, different types of pickups, game structure.

  • I can see this one developing into quite a few interesting videos.

  • Anyway, all of the source code is on.

  • Get hope as usual.

  • Please download it.

  • Hackett.

  • Have fun with it.

  • If you like this video, give me a big thumbs up it really does help with my self esteem on DDE.

  • Have a think about subscribing.

  • I'll see you next time Think.

Hello.

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it