字幕表 動画を再生する
All right.
Welcome to G T 50 Lecture five.
Today's topic is The Legend of Zelda, as you can see on the screen there.
Very iconic game.
Last week we did Super Mario Brothers, which is arguably the most iconic video game of all time.
Legend of Zelda is a close contender.
Even now, just like with Mario, they're producing very wonderful games, I think last year, Breath of the Wild took all the I forget which ceremony it was our award sort of show, but it took like every award possible this last year of the latest Sell The Breath of the Wild.
So it feels sort of a proposed thio.
Talk about Legend of Zelda in that context as well.
Here's a screenshot of the original legend result.
It was an NTS title, just like Super Mario Brothers.
Eh?
You know, just like most games of its time, tile based you can sort of see how the surroundings of sort of layered tiles bit by bit.
Um, with the goal of the game overall was to sort of explore this open world, which is kind of a first of its kind controlled link, showing the very bottom there yet a sword.
You had bombs.
You had arrows.
Bed.
You went to go find Ruby's.
You went through dungeons, you slave monsters and bosses.
And then ultimately, the goal was to obtain the tri forest, which is shown at the very top left and right of the slide.
Here, Um, here's a screenshot.
Another screen privileges all the inside an actual dungeon where you can see at the very top.
It's got like a map, layout, maps or sort of arranged in a grid.
And you could go room by room, whereby each room was the entire width and height of the screen looking for, you know, solving puzzles, looking for items, that sort of thing.
You can see there is a monster there.
You have heart to the very top, right?
So when you take damage, heart sort of document, we'll see both of these the hearts and the, uh, the dungeon aspect of the game today in lecture as well as you know, the width and height of the room being a dungeon tile and controlling an avatar.
But this is sort of a representative screenshot of what the game looked like back in the day.
Some topics today that will be discussing in order to implement through the foundation for what a game engine like this might look like are things like top down perspective.
So you can see in this screen shot we're looking at, you know, link from the very top in a bird's eye view, as opposed to how we used to look at Mario, um, from the side where it was sort of like a side stroller.
Um, here we're actually looking at things from the top down.
So we have, ah, view of the room in a sort of a different perspective.
They're sort of there's not really a Z access, technically speaking.
But there sort of is You can implement things like gravity in a game engine like this by jumping over holes and things like that.
But there's no gravity like there wasn't Super Mario where, you know, you walk left to right, you jump over gaps, and it's very easy to see in that, sir, since we'll be talking about infinite dungeon generation.
So in the context of today's example, we'll see how we can go about implementing a dungeon that sort of you can go through forever and ever and how to sort of model that and make it look as if you're traveling through a dungeon over and over again and going through different screens in different rooms that are all different.
But in reality will see it's actually just an illusion like we've seen before.
In prior lectures.
We'll talk about hit boxes and hurt boxes and with the differences between the two hit boxes being rectangles on the screen that inflict damage upon other entities in your game world and hurt boxes sort of being the rectangle that models where your player or whether where an entity in the game can be hurt by other hit boxes.
Well, look at events.
So events are a way of sort of broadcasting some key or some message that tells the game world.
Oh, this thing happened and let me register a function to call when that sort of event is processed.
So on some event, you know, dispatch an event and then upon that event, being received by whatever is listening for it performed this chunk of code.
It allows you to sort of decouple aspects of your game engine a little bit and makes for a little bit more readable code and allows you to do some interesting things with, like, achievements, for example, where you don't necessarily want to pull every single frame.
Oh, did I do this sort of arbitrary list of things?
This frame Rather, you can just process all of that with any event and have a listener and a function that, you know, every time you broadcast Oh, pickup coin.
Maybe I have an achievement.
That's like, Oh, uh, how I picked up 50 coins in this level.
You know, you're achievement callback function in your event.
Can can then look for that.
And in your game loop, you don't have to say every frame.
Oh, if Player has 8 50 coins and you sort of take out bloat that would exist in your sort of overall game loop that way, and we'll see an example of how we use that in today's lecture, we'll get screen scrolling.
So a very common are very sort of iconic aspect of legend of Zelda is when you're going from one screen toe another, there is a sort of transition period as one screen loads and the other screen goes away in hardware in the NTS.
But, uh, this was sort of the only way you could actually render a lot of, um, sort of more than a screen with of tiles.
You actually had to dynamically load in tiles and sort of override tiles that existed before that in memory.
But today we'll see how we can sort of create the illusion of doing that by just drawing a room and then having our main room and then just sort of twinning over and then setting everything back to the origin at 00 And it makes it look as if we're moving, you know, back and forth between all these rooms when in reality, all we're doing is just doing a shift and then putting everything back to 00 So all sort of illustrate that on the screen, if I can, And one last thing will look at his data driven design in the context of ah, lot of types of games, particularly RPGs and action games.
It's often very valuable to be able to model all of your items.
Entities sort of abilities, anything you really can as data rather than logic in order to make it easier for you to write one and two for you to sort of allocate the design aspect of your game to other people, not just programmers, and have an engine that's very versatile and model.
And we'll take a look at how we implement sort of a a foundation for that later on.
But first, I'd like to illustrate a demo for today's lecture.
Um, a sort of implementation of Legend of Zelda.
Is there anybody that would like to come up into a demo this today in class?
Awesome.
Thank you so much.
So, whenever you're ready, go ahead and press Ah, the return key there.
And so we see on the screen Legend of 50 which is our legend of Zelda mock our, you know, rip off sort of.
So if you press enter, you go into this is the place state of the game.
So you control an avatar, you can walk around, you can interact with switches as we saw here.
When he presses a switch, the doors open and once the doors are open, you can walk through them.
And it does as where I lived before it transitions the screen one entire screen higher with depending on the direction up, above and below way.
See here now where you're pressing space bar to actually swing our sword.
It's destroying the entities in the game space.
So there's a hit box triggering when you press the space bar that collides with other entities in the game world.
If that hit box hits their hurt box, then they are flagged is dead and they disappear from the game world.
And so this goes on ad infinitum.
It's just infinite dungeon so way he can go in between as many force that we want to.
All we're doing is every time you go through a doorway, spawned a new room, delete the old one and just keep going forever.
Never, never in a game like Legend of Zelda typically doesn't work like this.
There's a hard set number of rooms, and they all exist in sort of a two D array.
And when you generate your dungeon, you sort of have to take in consideration things like, Where do I put the keys?
What I put the boss where I put treasure, that sort of thing.
We won't get to in depth as to how we can implement a complex algorithm like that.
But we'll touch on it a little bit and talk about maybe some ideas that we have.
And then, lastly, we just If you want a demo, we could see the top left.
We have hearts there, which is iconic, sort of Zelda.
And when we do take damage from an enemy notice that we flicker a little bit.
So there's some rendering behavior triggering, and we become invulnerable when we take damage.
And then last night, when we finally take the last hit, we get a little game over screen using the Zelda Font, and that's the game.
In a nutshell.
Press Enter and Luke back.
So pretty simple altogether.
But there's a lot of pieces here that we haven't really seen before.
So thank you very much for coming up to Demo the game.
All right, so that was a demo of, you know, legend of 50 Legend of Zelda.
It has a lot of the pieces that Zelda has.
Its not as fully fleshed out, of course, is a full game like Zelda, which would be monstrously large on, and there's a lot of things we need a factor in.
But the foundation is there.
We have the Dungeon Foundation upon which we can build a an actual generator if we wanted to.
We have entities.
We have hit boxes.
We could easily model because we have switches in the game.
We could model things like treasure chests that open that have different states, just like the switch had different states and have different objects in our game space interact with other objects.
We have a lot here, and we'll talk about all of it today.
So here's a few screen shots just to show, you know what we just looked at.
Our goal, mainly, is the second screen shot on the top, right, which is the place state that has all of the little pieces we just saw.
But just a title Together.
We do have a start state here in a game over state, which is relevant in regard to the hearts in the top left.
So the first thing that I'll talk about, um as we sort of get the engine built up is where do we go for getting our assets into the game?
And just like in prior lectures prior to today, we just have a spreadsheet like we did with Mario, where everything is laid out in a fairly even sequence of, um, tile segments.
In this case, the segments are 16 by 16 pixels.
Here I've over later grid, just to show that the picture is indeed perfectly 16 by 16.
And this is something that you should take into consideration and consciously do when you're building your game.
Assets make it easy to chop up into little pieces so you can an index into this sprite via some table quads, Um, and then a sign, an I D to whatever object or tile you want to rendered to the screen.
And so we see.
If you look here things like the doors, they're not perfectly modeled by one tile.
And so when you do have things that are larger than 16 by 16 it's not quite as easy as, oh, you know, have an entity or an object with this frame, I d and draw it to the screen.
You actually do a little bit more complicated.
Render logic.
So just offhand.
If I wanted to draw a door, does anybody have any suggestions as to how I would model that and or draw it to the screen.
So if we have a door that's not perfectly, eh?
16 or a you know, 16 by 16 pixel tile.
Offhand, the you know what we need to do is just basically store all four of those tiles.
In this case, or at least you know, keep track of however many tiles you're, um, object is, and they just draw them based on some offset.
Have the, you know, an X Y that represents the top left of that object placed in the right position.
And instead of drawing just one tile, we draw four tiles.
And then, instead of having just one collision, boss, that's 16 by 16 tiles.
You can do a couple things.
You can either check collision on all four of these tiles or all at least all two of these door tiles or model your own custom hit box that then maybe that object that represents a doorway has control of so you can say, you know, doorway collides player, and then the doorway has a height and width of however many pixels.
It is wide by tall here, just this door part, and then you know, you are able to then build upon not just having one tile that models a an object or entity in your game space.
But now you have more artistic flexibility.
You can do things like have doorways that are more than one pixel white and sort of have a more convincing game world as a result of that.
And you see a lot of things like that in games like RPGs, where you have full houses that are obviously not just one tile.
Because that would be I mean, something.
You can model things as one tile if you want to.
But from an artistic perspective and from just a game engine perspective, it's a little bit easier to programmatically be ableto cut up all your assets into tiles and draw them as such.
Um, so being able to sort of build upon this just the single Sprite and be able to do multiple sprites to represent an object is the key to things like houses, things like big trees, um, things that are just more complicated than single tiles.
As we see here, the character spreadsheet is, as you can see, a little bit more complicated.
So this is an example of a spreadsheet that has padding.
Sometimes you will get spreadsheets that aren't neatly divided into even segments.
And for good reason, because sometimes you have tiles that are not perfectly the width and height of whatever your game engines tiles are.
In this case, the player is actually 20 pixels toll and 16 pixels wide, and on top of that, he's got different frames of animation.
We can see here at the bottom left.
He's got a sword swing animation.
The swordsman animation is actually stored in a 32 by 32 pixel frame because sometimes, um depending on which angle he's looking at, his spread could get a little larger or smaller.
So when you have a sprite with padding, what sort of a way that we can draw this to the screen, um, reliably, like, how do we How do we take this into consideration?
How would we render a screen?
Ah, spread with padding?
So let's say this right here.