字幕表 動画を再生する
[MUSIC PLAYING]
COLTON OGDEN: Hey, good evening.
Welcome to GD50 lecture four.
This is Super Mario Bros.
As seen on the slides here, though, we're
not using the actual Super Mario Bros. sprite sheet.
This is sort of like a rip off.
But I found a really awesome sprite sheet
that has all the basic tiles that we need to get this thing working.
There's a link in the distro as to where you can find it online.
I had a lot of fun playing with it.
So hopefully, maybe if you're curious, you
can use some of the sprites in there to go off and do your own thing.
But Super Mario Bros.-- the actual game which this lecture and assignment are
based off of-- is the game shown here.
I think everybody knows what it is.
It's probably the most famous game of all time.
But this game came out in 1985--
sort of revolutionized the gaming industry.
It was the game that brought the gaming industry from a crash
in the '70s thanks to a lot of poor game making policies
and companies and low QA standards.
It basically took the gaming crash of the late '70s, early '80s
and brought games really back to the forefront of people's consciousness.
This and games like Legend of Zelda and a lot of other NES titles
made Nintendo basically the dominator of the video games
industry in the '80s and '90s.
And even today, with games like Breath of the Wild,
they're still doing their thing.
This is Super Mario Bros.
It's a 2D platformer.
And what this basically means is you control Mario, who's a plumber.
He goes around, walks sort of looking at him from the side.
He walks left to right.
He can jump up and down.
He's affected by gravity.
He can hit blocks.
He can jump on enemies.
He can go down pipes, and there's a bunch of levels.
It was, for its time, quite a complicated game,
and it spawned numerous offshoots and rip offs and other good quality
platformers.
While we talk about Super Mario Bros. today,
some of the topics we'll actually be talking about are tile maps--
so how we can take basically a series of numbers--
tile IDs-- and turn that into a game world.
As you can see here, the game is broken up into blocks of 16 by 16 tiles.
You can see the bricks and the question mark blocks,
and the pipes are even all composed of simple tiles.
And they map to IDs.
And when you take a 2D table or array and you just iterate over all of it
and render the appropriate tile at the appropriate x, y,
you get the appearance of existing in some game world,
even though it's just composed of a bunch of tiny little blocks.
2D animation is something we'll talk about.
So far, we haven't really done any animation
at all in terms of at least characters.
We'll do that with Mario.
He'll have-- our version of Mario, an alien--
when he's moving, he'll have two frames of animation.
The frames of animation-- that's sort of like a flip book
if you've ever used one, where you can see individual pictures.
And when you display them rapidly back to back,
you get the appearance of animation.
We'll be talking about that.
Procedural level generation-- we'll be making all of our levels
generate randomly.
So every time we play the game from the beginning,
everything will be completely different.
We don't have to hard code a finite set of levels.
Everything will be dynamic and also interesting, in my opinion.
We'll talk about the basics of platformer physics
and how we can apply that to our game world
here, because we are just using a table of tiles,
each with an x, y that's hard coded in the game world space.
All we have to really do is take an x, y of Mario, for example,
and then just divide that by the tile size.
And then we get basically what tile that is
in our array at that point in the world.
And so it's really easy to do arbitrary collision detection based
on what direction you're going and not have to iterate over
every single tile in your world.
Because it's just a simple mathematical operation to get the exact tile
given two coordinates, since the world is in a fixed space.
We'll have a little snail in our game that
walks around and does a couple of random animations
and will go after the player, sort of like a little basic intro to AI.
And then lastly, we'll touch on things like power ups and game objects
and how we might be able to influence Mario and pick those up
and that sort of thing.
So first though, a demo.
So if anybody is willing to come up on stage
to test out my implementation of Mario, that would be awesome.
James?
I'm going to go ahead into here, so we should be all ready to go.
So as soon as you're ready, go ahead and hit Return there,
and you should be up and running.
So as a part of having random levels--
so currently, we have a green alien.
The blocks have a random chance in this case to spawn a gem.
And so once they do, you can pick the gem up.
Either they have a gem or they don't.
You can pick it up, and you get 100 points.
As we can see, the world is sort of shifting
based on where James's avatar is, so it tracks the character.
We have some notion of a camera.
You're getting unlucky with the blocks so far.
So you can fall down through the spaces, so you probably want to avoid that.
But if you want to demonstrate doing it--
so in that case, we collided with the two blocks below it.
The one on the right had the gem.
So go ahead and just fall down so we can demonstrate.
So when we fall down, we detect whether the player
has gone below the world limit, and then we start him back
at the beginning of the game.
You can press Enter, it should regenerate a brand new world.
Notice how we have random holes in the ground.
We have random tiles.
We have random toppers for them.
All the blocks are random.
We have snails now.
They're sort of chasing after James.
He can jump on top of them.
There's a lot of little moving pieces here, but a lot of them
are actually pretty simple.
And I'll show you very shortly.
JAMES: Should I stop?
COLTON OGDEN: Yeah, sure.
That would be a great point.
So thanks, James.
Appreciate it.
Currently, there is no notion of a level ending.
That's part of the piece that actually will
spawn an object that the player can interact with to just sort of retrigger
a new level, basically.
But the whole engine behind this basic platformer is there, and it all works.
And so our goal is seen here.
Our goal in this lecture is to demonstrate
how we can get things like a character that moves around on a screen,
and a camera that tracks their position, and tiles that are randomized.
And maybe there are pillars in the ground, holes in the ground.
All of this, again--
at least the tiles-- are stored as just numbers.
So all we really need to do is perform a transformation on a series of numbers.
Maybe 1 is equal to a tile being there, 0 is equal to empty space.
And so just by looking at it, we'll see we go column by column.
We can say, oh, maybe there's a chance to not spawn any tiles along the y
column on this x of the world map.
Or on this particular y, maybe instead of spawning the ground level,
we spawn a couple above it and down so that we get a pillar
and so on and so forth.
And it's just this summation of these randomizations
equals a nice little variety of game levels.
So the first thing we should talk about really is what a tile map is.
And what I've alluded to so far is you can really think of a tile map
as being effectively a 2D array or a table of numbers.
And it's a little more complicated than that depending on how complex
your platformer is, because some numbers are equal to tiles that are solid
or not.
So you should be able to check whether a tile is collidable,
meaning that the player or whatever entity you want to check for
can actually collide with it or
Not.
So obviously, we don't want to trigger a collision on empty tiles.
We want the player to move freely through those.
But if they run up against a wall or if gravity is affecting them,
and they hit tiles below them or above them, we want to detect a collision
and then stop them based on which direction they're moving.
And depending on how complicated you get with your platformer, maybe
you have animated tiles, for instance.
So if a tile's animated, it will display a different frame of animation
based