Placeholder Image

Subtitles section Play video

  • Hello, Let's make a retro arcade racing game.

  • So in the classic retro arcade style, we've got a car moving into the middle of the screen and we've got Ben's on the track on.

  • We can see how fast the car is moving because we've got lines scrolling towards a different speeds.

  • We can see the turning of the car because I've got very terrible sprites.

  • My apologies for the crudity of the model, the mountains in the background school around is necessary to give us the illusion that we're turning around the bends.

  • Andi, the objective of the game is to get around the track in the fastest possible time on.

  • There is actually some dynamics that affect this.

  • So if we go off the track, we slow the car down artificially.

  • And as I'm just about to cross the start, finish straight, we can see what lap time I clocked in this time was 42.8 seconds.

  • I'm sure we can do much better than that if I attempt to go too fast around the corner and pushed out to the side, so I have to use the accelerator quite carefully, like some of my other coded yourself videos.

  • This one looks like there's a lot going on, but actually there isn't.

  • And I think this is really what this video is about is we can take a really mundane, simple mathematical concept.

  • But if we present it in an interesting way, becomes a playable gay.

  • And as usual, we'll be doing all of this in the command from seances all asking about.

  • We don't need any third party libraries to get us going.

  • Asked for the current trend of my videos, I'm going to be using the one lone code, a console game engine which you can read about in the little Linka book.

  • The game engine is based class that we must inherit from and over right to methods on user create and on user update.

  • All this class does is wrap up the user input on displaying to the council, so I don't have to type it out for every single video.

  • All my in main function is going to do is create an instance of the class.

  • In this case, it's Formula One lone Koda, Please don't sue me if I on this time I'm creating a console which is 160 characters wide on 100 characters.

  • High on each character is going to be eight by eight pixels.

  • Let's start by getting some of the easiest stuff out of the way first, so I'm going to draw a track.

  • And, of course, this occupies the bottom half of the screen.

  • So I went to take the screen height and divided by two.

  • Then free dro.

  • I need to break up the row into whether it's, ah, grass clipping board all road, so each character going across the console we're going to classify as one of the other.

  • To make things a little simpler, I'm going to assume that the width of the screen is going to be a normal life Specs or zero for the left, on one for the right so the middle of the screen will be 10.5.

  • This is useful because we'll probably want to scale things up, depending on the size of screen, but it also makes some of the mathematics a little simpler later on, too.

  • So the first thing to establish when drawing the track is where is the track on the screen?

  • I'm going to assume we're drawing.

  • It's in the middle to begin with.

  • So that's a 0.5 in our normal life space.

  • I'm also for now going to assume that the road occupies about 60% of the screen, and so everything remains proportional.

  • I can assume that the clipboard with they're the red and white lines going around the track.

  • I'm going to assume that they're 15% of the road with.

  • And just to make the next section a little simpler, I'm going to assume that the road is symmetrical around its middle point.

  • So actually, I can have the road width and we'll see why this comes in handy now.

  • As we're retreating across the screen column by column, it's important to classify.

  • Each character is being grassed, clipping board or road.

  • So I need to work out where those boundaries are in the ex direction.

  • So, for example, I know that my grass begins at zero, but it will stop when we get to the middle point of the track, minus the road with which is no half on minus the clipping board with.

  • I can then scale that into the screen space for the council in a similar manner.

  • I can work out where my left clipping board is.

  • So it's exactly the same calculation.

  • But I don't need to include the clip width this time on because we have the road with before Doing the right inside is the same now, except we're doing pluses instead of minuses.

  • So we're exploiting the symmetry in order to make things simpler for us to do.

  • Now we just need to call them in.

  • So we know that if X is greater than zero on dhe exes left than our end left grass variable that we're going to shade that character green, and I'm going to use the drawer functions.

  • This is provided by the one lone Koda class, and all it does is take the X and Y coordinates, and we can use the solid character to basically fake a pixel on will use the constant F G green, the grass.

  • Some of you may have noticed that actually, why represents zero to screen height divided by two.

  • So that means we'll be drawing the top of the screen, which isn't what we want.

  • We want to be drawing in the bottom half of the screen, so I'm going to just cash here a little row position, which is that calculation already.

  • So instead of ah, drawing to this white corner, I'm going to draw to the row instead.

  • On that, make sure we're in the bottom half of the screen in a similar way.

  • We control the other types of road section, so the next thing to be drawn is the clipping board, and we're going to draw that using red pixels.

  • I'm not his type all of these out, but it goes without saying it looks the same for the other types of sections.

  • So in between the left clip and the right clip, we've got Road.

  • So I'm going to draw that in as Gray, and then we've got the right and clipping board.

  • So that's red again and finally going to the edge of the screen.

  • We've got more grass.

  • One final thing before we try This is to make sure that we raised the background first, So I'm just going to draw black empty spaces across the whole council screen.

  • Using the fill function, which is provided by the Gay mentioned not just deter rates through two loops until it's call it in all of the pixels.

  • Let's have a look what this looks like.

  • Well, we can see that we've got the bottom half of the screen cooler Didn't know and we've got grass clipping board and road clearly defined a sections.

  • The next thing, of course we're going to need is a car.

  • I'm going to add a variable to the class to store our car position on the track.

  • This time, I want the cart's position on the track to go from minus 12 plus one minus won't be on the left hand side.

  • M plus one will be on the right hand side.

  • That means zero will be dead center in the middle of the track.

  • So we need to do some scaling toe work out where that is in console space screen with divided by two will give us the middle off the track, and I want to offset from the middle of the track where we're going to put it in the car.

  • I'm also going to curiously ad because I've seen into the future, of course, a minus seven here, and I know that's going to be the width of the spite of the car.

  • So the middle off the spite of the car will align with zero.

  • On this way, when we draw the car, it's not going to be offset to the right.

  • So to draw the car, I'm calling the drawstring Alfa function here, which simply takes any space and doesn't draw it in the background.

  • So it pretends that that character is transparent and I'm going to draw the car in.

  • The exposition will be defined by En Chara.

  • Posit we've just worked out on the white position is going to be fixed on the screen, so let's take a quick look at this.

  • Brilliant.

  • We can see we've now got a car in the middle of the road, but something doesn't look quite right.

  • We're lacking perspective.

  • Perspective isn't as complicated as you might think to implement what we're going to do is take the current row and divide it by half of the screens That basically gives us a percentage on there, for the perspective tends toward zero when, why small and it tends towards one when wise large in a linear fashion.

  • The road with variable is what governs all of the other metrics used to define our road.

  • So if we modify the road with for any given row, everything else should adapt accordingly.

  • Now, if I just set the road with to be equal to the perspective, it probably wrote, Look very convincing.

  • Let's see, it does work, but our road disappears at the horizon and it takes up all of the screen at the bottom.

  • So we want to add some more sensible boundaries to this.

  • I wanted to be a minimum 10% off screen wit, so I'm going to throw that in his a constant Andi.

  • I'm not going to take 100% of the perspective.

  • I'm only going to take up to 80% off.

  • This means we have a road with going from 10% to 90% of the screen with Let's have a look.

  • Now that's a lot better.

  • We need to create the illusion of the car moving forward.

  • Of course, the car doesn't move forward in the screen.

  • What we do is change the scenery to give the illusion that the car is going forward.

  • I'm going to create another variable now, which represents the distance the car has traveled around the track.

  • I'm going to add in a little bit of user input to help was debug things.

  • So I'm going to make it that when we hold down the up key as a cold by this, if function here, the distance is increased proportionally according to a prolapse time.

  • If we remember from other videos, the computers don't run at the same speed.

  • So we need to take that into account when we're building a game engine to give the illusion of forward movement.

  • I want to draw some lines on the grass of different colors, but these lines appear to flow towards the player.

  • We also need to take into account perspective so I could just have lines that are all equally spaced apart and moved these towards the player.

  • However, this would lose the illusion off the perspective, which is bad.

  • Instead what I wanted in the distance, my lines to be very close together.

  • Unless they approached the player, they get further apart.

  • We can achieve this line positioning by using some simple maths here, using the Desmond Starcom platform, I'm graphing a sine wave, but it's a sine wave has been modified by two things.

  • Firstly, the ex direction represents the perspective on as we can see the as the ex gets larger like it does when we're drawing it, the peaks get further and further apart.

  • But I also need to take into account the face on the phase is going to be represented by the distance the cars moved around the track.

  • So by moving the slider and changing the face, we can see we get this nice transition.

  • So by using nothing but a periodic a solitary function, we can do all of this in one line.

  • So I got my sign here on here.

  • I've got my ex.

  • I'm taking the Cube off one minus the perspective here.

  • This is a bit of fine shooting and we'll find with this application that actually we do need to just hand tune some values sometimes to make it feel right.

  • The result of this sine function will, of course, be between minus one and plus one.

  • So I'm going to threshold it to tell me whether the pictures should be green or dark green.

  • And so now, instead of hard coding the value into the grass drawing routine here we use our variable instead.

  • Let's take a look.

  • That's quite nice.

  • We can see we've got narrow alternating light green and dark green colors where far away from us on, the bands get bigger and bigger as they approach the screen.

  • And if I hold down the button, our distance should increase, although at this point is doing it very slowly.

  • No matter we can go into the code.

  • Remember, this is input just for debugging.

  • Right now.

  • We'll change that to one hundred's.

  • There should be 10 times faster time another go.

  • Very nice.

  • We'll do exactly the same for the clipboards, but I want to use a higher frequency because I think the red and white boundary should be closer together.

  • So whereas without grass color, our frequency was dominated by this 20.

  • I'm going to use for the clipboard color eight.

  • So it should be a four times denser frequency.

  • I'm also into said, this time going to choose red on white collars, and we'll set this for both clipboards.

  • Take a look.

  • Very nice stuff.

  • Things looked like a racing game.

  • So how do we go about defining a track?

  • Well, in most modern games, of course, the track is a three D model, and it may be tempting to do something similar, for example, having a whole load of nodes on defining some properties between the nodes in three D space.

  • I propose we do something simpler than this.

  • I'm going to break the track up into discrete sections.

  • I'm going to label each section with curvature and distance.

  • And as the player moves around the track, we look how far we've traveled.

  • Accumulate the distance for all of the sections on work Out.

  • Which section there in and all we need to display on the screen is the tracks curvature.

  • The thing with this approach, though, is it allows us to create completely nonsense tracks.

  • But the play will never know that their nonsense, because you can only see the curvature for one section of track at any given time.

  • In fact, we don't even need to make the ends joined together, because we could simply loop around our list of segments back to the start.

  • To stall the track, I'm going to use a vector of pers where the first element of the perp is the curvature.

  • On the second is the distance on will create our track in the on user, create function, and we're creating a track is very simple.

  • So here I've added a straight section because the curvature is zero.

  • I was going to last for 10 units.

  • I'm going to use this.

  • Ask the start finish line, so just label this one separately.