1 00:00:00,000 --> 00:00:00,050 2 00:00:00,050 --> 00:00:02,550 SPEAKER: In Mario 3, we took a look at procedure generation. 3 00:00:02,550 --> 00:00:06,560 So it's an area of game programming that I particularly am very interested in. 4 00:00:06,560 --> 00:00:10,590 It allows programmers to really take advantage of the CPU's resources 5 00:00:10,590 --> 00:00:13,260 and take away from design time in order to-- 6 00:00:13,260 --> 00:00:14,730 if your algorithm is good-- 7 00:00:14,730 --> 00:00:17,640 construct a large amount of sort of content assets 8 00:00:17,640 --> 00:00:21,633 that you can use to also regenerate every time you run the game, 9 00:00:21,633 --> 00:00:23,550 and make it a different experience every time. 10 00:00:23,550 --> 00:00:27,195 So games like Minecraft in particular capitalize on this tremendously. 11 00:00:27,195 --> 00:00:29,820 But they have slightly more sophisticated generation algorithms 12 00:00:29,820 --> 00:00:30,830 than we've used. 13 00:00:30,830 --> 00:00:33,580 In this update, we're just going to add an avatar to the screen. 14 00:00:33,580 --> 00:00:37,005 So we're going to add the little a in alien, so a sort of faux Mario 15 00:00:37,005 --> 00:00:37,615 to the scene. 16 00:00:37,615 --> 00:00:39,990 It's not going to be able to move in this update just yet 17 00:00:39,990 --> 00:00:41,240 or really do much of anything. 18 00:00:41,240 --> 00:00:43,572 It's there more for illustration just to mock up 19 00:00:43,572 --> 00:00:45,030 sort of what we have going forward. 20 00:00:45,030 --> 00:00:48,623 But it is a step towards realizing the full sort of vision of the Super Mario 21 00:00:48,623 --> 00:00:49,290 Brothers mockup. 22 00:00:49,290 --> 00:00:51,540 So let's transition over to the code here. 23 00:00:51,540 --> 00:00:55,307 We're going to really store the player inside of the map. 24 00:00:55,307 --> 00:00:56,640 And also, one thing to note too. 25 00:00:56,640 --> 00:01:00,300 In the Graphics folder, I've gone ahead and added the blue_alien.png, 26 00:01:00,300 --> 00:01:01,740 which you'll see in the distro. 27 00:01:01,740 --> 00:01:04,157 We have the spritesheet from before, which is just blocks. 28 00:01:04,157 --> 00:01:07,510 But we have the actual blue_alien.png which has all of its frame data. 29 00:01:07,510 --> 00:01:09,762 So this first frame here is a standing frame. 30 00:01:09,762 --> 00:01:12,720 But then we have things like walking and ducking and climbing a ladder, 31 00:01:12,720 --> 00:01:14,380 jumping, so on and so forth. 32 00:01:14,380 --> 00:01:16,510 So it has quite a few different frames for different use cases, 33 00:01:16,510 --> 00:01:18,180 depending on if you want to go out and explore 34 00:01:18,180 --> 00:01:19,710 some other things with the distro. 35 00:01:19,710 --> 00:01:23,040 But we're just going to use a few of these throughout the track. 36 00:01:23,040 --> 00:01:24,720 So let's go back to Map. 37 00:01:24,720 --> 00:01:27,853 And what I want to do is create a player object. 38 00:01:27,853 --> 00:01:30,520 And when we were doing this before, we created the Player class. 39 00:01:30,520 --> 00:01:33,500 What I'm going to do is I'm going to say self.player is equal to player. 40 00:01:33,500 --> 00:01:35,125 And I'm actually going to pass in self. 41 00:01:35,125 --> 00:01:37,620 I'm going to pass in the map object to the player 42 00:01:37,620 --> 00:01:40,805 so the player has a reference to the map data when we're constructing it. 43 00:01:40,805 --> 00:01:41,680 So this is important. 44 00:01:41,680 --> 00:01:44,100 We're passing in a reference to self, which is 45 00:01:44,100 --> 00:01:46,440 the map itself, going into the player. 46 00:01:46,440 --> 00:01:47,185 So very useful. 47 00:01:47,185 --> 00:01:50,310 Now what we're going to do is, I'm going to go down to the update function. 48 00:01:50,310 --> 00:01:52,920 Now, we're not doing anything with the player 49 00:01:52,920 --> 00:01:55,170 in terms of updating it this iteration. 50 00:01:55,170 --> 00:01:57,720 But we're going to add it just for going forward, 51 00:01:57,720 --> 00:02:02,520 just sort of to proactively anticipate that we're going to need to do so. 52 00:02:02,520 --> 00:02:06,120 We will, in this iteration, need self.player render here 53 00:02:06,120 --> 00:02:07,830 in the Map render function. 54 00:02:07,830 --> 00:02:11,580 Now what I'm going to do is I'm going to create a new file, the player.lua. 55 00:02:11,580 --> 00:02:15,280 And actually, before I finish with that, with Map, I'm going to go up here. 56 00:02:15,280 --> 00:02:19,080 And underneath Util, I'm going to require player just proactively. 57 00:02:19,080 --> 00:02:22,860 Going back to Player.lua, I'm going to say player is equal to class. 58 00:02:22,860 --> 00:02:24,360 I'm going to create a few functions. 59 00:02:24,360 --> 00:02:26,900 So player init, of course, is necessary. 60 00:02:26,900 --> 00:02:29,070 We will eventually need an update function, 61 00:02:29,070 --> 00:02:31,620 though we won't use it in this version of the track. 62 00:02:31,620 --> 00:02:35,245 And then render we will need as well. 63 00:02:35,245 --> 00:02:36,870 So we're going to need a few variables. 64 00:02:36,870 --> 00:02:38,953 So for example, we will need a width and a height. 65 00:02:38,953 --> 00:02:42,210 So I do know that the width is 16 pixels. 66 00:02:42,210 --> 00:02:45,600 The height is 20 pixels, actually so that the character is actually slightly 67 00:02:45,600 --> 00:02:48,180 taller than the tile size of our map. 68 00:02:48,180 --> 00:02:50,550 We're going to initialize it with an x and a y value. 69 00:02:50,550 --> 00:02:54,780 So the x value is just going to be a certain amount of tiles. 70 00:02:54,780 --> 00:02:56,780 So we're going to use tile width in this case. 71 00:02:56,780 --> 00:02:58,405 And we're going to multiply this by 10. 72 00:02:58,405 --> 00:03:01,543 So about 10 tiles to the right is where we're going to place our character. 73 00:03:01,543 --> 00:03:03,210 Because we're multiplying by tile width. 74 00:03:03,210 --> 00:03:06,180 So that's 160 is really what that adds up to. 75 00:03:06,180 --> 00:03:08,340 So 160 pixels to the right. 76 00:03:08,340 --> 00:03:10,590 And in this case, we're going to do map.tileHeight. 77 00:03:10,590 --> 00:03:15,330 And we want the avatar to be just above the halfway point of the map. 78 00:03:15,330 --> 00:03:20,700 So we're going to say tile height times map.mapHeight divided by 2. 79 00:03:20,700 --> 00:03:22,890 So it's halfway down the map. 80 00:03:22,890 --> 00:03:26,218 Minus 1 because it's 0 indexed pixel-wise. 81 00:03:26,218 --> 00:03:27,510 So we're going to have minus 1. 82 00:03:27,510 --> 00:03:30,960 And then further, I need to actually-- because everything, remember, is 83 00:03:30,960 --> 00:03:34,770 relative to its top left corner, I need to subtract self.height 84 00:03:34,770 --> 00:03:37,980 as well so that we're not drawing right where the halfway point starts. 85 00:03:37,980 --> 00:03:40,980 We're drawing 20 pixels above that. 86 00:03:40,980 --> 00:03:43,920 So the avatar can be standing on top of the ground as opposed 87 00:03:43,920 --> 00:03:47,460 to have its head right where the ground is, which looks obviously a little bit 88 00:03:47,460 --> 00:03:48,747 unnatural. 89 00:03:48,747 --> 00:03:50,580 Another thing that we're going to need to do 90 00:03:50,580 --> 00:03:55,340 is define the texture data and the frame data for our Mario avatar. 91 00:03:55,340 --> 00:04:00,510 So I can say self.texture equals love.graphics.newImage where we take 92 00:04:00,510 --> 00:04:03,750 in graphics/blue_alien.png. 93 00:04:03,750 --> 00:04:08,542 And then we can say self.frames is equal to generatequads, 94 00:04:08,542 --> 00:04:11,250 which is the function that we wrote before to splice up our frame 95 00:04:11,250 --> 00:04:13,980 information for the tile sheet. 96 00:04:13,980 --> 00:04:15,720 And I can say self.texture. 97 00:04:15,720 --> 00:04:18,779 And 16 pixels by 20 pixels are the dimensions 98 00:04:18,779 --> 00:04:23,070 for each of the quads in the aliens spreadsheet. 99 00:04:23,070 --> 00:04:28,530 So then I can say in render I want to love.graphics.draw our texture. 100 00:04:28,530 --> 00:04:33,540 I want to draw frames 1-- so that's the very first frame that we split up. 101 00:04:33,540 --> 00:04:35,610 And that's just a standing frame. 102 00:04:35,610 --> 00:04:39,780 And then I want to do self.x and self.y, just like so. 103 00:04:39,780 --> 00:04:43,930 Now, if I run this, it looks like map is a null value for player. 104 00:04:43,930 --> 00:04:45,450 So I'm going to go back over here. 105 00:04:45,450 --> 00:04:48,180 And I forgot to pass that map as an argument 106 00:04:48,180 --> 00:04:49,930 to player init, which is very important. 107 00:04:49,930 --> 00:04:50,930 Don't forget to do that. 108 00:04:50,930 --> 00:04:53,670 Remember, that's the self that we're passing in from the map 109 00:04:53,670 --> 00:04:56,342 when we actually instantiate the player in the maps constructor. 110 00:04:56,342 --> 00:04:58,050 I'm going to go ahead and run this again. 111 00:04:58,050 --> 00:05:01,550 And we do indeed see we have our alien drawn there with a bush beside him. 112 00:05:01,550 --> 00:05:05,810 We've got a couple of gaps there to show our sort of random generation in a way 113 00:05:05,810 --> 00:05:07,810 that we didn't get to see in the last iteration. 114 00:05:07,810 --> 00:05:09,370 So that's it for drawing Mario. 115 00:05:09,370 --> 00:05:11,110 So pretty straightforward. 116 00:05:11,110 --> 00:05:13,450 In Mario 5, we're going to take the next step. 117 00:05:13,450 --> 00:05:15,942 We're going to add the ability to move Mario left or right. 118 00:05:15,942 --> 00:05:18,400 Even though we're not going to have any animation just yet, 119 00:05:18,400 --> 00:05:21,567 we're not going to have collision, we're going to get to all that very soon. 120 00:05:21,567 --> 00:05:25,000 But for now, join me in Mario 5 as we add keyboard input to move Mario. 121 00:05:25,000 --> 00:05:26,730 See you then. 122 00:05:26,730 --> 00:05:27,539