1 00:00:00,000 --> 00:00:00,060 2 00:00:00,060 --> 00:00:03,230 SPEAKER: In Mario 1, we looked at how to implement scrolling to our app. 3 00:00:03,230 --> 00:00:06,630 So one of the key features of a side scrolling platforming game 4 00:00:06,630 --> 00:00:08,340 is the ability to scroll our map. 5 00:00:08,340 --> 00:00:11,610 In this example, we're going to take a look at controlling the scrolling. 6 00:00:11,610 --> 00:00:13,110 So previously, it was autoscrolling. 7 00:00:13,110 --> 00:00:16,200 And there are platforming games that are considered autoscrollers, 8 00:00:16,200 --> 00:00:18,658 where you don't actually get to manipulate the camera based 9 00:00:18,658 --> 00:00:19,500 on your movement. 10 00:00:19,500 --> 00:00:21,630 In our game, as we get towards the end, it 11 00:00:21,630 --> 00:00:24,842 is going to be a normal scroller in that it follows an avatar. 12 00:00:24,842 --> 00:00:26,550 But for right now, we're going experiment 13 00:00:26,550 --> 00:00:30,780 with just moving the camera ourselves with the keyboard controls. 14 00:00:30,780 --> 00:00:34,830 And that's really the only explanation I think I'll give for this. 15 00:00:34,830 --> 00:00:37,080 I'm going to go over to my main.lua. 16 00:00:37,080 --> 00:00:40,410 And actually, really, we're not doing anything with main.lua at all. 17 00:00:40,410 --> 00:00:43,560 So I'm just going to run this so we can see what we have. 18 00:00:43,560 --> 00:00:45,343 So currently, it scrolls automatically. 19 00:00:45,343 --> 00:00:46,510 We don't want that behavior. 20 00:00:46,510 --> 00:00:49,780 What I want to do is have this be manual. 21 00:00:49,780 --> 00:00:54,540 So what I'm going to do, I want to clamp the movement 22 00:00:54,540 --> 00:00:57,100 to the width of the map in pixels. 23 00:00:57,100 --> 00:01:00,210 And to do this, I'm going to sort of cache some values 24 00:01:00,210 --> 00:01:02,230 for the size of the map in pixels. 25 00:01:02,230 --> 00:01:04,780 So I'm going to say mapWidthPixels. 26 00:01:04,780 --> 00:01:11,730 And I'm going to set that equal to self.mapWidth times self.tileWidth. 27 00:01:11,730 --> 00:01:12,930 Same thing here. 28 00:01:12,930 --> 00:01:20,580 mapHeightPixels is going to be equal to self.mapHeight times self.tileHeight. 29 00:01:20,580 --> 00:01:23,430 And so this will keep track of the overall pixel size 30 00:01:23,430 --> 00:01:26,700 such that when we're moving our camera, when we're actually moving our camX 31 00:01:26,700 --> 00:01:31,980 and camY here, we can clamp that to be no less than 0, no greater 32 00:01:31,980 --> 00:01:35,423 than the sort of upper bound of those values. 33 00:01:35,423 --> 00:01:36,840 So I'm going to go down to update. 34 00:01:36,840 --> 00:01:39,090 And this is where I want to have this actually happen. 35 00:01:39,090 --> 00:01:42,353 Now, remember we have the love.keyboard.isDown function 36 00:01:42,353 --> 00:01:43,270 to make this possible. 37 00:01:43,270 --> 00:01:46,740 So I'm going to say, if love.keyboard.isDown-- 38 00:01:46,740 --> 00:01:48,810 and we'll just use wasd for this. 39 00:01:48,810 --> 00:01:55,560 So w, and then we'll say, elseif love.keyboard.isDown s, 40 00:01:55,560 --> 00:01:58,110 elseif love.keyboard.isDown-- 41 00:01:58,110 --> 00:02:00,960 42 00:02:00,960 --> 00:02:05,370 actually, w, we'll do a, s. 43 00:02:05,370 --> 00:02:12,280 And elseif love.keyboard.isDown, d. 44 00:02:12,280 --> 00:02:13,110 Cool. 45 00:02:13,110 --> 00:02:18,540 So here we are basically checking up, left, down, and right for the movement. 46 00:02:18,540 --> 00:02:23,440 So we'll just say up movement, just to keep myself organized here. 47 00:02:23,440 --> 00:02:30,970 Left movement, and this is down movement, and right movement. 48 00:02:30,970 --> 00:02:36,480 What we want to do now is basically do what we're doing down here. 49 00:02:36,480 --> 00:02:37,770 I'm going to copy that. 50 00:02:37,770 --> 00:02:41,220 Moving the camX or camY accordingly. 51 00:02:41,220 --> 00:02:43,620 I'm just going to copy this in each of these, 52 00:02:43,620 --> 00:02:46,410 even though this is currently just moving the camera to the right 53 00:02:46,410 --> 00:02:53,820 by setting the camX going forward, I'm going 54 00:02:53,820 --> 00:02:56,510 to go ahead and set-- so this is up. 55 00:02:56,510 --> 00:02:58,260 So this needs to be camY. 56 00:02:58,260 --> 00:03:01,270 Down needs to be camY well. 57 00:03:01,270 --> 00:03:05,550 So if it is the case that we are pressing up, w, then what I want to do 58 00:03:05,550 --> 00:03:12,210 is say that this should be to negative SCROLL_SPEED if we're going up. 59 00:03:12,210 --> 00:03:16,470 And then if we're going left, then this should be negative SCROLL_SPEED on x. 60 00:03:16,470 --> 00:03:19,830 And then this can be positive scroll speed on y going down 61 00:03:19,830 --> 00:03:21,550 and x going to the right. 62 00:03:21,550 --> 00:03:24,310 Let's go ahead and save this and just test this out. 63 00:03:24,310 --> 00:03:28,920 So if I move to the right, if I'm pressing d, we do indeed move right. 64 00:03:28,920 --> 00:03:30,990 If I press s, we go down. 65 00:03:30,990 --> 00:03:34,120 And it looks like we have a little bit of a bug here. 66 00:03:34,120 --> 00:03:36,480 So let's go ahead and check this out. 67 00:03:36,480 --> 00:03:40,590 I think it's because we are currently not actually setting 68 00:03:40,590 --> 00:03:42,410 the translate to the camY. 69 00:03:42,410 --> 00:03:44,910 Oh, we are setting it to camY, OK. 70 00:03:44,910 --> 00:03:49,410 So we're going to say love to translate math.floor negative camX plus 0.5, 71 00:03:49,410 --> 00:03:51,790 which we are doing floor on. 72 00:03:51,790 --> 00:03:53,550 Let's go over to Map. 73 00:03:53,550 --> 00:03:56,760 And let me just make sure that I'm doing this appropriately. 74 00:03:56,760 --> 00:03:59,725 So self.camY plus dt. 75 00:03:59,725 --> 00:04:00,480 Oh, you know what? 76 00:04:00,480 --> 00:04:01,563 Because I have a bug here. 77 00:04:01,563 --> 00:04:03,420 I forgot to set this to y. 78 00:04:03,420 --> 00:04:06,300 Let's go ahead and make sure both of those are camY. 79 00:04:06,300 --> 00:04:08,190 So let me rerun that, try it again. 80 00:04:08,190 --> 00:04:11,010 I'm moving down, moving up, moving left, moving right. 81 00:04:11,010 --> 00:04:13,620 And everything does seem to be smoother. 82 00:04:13,620 --> 00:04:14,790 OK, perfect. 83 00:04:14,790 --> 00:04:18,450 Now, we haven't taken care of the aspect of actually smoothing out 84 00:04:18,450 --> 00:04:19,350 the movement-- 85 00:04:19,350 --> 00:04:21,279 or clamping the movement, I should say-- 86 00:04:21,279 --> 00:04:23,160 such that it doesn't go beyond the map edges. 87 00:04:23,160 --> 00:04:25,020 So observe one more time. 88 00:04:25,020 --> 00:04:28,500 If I run this and I move the map, we do have it sort 89 00:04:28,500 --> 00:04:30,930 of allowing us to move left and right. 90 00:04:30,930 --> 00:04:34,080 So we're not going to do that, be on the map edges. 91 00:04:34,080 --> 00:04:34,920 I want it to clamp. 92 00:04:34,920 --> 00:04:38,820 I want it to only show the left edge but not the sort of cut-off point. 93 00:04:38,820 --> 00:04:40,380 And the right edge are flipped. 94 00:04:40,380 --> 00:04:43,320 So what I can do is, remember, we have the math.min 95 00:04:43,320 --> 00:04:47,790 and math.max functions, which will allow us to say, return the greater or lesser 96 00:04:47,790 --> 00:04:49,050 of two numbers accordingly. 97 00:04:49,050 --> 00:04:52,050 So in the example of moving up, we essentially 98 00:04:52,050 --> 00:04:58,230 want to return the greater of 0 and this value, y 99 00:04:58,230 --> 00:05:03,070 being added to negative SCROLL_SPEED, or dt times negative SCROLL_SPEED. 100 00:05:03,070 --> 00:05:05,760 So if we return the greater of 0 and that amount, 101 00:05:05,760 --> 00:05:07,590 it will never get any less than 0. 102 00:05:07,590 --> 00:05:11,640 So we can say math.max of 0 and this number. 103 00:05:11,640 --> 00:05:13,770 I can do the same thing for moving left, actually. 104 00:05:13,770 --> 00:05:18,990 So I can say, math.max of 0 and this. 105 00:05:18,990 --> 00:05:23,070 And this will prevent both on the y and the x going below 0. 106 00:05:23,070 --> 00:05:29,130 And for y, we can return the math.min of the map height of pixels, 107 00:05:29,130 --> 00:05:34,050 so self.mapHeightPixels of that. 108 00:05:34,050 --> 00:05:41,610 And we'll do this for math.min of self.mapWidthPixels. 109 00:05:41,610 --> 00:05:47,580 And actually, what we need to do as well is subtract virtual height. 110 00:05:47,580 --> 00:05:49,805 Because remember, it's relative the top left corner. 111 00:05:49,805 --> 00:05:51,930 So if our camera is [INAUDIBLE] the top left corner 112 00:05:51,930 --> 00:05:55,860 but we allow ourselves to go all the way to the end of the map height 113 00:05:55,860 --> 00:05:58,650 and width in pixels, then we'll end up actually 114 00:05:58,650 --> 00:06:01,890 going all the way past the screen, a whole screen size past the border. 115 00:06:01,890 --> 00:06:06,840 So we want to subtract virtual height and virtual width from that 116 00:06:06,840 --> 00:06:09,120 to account for these screens offset. 117 00:06:09,120 --> 00:06:12,690 So we'll say VIRTUAL_WIDTH in this case. 118 00:06:12,690 --> 00:06:13,440 Run that. 119 00:06:13,440 --> 00:06:16,368 Now if I move the camera, I can't actually move left here. 120 00:06:16,368 --> 00:06:17,910 It's preventing me, which is perfect. 121 00:06:17,910 --> 00:06:19,720 That's the exact behavior I want. 122 00:06:19,720 --> 00:06:22,740 And if I try to move right, this is as far as it will let me go right. 123 00:06:22,740 --> 00:06:26,100 And if I move down, eventually I'm going to hit the bottom of all the brick 124 00:06:26,100 --> 00:06:29,640 walls, which will be more or less the screenshot that we 125 00:06:29,640 --> 00:06:31,140 saw in the prior example. 126 00:06:31,140 --> 00:06:35,010 And if I move up as well, eventually I won't be able to move anymore. 127 00:06:35,010 --> 00:06:38,010 So that's it in terms of getting the ability 128 00:06:38,010 --> 00:06:40,040 to control the movement of the screen. 129 00:06:40,040 --> 00:06:42,540 In the next update, we're going to look at something I think 130 00:06:42,540 --> 00:06:43,670 a little more visually interesting. 131 00:06:43,670 --> 00:06:45,660 We're going to get into procedural generation 132 00:06:45,660 --> 00:06:49,650 with the procgen update, where we actually see how to create something 133 00:06:49,650 --> 00:06:52,440 beyond just a flat sort of grid of bricks, 134 00:06:52,440 --> 00:06:57,682 and start adding columns and spaces and bushes and blocks and clouds 135 00:06:57,682 --> 00:06:58,640 and so on and so forth. 136 00:06:58,640 --> 00:07:01,440 So we'll see you then in Mario 3. 137 00:07:01,440 --> 00:07:02,323