SPEAKER: In Mario 3, we took a
look at procedure generation.
So it's an area of game programming that
I particularly am very interested in.
It allows programmers to really take
advantage of the CPU's resources
and take away from
design time in order to--
if your algorithm is good--
construct a large amount
of sort of content assets
that you can use to also regenerate
every time you run the game,
and make it a different
experience every time.
So games like Minecraft in particular
capitalize on this tremendously.
But they have slightly more
sophisticated generation algorithms
than we've used.
In this update, we're just going
to add an avatar to the screen.
So we're going to add the little a
in alien, so a sort of faux Mario
to the scene.
It's not going to be able to
move in this update just yet
or really do much of anything.
It's there more for
illustration just to mock up
sort of what we have going forward.
But it is a step towards realizing the
full sort of vision of the Super Mario
Brothers mockup.
So let's transition
over to the code here.
We're going to really store
the player inside of the map.
And also, one thing to note too.
In the Graphics folder, I've gone
ahead and added the blue_alien.png,
which you'll see in the distro.
We have the spritesheet from
before, which is just blocks.
But we have the actual blue_alien.png
which has all of its frame data.
So this first frame here
is a standing frame.
But then we have things like walking
and ducking and climbing a ladder,
jumping, so on and so forth.
So it has quite a few different
frames for different use cases,
depending on if you want
to go out and explore
some other things with the distro.
But we're just going to use a few
of these throughout the track.
So let's go back to Map.
And what I want to do is
create a player object.
And when we were doing this before,
we created the Player class.
What I'm going to do is I'm going to
say self.player is equal to player.
And I'm actually going to pass in self.
I'm going to pass in the
map object to the player
so the player has a reference to the
map data when we're constructing it.
So this is important.
We're passing in a
reference to self, which is
the map itself, going into the player.
So very useful.
Now what we're going to do is, I'm
going to go down to the update function.
Now, we're not doing
anything with the player
in terms of updating it this iteration.
But we're going to add it
just for going forward,
just sort of to proactively anticipate
that we're going to need to do so.
We will, in this iteration,
need self.player render here
in the Map render function.
Now what I'm going to do is I'm going
to create a new file, the player.lua.
And actually, before I finish with
that, with Map, I'm going to go up here.
And underneath Util, I'm going to
require player just proactively.
Going back to Player.lua, I'm going
to say player is equal to class.
I'm going to create a few functions.
So player init, of course, is necessary.
We will eventually need
an update function,
though we won't use it in
this version of the track.
And then render we will need as well.
So we're going to need a few variables.
So for example, we will
need a width and a height.
So I do know that the
width is 16 pixels.
The height is 20 pixels, actually so
that the character is actually slightly
taller than the tile size of our map.
We're going to initialize
it with an x and a y value.
So the x value is just going to
be a certain amount of tiles.
So we're going to use
tile width in this case.
And we're going to multiply this by 10.
So about 10 tiles to the right is where
we're going to place our character.
Because we're multiplying by tile width.
So that's 160 is really
what that adds up to.
So 160 pixels to the right.
And in this case, we're
going to do map.tileHeight.
And we want the avatar to be just
above the halfway point of the map.
So we're going to say tile height
times map.mapHeight divided by 2.
So it's halfway down the map.
Minus 1 because it's
0 indexed pixel-wise.
So we're going to have minus 1.
And then further, I need to actually--
because everything, remember, is
relative to its top left corner,
I need to subtract self.height
as well so that we're not drawing
right where the halfway point starts.
We're drawing 20 pixels above that.
So the avatar can be standing
on top of the ground as opposed
to have its head right where the ground
is, which looks obviously a little bit
unnatural.
Another thing that we're
going to need to do
is define the texture data and the
frame data for our Mario avatar.
So I can say self.texture equals
love.graphics.newImage where we take
in graphics/blue_alien.png.
And then we can say self.frames
is equal to generatequads,
which is the function that we
wrote before to splice up our frame
information for the tile sheet.
And I can say self.texture.
And 16 pixels by 20
pixels are the dimensions
for each of the quads in
the aliens spreadsheet.
So then I can say in render I want
to love.graphics.draw our texture.
I want to draw frames 1-- so that's
the very first frame that we split up.
And that's just a standing frame.
And then I want to do self.x
and self.y, just like so.
Now, if I run this, it looks like
map is a null value for player.
So I'm going to go back over here.
And I forgot to pass
that map as an argument
to player init, which is very important.
Don't forget to do that.
Remember, that's the self that
we're passing in from the map
when we actually instantiate the
player in the maps constructor.
I'm going to go ahead
and run this again.
And we do indeed see we have our alien
drawn there with a bush beside him.
We've got a couple of gaps there to show
our sort of random generation in a way
that we didn't get to see
in the last iteration.
So that's it for drawing Mario.
So pretty straightforward.
In Mario 5, we're going
to take the next step.
We're going to add the ability
to move Mario left or right.
Even though we're not going to
have any animation just yet,
we're not going to have collision, we're
going to get to all that very soon.
But for now, join me in Mario 5 as
we add keyboard input to move Mario.
See you then.
