Placeholder Image

字幕列表 影片播放

  • 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.

  • We'll come back to that in a bit.

  • Then I'm going to want a nice, long straight section.

  • So again, zero curvature.

  • But this time it's going to be for 200 units.

  • Of course, units are meaningless in this.

  • Let's assume their meters.

  • After the long straight, I'm going to add in a sharp bend.

  • So here I've got a full curvature off one to the right, and again the length of this curve is going to be 200.

  • Let's go into a nice, long, straight again, this time twice as long as the previous one, and we'll have a sharp bend the opposite way going to throw in a chicane here.

  • So we've gone from minus one curvature for a short distance to plus one curvature for a short distance.

  • Now I've got a vector full of track sections.

  • I need to work out where I am on the track according to my car's distance and to do this, I'm going to track two more variables and we'd have offset.

  • I would have track section, which will be an interview representing the index of the vector.

  • I'm going to be lazy this time.

  • I'm just going to Witter, ate through the vector section by section, accumulating the distances on when the total distance is greater than my current car distance.

  • I noticed.

  • Stop.

  • I know which section I'm in, and I can work out how much my car is offset into the track.

  • Once I know this index, I can work out the target curvature for that section of track, and I can display that now on the screen displaying curve, actually, simply angling the track off at a particular radius.

  • It's a good job we have this middle point variable because all we need to do is change the middle point.

  • Depending on the perspective.

  • On the curvature of that section of the track, the rest of the drawing routines will update accordingly.

  • So let's start naively by just offsetting the middle point by the target curvature.

  • We know that on the straights, the target curvature zero so the middle point stays in the middle or we plus or minus one to it is necessary.

  • Let's see what happens now as we move forwards got straight section and we've got some wild curve inches to the right.

  • Another straight section.

  • Wildcard pictures of the left.

  • It's not very good, but we can see that we're going through track sections.

  • The problem here is our target coach goes indiscreet steps.

  • This can't happen, so we need to slowly inter plate between different target coaches to give us the impression that the road is turning left or right.

  • Because this is persistent.

  • Between update loots, I'm going to add a variable F curvature, which represents the curvature of the track at a given point in time to perform the linear interpellation.

  • I'm going to calculate the difference by subtracting the current curvature from the target.

  • Curvature are multiplying it by every elapsed time on going to update my F curvature with that difference, and instead of now using the target curvature variable, I'm just going to use the curvature variable.

  • Let's see how this works.

  • So I'm pressing the forward key and we can see there was a nice, smooth transition between the track sections.

  • Different curvature no, is that she came.

  • However, it clearly still doesn't look right.

  • And that's because our interpellation off the perspective is linear.

  • We shouldn't be the case.

  • Our roads need to look like the curved.

  • So I need to know factor into our middle point calculation, that perspective.

  • And I'm going to do this by multiplying to one minus perspective to the power of three.

  • Let's take a look because I go forward.

  • We can see it.

  • Ben's on what works.

  • Then we can see.

  • It continues to bend because the elapsed time is still ticking over on the game loop, even though the car's not moving forward.

  • So we'll address that in a minute.

  • We can see now that the curves smoothly move around.

  • And if we get to the next bend, what we're actually looking at here is the cubic function of the perspective, which I believe looks about right now.

  • We don't necessarily have to use the cubic we can use this the quadratic instead, but I feel that these Ben's don't feel quite right.

  • I guess it's a matter of personal taste.

  • I'm gonna stick it back to the Cuban.

  • We just saw them that even Though the car wasn't moving, the track was still moving around.

  • So we should address this by changing how much we inter plate the track by how fast the car is moving.

  • So if the car isn't moving, we don't do any interpellation.

  • It's time to add another variable, and this one is going to represent the current speed off the car.

  • We may as well take this opportunity to also add the feeling of acceleration and deceleration.

  • So if the key is held, we're no longer going to update the distance directly.

  • We're going to update the speed variable.

  • And if the key is released, we want in The Carter break were effectively emulating drag here, so I'm going thio, not make them the same.

  • This little dynamic may have some interesting game play later, and of course, instead of increasing, I'm going to decrease.

  • Once we start playing with variables like this, it's always good to make sure we remain in control of them, so I'm going to clamp them here so it's speed is always between zero and one.

  • After all, we don't want the car going backwards, but we still need to modify our distance variable so we'll do this here.

  • Andi, I've chosen a value 70 here on we can play with different values in a minute.

  • But this using our speed variable, which will between zero and one.

  • Um, we're using the elapsed time again, so this should give us the feeling of acceleration.

  • But because our speed is clamped between zero and one, we can effectively use it as a break for our curvature interpolation.

  • So in this calculation, here, I'm going to multiply by f speed.

  • So if our speed is zero, there is no change in the curvature displayed on the screen.

  • So I'm accelerating and I've let go of the button and we see we slowly come to a halt on.

  • We slowly pick up, speed goes round.

  • I'm gonna let the car stop and we can see that the trackers stopped inter plating.

  • At this point, I'm not implemented any steering, we'll come to that next.

  • So basically, I'm now driving like a camera around the track.

  • By now, you're probably thinking this is all very well and good, but we're not actually implemented any game yet.

  • All we can do is move around the track.

  • So how do we turn this into a game, and this is the bit where I said at the start of the video, we can actually make something really mundane into something fun just by how we present it on the screen.

  • So here is a track broken in two sections on As the car moves along the track.

  • Draw little car here.

  • That's the Commons along the track.

  • We want to follow the curvature of the track as best as possible.

  • So we're going to have to particles a blue particle controlled by the player on a green particle controlled by the track curvature.

  • So as we're going along, we're not accumulating any curvature along the straight section because it zero.

  • But as we go around the bend, our curvature has accumulated.

  • It remains the same for this straight section, but again it accumulates a bit more.

  • We should expect the player to do pretty much exactly the same thing.

  • So if the player is moving along the track and can achieve the same curvature as what is ideally specified by the track sections, then the players car will always remain in the middle of the track.

  • However, if the player starts to steer.

  • Let's, for example, say, on this straight section, the players curvature can change, and this will change the position of the car on the track horizontally.

  • Let's consider this from a slightly different perspective.

  • Let's assume, would play in a game where a path is being presented towards the player and the player has to press the left and right key to make sure that their point remains on that path as the path is moving towards them.

  • If the player can keep the point on that path, everything's great.

  • Good.

  • This is the same as our car being in the middle of the track.

  • But as the player struggles to keep the point on the path due to forces such as acceleration, the challenge becomes more difficult.

  • And ultimately, that could be a discrepancy between where the players particle actually is and where it should be.

  • And it's this discrepancy which we'll use to position the car horizontally on the track.

  • So we're going to accumulate two variables.

  • One is the tracks, curvature on the other is the player curvature.

  • And if we subtract the two, we get the horizontal composition and we can use our horizontal XK our position.

  • In fact, we can use the absolute all of it toe workout.

  • Are we still on the track, or have we drifted off the clipboards and onto the grass?

  • So if we take the absolute office on dhe check, so I'll say horizontal car position.

  • Absolute.

  • It's greater than will say a value for now.

  • No 0.8.

  • That means we're off the track.

  • So this line is where we accumulated the linearly interpolated curvature of the track.

  • So we'll use the same function to accumulate the track curvature.

  • So this variable represents the curvature of a single particle moving around the track.

  • We'll need another variable, which represents the player.

  • Curvature on this variable is controlled solely by the players inputs.

  • So if they used the left are okay, we want to steer left and likewise something similar for right.

  • And if the track curvature and the player curvature are different by a certain amount, we want to artificially slow down the car because this means they'll have gone off the track.

  • We might need to find, too, in this value, but I've used a higher deceleration rate here than normal, not just accelerating to make it feel as if that the grass is is grip here than the road.

  • We should now draw the car in a different place, depending on the discrepancy between the two.

  • Curve itches.

  • So we've got our F car position variable here.

  • So let's set that to something more useful.

  • In this case, it's just going to be the direct difference between the player curvature on the track curvature.

  • So if the player curvature has overestimated the overall track curvature, the car will drift towards the right.

  • On the other hand, if the player has underestimated the total curvature, the cowl drift towards the left.

  • So I confessed, left the car minutes left, and I confess right to the car moves right.

  • And that's because our curve itches are not the same.

  • In fact, let's display the courage is on the screen.

  • After drawing the car, I'm going to display a whole load of stats on the screen, so I've got the total distance around the track.

  • I've got the current curvature for the section of road being displayed.

  • I've got the player curvature.

  • I've got the player speed, and I've got the current track curvature now, given the high resolution of the console.

  • These may be difficult to see, but let's have a look.

  • So as I move the left key, I can see that my player curvature is decreasing.

  • So now it's no 0.5.

  • And of course, the cars moved to the left because the overall track curvature is zero, and I'm about 00.5 here, over to the right.

  • So when I specified the 0.8, that's about the we can see.

  • The cow is touching the grass and likewise minus 0.8 is about 30.

  • So keeping the symmetrical sets up from the staff has proven really advantageous.

  • It is allowed us to do collusion, checking on straights and cursed sections with relative ease.

  • Now let's see what happens when we drive the car forward and come to a bent.

  • I'm not going to steer the car.

  • We can see there's a discrepancy between the curve itches, and that's because the car has carried on going in a straight line, and this is exactly the behavior we want.

  • The car now drifts towards the outside of the bend, and it effectively gets stopped by the grass, so the player has to then keep the car moving in.

  • It also gives us this impression of inertia of the car going around the bend.

  • So if we're going too fast because we modulate our player position with speed, the player can't get around the bend, so they have to lift off the accelerator.

  • And this could be shown in this nice, long section here with a slight curve to it.

  • I have to keep correcting my horizontal position to get around the bend successfully.

  • It's actually quite challenging to get around the track without any incidents without any artificial slow down.

  • I want to stay on the track so I actually do have to follow the racing line.

  • At the moment, though, we have a dangerous element of our code.

  • If the total distance our player has moved is greater than the total distance provided by the track segments, then we're going to run out of vector elements to choose from.

  • This will crash to make sure this doesn't happen.

  • We want to assume that all of our tracks are actually loops, So if we take our current player distance on, we see if it's greater than the track distance, which will calculate in a minute, then We simply want to subtract from our player distance the track distance So the track distance is going to need to be another variable in our class, and we'll calculate that We're simply going through all of the elements in the vector and adding up the second part of the perp.

  • Easy with the auto keyword.

  • I need to implement some sort of indication that I've actually done a lap of the track.

  • Now.

  • I'm not going to go into putting furniture and start finish sort of checkerboard patterns.

  • That is actually quite complicated, and I believe that is an exercise along with putting other players on the track.

  • These are interesting challenges to do using this framework.

  • Basically, all I'm doing is rendering some geometry.

  • There is no way I and you know that might be an interesting challenge for another video.

  • Have a goatee cells to give the player visual indication that they have done a lap.

  • I'm going to flash the road white on.

  • I'm going to going to do this when the track section that's been selected by the distance is equal to zero.

  • It's a bit of a hack, So instead of just gray, we're going to use road color.

  • And the reason it's bit of a hack is because we did specify in one of our sections pushed into the vector a very short section.

  • So let's see what that looks like.

  • Now we can see the road is white and as we start driving, it's gone to the normal gray color.

  • And as we take this long curve along the back straight here, it should pull into a regular straight section.

  • And then we should cross the start finish line, and we did by seeing the road flash toe white there and we're looping back around again.

  • We need to indicate to the play that they're making progress, so we'll start recording some lap times will display the most recent five lap time so they can see whether they're getting worse or better.

  • Now, you might think I'm gonna go straight into the krone library to do lap times, but I'm not.

  • I don't like it, so I'm going to have a floating point variable cold current lap time on.

  • The nice thing about this approach is because thegame engine itself provides the difference.

  • In the elapsed time.

  • I could just accumulate this so here I've just accumulated the elapsed time into the current lap time.

  • Now we can also exploit this little error checking function before to tell us when we have done a lap.

  • Because, of course, if the distance is greater than the total track distance, we must have gone around the track at least once.

  • So when this statement is true, will use that to reset the current lap time.

  • We should draw this information on the players screen, but I just have a floating point filled with floating point seconds.

  • I'm going to create a little lambda function to help me out.

  • So the Lambda Function takes a floating point t parameter, which is the time in seconds, and it's going to return a W string, which is thestreet equivalent of that time in minutes, seconds and milliseconds.

  • So to calculate the number of minutes.

  • Of course, I just take tea on Divided by 60.

  • The fact that it gets cast to interview health is out here.

  • It gets rid of all of the crowd at the end of that remainder.

  • Once I know how many minutes I can subtract that from the time and calculate the number of seconds that left over and in the same way I can calculate the number of milliseconds.

  • But I need to multiply this by 1000 at the end because this will be 0.111 whatever, but we don't want to display 0.0 point 0111 So we're going to multiply by 1000 to give us.

  • Ah, nice number for displaying is a string and then with liberal use off the two W string function.

  • I can glue all of this together once I've got my little lamb to function.

  • Drawing the time to the screen is easy.

  • I could just use the drawstring command, which is part of the council game engines library drawing utilities.

  • There was a droid to a fixed position 10 columns in by eight rows down this time F current lap time.

  • Let's not forget, I want to store that most recent five lap times so the player can see if they're improving or not.

  • I'm just going to include a list off floats for this.

  • I'm going to initialize the list with 50 lap times, and the reason I'm choosing a list instead of a vector for this is I like the push from the front and pop from the back functions, So I'm just going to push the current last time.

  • This is our little lap checking function, remember?

  • So once we've done a lap, I'm going to push to the front of the list the current lap time, and I'm going to pop from the back of the list.

  • Whatever was there before, we should also display these times to the player on having our little Lambda function has made this much simpler now because all I need to do is create an auto too literate through the lap times, and I draw them all to the screen.

  • I got a little temporary variable J here because I want them to draw them line by line.

  • I need to increment that.

  • Let's have a look.

  • We can see in the top left that there is a time of accumulating the current lap time on just about to cross the finish line.

  • We see it popped it into the list, and it's been stored 53 seconds.

  • Well, that's because I was doing other things with cameras and microphones in between.

  • I guess you always need a hot lap to start with 34 seconds, much better.

  • So now we've got the fundamental mechanics of the game.

  • After the way, the only thing that strikes me left to do is we're only really drawing to half the screen.

  • So let's try and make the game look a little perfume.

  • Instead of filling the screen, and with all black, I'm going to draw the top half as two shades off blue.

  • This gives us the impression of some sorts of sky, but I want to draw some scenery in the background that moves in proportion to how the player is driving around the track.

  • The senior is not going to be very complicated.

  • In fact, all I'm going to do is use a sine wave.

  • But as we did with the lines going towards the player down here, I'm going to use the players curvature now to adjust the phase of this sine wave, and that will give the impression off the mountains, scrolling across horizontally in the background.

  • But in some way it'll be proportionate to what's actually happening in the foreground.

  • So my hill height here is simply a sine function, particularly low frequency sine function where X is just the screen with going across the screen.

  • Ah, that will give me, of course, the value between zero and one, which I multiplied by 16.

  • So I know that my highest mountain is going to be 60 and characters high, but I'm using the track curvature to offset the phase of this sine function.

  • The rest of the code here simply draws a line from the middle of the screen to the hill height.

  • So let's have a look how the mountains and sky go together.

  • So on the streets here we can see that Ah, the mountains don't move on.

  • If I move the player character, great, because we're not using the play curvature to calculate the mountains position.

  • But as the track goes around the bend, we can see the mountains move to, and they stop moving when we straighten out again, which is exactly the behavior we would want.

  • And when we go around the bend, the different direction they move the opposite way.

  • It's simple tricks like this that can create emotional, compelling gameplay experience.

  • Now the player doesn't really have to focus on the cast amongst the whole screen is giving them information about what's going up.

  • So we've got these periodic oscillator re functions, giving those lines, giving us perspective on.

  • We're using a very similar function to give us some horizontal movement.

  • There's only one more indicator we need to give to the player, and that is that they are actually pressing the left or right key.

  • But instead of just having a left or right arrow appear on the screen, I thought it would be nice to have the car trying to point in the direction that they're staring or especially can do without asking.

  • Anyway.

  • Scratch that best I can do without.

  • Actually, I've seen some brilliant asking out out there, and if anybody can do anything better, please let me know.

  • So I'm going to create a car direction variable, which is just simply set to plus one or minus one, depending on which key is pressed.

  • Press the left key.

  • It gets set to minus one, and if they press the right key, it gets set to plus one.

  • And so now, instead of choosing to draw a static car, I'm going to use a switch statement with three different cast sprites I just couldn't paste that in.

  • So if the cast turning right, we get the plus one.

  • It's angled slightly to the right.

  • Yes, it looks terrible.

  • I know my apologies.

  • This one looks even worse because of the escape character being part of the asking model.

  • Let's have a look.

  • So now we can see the car changes direction and it's a little bit more fun.

  • And so that's that's It's about 200 lines of code in total.

  • What I think is the essence of this video is how simple some of the functions and routines have been to give us quite a complex looking behavior.

  • For example, we've been able to give the illusion of moving forward just by choosing the correct mathematical function on the game itself is simply the difference between two numbers changing in time, and the player has to try and keep that difference as minimal as possible.

  • I just like how, when you present this information in a particular way, you can get a game out of it.

  • As always, all of the code is available on, gets up to download, have a look at the links below.

  • I've also noticed the recent surge in subscribers.

  • So I'd like to welcome all of the new people to the channel.

  • Please check out some of my other videos.

  • None of them need to be watched in any particular order.

  • If you've enjoyed this video, give me a big thumbs up.

  • Have a think about subscribing and I'll see you next time.

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

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

自己編寫代碼!復古街機賽車遊戲--從零開始編程 (快速簡單的C++) (Code-It-Yourself! Retro Arcade Racing Game - Programming from Scratch (Quick and Simple C++))

  • 3 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字