Placeholder Image

字幕表 動画を再生する

  • Hello.

  • I'm gonna take a quick break from the role playing game, Siri's to have a look.

  • ATT programming pseudo three dimensional planes.

  • And this was a technique made popular by the Super Nintendo, and I'm going to use a super Mario Kart is an example where an image is taken as the ground plane and it is rotated and scaled and translated around the camera is necessary to give the impression over three dimensional environment.

  • This was known as Mode seven, which for the Super Nintendo was just really implementing an F fine transform in hardware.

  • I'm not going to be using African transformed directly because I want to play with some of the parameters and see what happens.

  • And so this is what we're going to be developing.

  • Of course, it's in the console now.

  • To those of a certain age, this may look very familiar.

  • This is indeed the first track, I believe from Super Mario Kart, and for those expecting another episode of the role playing game, you can see it's vaguely related.

  • We're using exactly this technology for the world map.

  • What I think is really needs about this program is that is it.

  • There's barely anything to it.

  • A toss.

  • There should be a nice, short, quick video showing something interesting we might be able to use in other games and technologies.

  • So as we usually do on this channel, let's take a quick look to just explore what it is that we're going to do and try and understand that some of the concepts and principles behind the algorithm I'm going to create a big ol sea sprite, and we know that these behaved just like textures on that we can sample from them.

  • Assuming that the top left is 00 on, the extremities are 1.0 on 1.0, and if you remember from the code it yourself first person shooters, this makes sampling the texture scale.

  • In variant.

  • I'm going to treat this big texture as if it were my world map or the Mario kart track.

  • In this case, in this map, I'm going to have a position which represents where the camera is.

  • I'm going to call this position World X on worldwide.

  • The camera will also have an angle associated with it.

  • We're in a two D plane here, so we don't need a three dimensional camera on will assume that the angle is what direction is the camera looking at in this plane?

  • From this information, I'm going to create a viewing frost.

  • Um, but I need a little bit more information first.

  • Firstly, I need a field of view and we'll call that feta.

  • I don't need two more pieces of information.

  • I need to know what is the nearest location to the camera on which is the furthest location from the camera.

  • And there's going to be lines that straddle are viewing first room.

  • Let's draw these in.

  • And if we were to continue drawing our camera vector, what we can see about these two lines is they are right angles.

  • So where the camera is looking?

  • This gives me four coordinates.

  • Oh, Pierre.

  • Here, here.

  • I'm here, and I'm going to use those coordinates to give me a region which I will be Sampley to display to the user.

  • And this is my first time.

  • Once we've got the first, um, we can now determine the mapping between what the player can see on the two d plane versus what they can see on this screen now in the council window we know that the Y axis goes in this direction on the X axis goes in this direction.

  • Well, that maps on to our first, um too.

  • So the furthest away, why location is going to be towards the top of the command prompt window, which means this becomes out.

  • Why access and this becomes our X axis will notice that the X axis changes length depending on where it is in the Y axis when we're far away.

  • We're looking at a lot more ex than we are when we're close to it.

  • This means we can take any X Y coordinates in the command prompt window workout where it lies inside our first, um, and that becomes the sampled point that we will display on the screen.

  • It would appear that there's quite a degree of interpellation happening on the race, so I'm going to put some naming conventions in so we can follow the code.

  • This point up here is going to be known as far X one on why one this one down here is going to be known as near X one on why one this one is far X two, and why, too, and This one is near X two on Whitey.

  • When we extract a pixel location from the console screen, we will be normalizing it versus the screen with and screen height so well, getting in a value between zero and one.

  • Let's say our pixels location, axe, and why is no 0.5 by no 0.5?

  • That means we want to select somewhere in the middle of our first room.

  • But how do we know where the middle is on a shape like this?

  • Well, we know that the Y coordinate is going to be reasonably consistent for now.

  • Those who are thinking ahead we'll come back to that later.

  • No 0.5 will be somewhere halfway along the line between near and far.

  • And because we know the vector between far X one and near X one on the vector between farts too, and near x two, we can work out where those two points are.

  • And once you've got those two points, we create a new line.

  • I'm going to go see the middle.

  • So I'll just flag that in normalized space.

  • This is halfway along and then, of course, because we've got this line we can do exactly the same to this new line toe workout, the X location, which is halfway across this new line, which withdrawn in already it's there.

  • And so, by using this approach, we can specify any coordinates between zero and one and work out where it lies.

  • Within this shape, let's just do it.

  • A second example.

  • Just to make sure that let's assume that instead of no 0.5, we've got no 0.25 by no 0.75 So in this instance we would go 3/4 of the way a longer line linearly no 0.75 They're on about there on the same.

  • Create a new line between those two points, and it says we're no 0.25 along the X axis.

  • Well, we know that the middle is about thirst of not 0.25 Must be about they're.

  • So this becomes our sampling point Now.

  • You may have noticed that I subtly hinted something's not quite right with this approach, but we'll come back to that when we start writing some code.

  • So let's get started with the code.

  • I've already created a subclass called one lone code, a fake mod seven on I've created a main function which creates an instance of this class constructing the consul to be 3 20 wide by 2 40 High on each character is going to be four by four pixels.

  • Note that this is quite a high resolution on indeed, may not work on certain screens.

  • If you're not using a 10 80 p screen, it's not going to fit on that desktops.

  • You'll have to use a smaller console size.

  • Well, let's start by adding the very basics I know I'm going to need a Sprite that represents the ground later will show how to load the Sprite.

  • But to begin with, I'm going to create it Algorithmic Lee, because I wanted to be a sprite of lines so we can see.

  • How does the three D effects start to distort what the user can see on On the whole, I know that my map is going to be square on both sides are going to be 1024 so it's going to be like a one megapixel texture, quite a big thing for the console game engine.

  • So in the on user create function, I'm going to create it.

  • And here we go.

  • I've defined it as being a square sprite of size, map size by map size.

  • I want to populate this map by hand somewhere to create two nested four loops to draw lines going from one side of the map to the other in both the accent.

  • Why directions?

  • And I wanted to leave a gap off 32 pixels between each line for the opposing access.

  • I want to draw in every single pixel, so we skip by one pixel at a time.

  • Now, even though I've used the naming conventions X and why here?

  • I can actually both draw both the horizontal and vertical lines at the same time, and that's because the map will be reflected along the X Y axis.

  • It's fine, and sprites have accessing methods, so we can actually set the content of the Sprite manually.

  • So I'm going to set the color of that location to be magenta.

  • I'm going to send to the pixel type at that location to be the solid pixel.

  • In fact, I'm going to do exactly the same for the neighboring pixels because this will give the line some thickness, so this will be drawing lines in the Y axis.

  • We can simply flip the coordinates to draw lines in the X axis.

  • So these two nested four looks work to create a grid like pattern of magenta lines of one access on blue lines in the other.

  • Everything else we want to worry about is in on user update.

  • I'm going to have some variables that represent where the player is in the world X y and angle in radiance.

  • I will also need some variables that represent the first, um, I'm going to choose of numbers at random to begin with.

  • So the near plane is going to be not pointing out one on the far plane.

  • No 10.1.

  • I've really no idea what these mean in this scale of the map that we're creating.

  • I'm also going to need a field of view variable, but I'm going to store instead the field of view half variable.

  • So in this case, the field of view would be pi divided by two.

  • But I'm automatically having it already, so it's pi divided by four on.

  • The reason for this is because I'm taking the angle of the center line from the player into the map and I'm going to subtract half the field of you.

  • I'm going to add half of the field of view to give me the first of the points.

  • So let's do this now.

  • We want to create our first set of points, which was far X one and why one?

  • Well, if we assume that the player exists at World X, we can create a unit vector using co sign and sign off the angle that the player is facing minus the field of view times, the far plane.

  • So wherever the player is in the X axis, we're going to create a value between zero and one here on were multiplying that value by the far plane again.

  • I don't know where this exists in the space of our world.

  • It goes without saying that's to create B Y.

  • Component is exactly the same.

  • Except will you sign for the opposing Farpoint?

  • We're placing half the field of view instead of subtracting it and for the near points were using the near plane value instead of the far plane value.

  • So this gives us 42 dimensional points that represent the corners of our first um within the map.

  • When we're drawing the maps, we only want them to occupy half of the screen, not the full screen, because this assumes that are vertical.

  • Vanishing Point is halfway up the screen, so I'm going to work on a row by row basis within our council window.

  • Going from zero toe, half the screen height will need to normalize the screen height value to between zero and one.

  • I'm going to call this simple depth, and it's just simply the why value divided by the total range of the Y value in this case, knowing how far into the first room we need to bay, we can create two points that represent this scan line going across the first room.

  • So on the left hand side, the X one side, I get the direction vector off the line of the side of the first, Um, I multiplied by my normalized value to create a sampling point, and I offset it by the near plane, I guess an end point for the scan line by doing exactly the same thing.

  • Now we know where the scan line begins and ends.

  • In our first room.

  • We can use the X component of the screen coordinate toe workout were along that line.

  • We should sample the pixel in color.

  • So in exactly the same way, I'm going to create a normalized point between zero and one sample wit, and I'm going to find the sample location by inter plating along that line.

  • Once I have my sample coordinates, I can go and extract them from the OLC Sprite, using the sample cliff and sample cooler functions.

  • Now these functions will operate on a nearest neighbor principle, which means we don't really care about the spatial scale.

  • In this instance, the sampling algorithm will do what it should do on will never give us any holes or blanks.

  • Once we know which symbol to draw on which color it is, we should draw it.

  • But I'm going to draw, offset by half the screen height in the Y axis, so this gives us a ground plane along the bottom of the screen.

  • Let's take a look.

  • Mmm, Well, something's going on from that static image.

  • I can't really work out what's happening.

  • I need to add some user controls to move the player location around the map, and I will add these outside of our rendering loop.

  • We've seen this many times before.

  • I'm just going to see if the left Roky is held down.

  • And if it is, I'm going to deck.

  • Lament the angle.

  • If the right arrow keys held down, I'm going to increment the angle.

  • If the up arrow key is held down, then I want to increment the X and Y coordinate along the unit vector created by the angle.

  • We're going to increments.

  • At this particular speed, it's quite slow, but at the moment, slow is relative because I have no idea what the scale of our world is.

  • This will take a little bit of fiddling about on getting a feel for it, and I could do the same for reverse.

  • Except this time I'll let put a minus sign in front of the cosine sine.

  • Let's take a look.

  • Well, I'm turning in the world, and it's looking pretty funky.

  • What I notice, though, is that the world seems to end quite quickly.

  • Let's try moving backwards.

  • Well, that was strange.

  • And moving forwards.

  • Well, it's just outright psychedelic.

  • It's pretty but useless.

  • The problem here is I've just taken a guess at what are near and far plane should be on our field of view, so I'm going to make these controllable too similar code.

  • Just going to check for certain key presses on Alter the permitted by implementing it or deca menting it.

  • Let's see how this works, so without turning anything Q and a change The Plains near parameter Well, that seems to stretch things out.

  • W and s change the Plains Far perimeter.

  • We can see there is change, and it gets it kind of makes some sense.

  • The field of view is changed by said and X, and that's definitely affecting things in the X axis.

  • Let's rotate the player into the scene a little bit more, widen the field of view on.