Placeholder Image

字幕表 動画を再生する

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

  • Our character swinging a sword is in 32 by 32 pixel box, right?

  • This sort of box around here, this white space, but he's only still maybe 16 pixels wide by 20 pixels tall or maybe he's some amount similar to that in order to draw him to the screen, which you can look at in the code.

  • All we really need to do is a sign that sprite and offset just say OK, the sprites offset Accent offset.

  • Why are some value that basically lets us draw the sprite toe a negative X and a negative y value And that will shift the sprite up suspended aligns perfectly with wherever his x y r and weaken.

  • You can take a look at that in the code to see exactly how that works.

  • Lastly, the actual entities for our game world are different creatures, and this is a spreadsheet.

  • This is a more ideal spreadsheet where everything is 16 by 16 pixels wide and tall.

  • And all we really did here was just divide the spreadsheet using the regular utility function, generate quads by 16.

  • 16.

  • Um, we don't have to worry about separate, you know, wits and heights for everything.

  • And we can create animations very simply because of this, um, as a side note, something that I like to do when I'm, you know, parsing or when I'm piecing apart a spreadsheet that's got a lot of individual frames particular from creating animations, or I just need to know it for a tile particular tile to drop to the screen.

  • It's kind of a pain to manually look through each and every tile one by one and say, OK, this is one.

  • But okay, if I want to find out what's one?

  • This slime is I gotta count.

  • Okay.

  • How many pixels wide is this?

  • OK, and then it's time's forces 12 and then it's on the fifth row.

  • So 12 times four plus one.

  • Well, get me Okay, so it's Zay Index 49.

  • So I've spent, you know, a non trivial amount of time.

  • So hand calculating what?

  • All these d'oh!

  • I wrote a simple python script that will just go over a file and just add a digit to each individual quad to just show you at a glance what each Sprite is.

  • And this is included in the districts.

  • You can see what it looks like, saves a lot of time, and I recommend trying when you're, you know, sort of working with assets and you find yourself doing something that takes a long time in a sort of tedious and mechanical.

  • Maybe try.

  • Try to find a way to sort of automate that, or at least make it easier to do things at a glance.

  • In this case, just simply imposing a numerical grid solves that problem.

  • I don't have to spend a significant amount of time figuring out which frames of animation the ghost facing left is.

  • I know instantly it's 67 68 69 um, and allows me to just crank things out that much faster.

  • So the first thing we'll take a look at is, ah, sort of top down perspective.

  • Uh, and we mostly talked about this before earlier, but all it really is is a tile map, which we've seen before.

  • Uh, the only difference is now, instead of looking at things from the side, we're just looking at things from up above.

  • So what's it?

  • What's it Probably the most obvious consideration when designing a top down perspective versus a sort of side scrolling point of view.

  • Ping it, looking at, particularly at how the tiles are drawn, what stands out.

  • So the thing that stands out to me is that we have things like shadows on walls.

  • Here we have also corners and things altogether are skewed such that they are almost like rotated slightly as if they're simulating an angle of rotation relative to Thea camera facing from up above.

  • You can see this in like the player, for example.

  • He sort of looked sort of looks like you're looking at him from kind of backwards and up when you're modeling your assets that way.

  • Uh, you this it's more convincing, and Zelda has always done this to make your assets look as if they are slightly tilted and that you're looking up above.

  • So when you're designing a top down game just for convincing the sake of being more convincing, try and emulate that the entities here, like the skeleton and such are a little bit more straight on the bats and Slim's and what not, even though they still have a little bit of that appearance.

  • Like the spider, it sort of looks as if it's from the top back, but modeling your assets from a top down perspective.

  • Really, that's made mainly the thing.

  • Pay attention to shadows and highlights, which adds a lot in terms of convincing us that we're in this room with lighting And also make sure that you're doing things like corners and stuff and making it look as if things are slightly skewed.

  • Rotation wise, the first thing that we're gonna look at in terms of the code and the destro is dungeon generation.

  • So, uh, in Legend of Zelda, dungeons are fixed.

  • They're completely set in advance by the designers.

  • And in most games, this is actually the case in our example and in a couple of other examples, primary example of them being that I can think of that I haven't slides.