1 00:00:00,000 --> 00:00:00,990 2 00:00:00,990 --> 00:00:03,058 SPEAKER: All right, so in pong0, we took a look 3 00:00:03,058 --> 00:00:04,600 at getting a window up on the screen. 4 00:00:04,600 --> 00:00:07,050 We used a 16 by 9 aspect ratio-- 5 00:00:07,050 --> 00:00:10,080 1,280 by 720-- instead of the square aspect ratio 6 00:00:10,080 --> 00:00:12,330 just so that we have something looks a little bit more 7 00:00:12,330 --> 00:00:14,487 like what you would see on a modern screen. 8 00:00:14,487 --> 00:00:16,320 And we also took a look at drawing something 9 00:00:16,320 --> 00:00:18,270 in the center of the screen with printf. 10 00:00:18,270 --> 00:00:20,730 So a very simple start with Hello, Pong. 11 00:00:20,730 --> 00:00:23,370 Now we're going to approach a problem that we realized we had 12 00:00:23,370 --> 00:00:24,870 towards the end of the last section. 13 00:00:24,870 --> 00:00:28,540 And that's the fact that the text was just a little bit too small. 14 00:00:28,540 --> 00:00:32,350 So with this update, we're going to increase the size of the text. 15 00:00:32,350 --> 00:00:36,240 But what we're really going to be doing is emulating a virtual screen size 16 00:00:36,240 --> 00:00:39,720 that's much smaller, much more like as if we were coding for, let's say, 17 00:00:39,720 --> 00:00:41,338 the NES or the Super Nintendo. 18 00:00:41,338 --> 00:00:44,130 We're not actually increasing the font size, but we are zooming in. 19 00:00:44,130 --> 00:00:46,080 We're drawing to a virtual raster. 20 00:00:46,080 --> 00:00:48,780 And ordinarily, that would be a little bit tricky. 21 00:00:48,780 --> 00:00:52,530 But fortunately, we have something called the push library. 22 00:00:52,530 --> 00:00:53,520 Now this is on GitHub. 23 00:00:53,520 --> 00:00:55,620 This is Ulydev/push. 24 00:00:55,620 --> 00:00:58,680 It's just a very simple library that essentially 25 00:00:58,680 --> 00:01:02,880 has a virtual raster that you can draw to that gets stretched to fill whatever 26 00:01:02,880 --> 00:01:04,753 window size that you want. 27 00:01:04,753 --> 00:01:06,420 It's a simple download here from GitHub. 28 00:01:06,420 --> 00:01:09,690 If you click this green button here, it'll be included with the distro code. 29 00:01:09,690 --> 00:01:13,290 I've gone ahead and downloaded it in advance. 30 00:01:13,290 --> 00:01:16,450 And it looks something like this. 31 00:01:16,450 --> 00:01:20,670 This push.lua file is going to be what you actually get out of that zip file. 32 00:01:20,670 --> 00:01:23,880 So just make sure you include it here with your main.lua 33 00:01:23,880 --> 00:01:25,132 file in the same directory. 34 00:01:25,132 --> 00:01:27,090 And I've gone ahead, and I've also, in advance, 35 00:01:27,090 --> 00:01:31,230 created this pong1 folder here with the source code from the last example. 36 00:01:31,230 --> 00:01:34,900 Now I'm going to open it up just in advance in VS code here. 37 00:01:34,900 --> 00:01:36,150 So let's do that. 38 00:01:36,150 --> 00:01:38,060 And I'm going to magnify that. 39 00:01:38,060 --> 00:01:40,320 And as you can see, we have main.lua, and then we 40 00:01:40,320 --> 00:01:42,690 have push.lua, which is going to be a little bit 41 00:01:42,690 --> 00:01:44,070 intimidating to read through. 42 00:01:44,070 --> 00:01:45,660 It's a little bit lower level. 43 00:01:45,660 --> 00:01:48,723 And then in this case, I'm using the distro code for pong 0, 44 00:01:48,723 --> 00:01:50,640 not the code that we used in the last section. 45 00:01:50,640 --> 00:01:52,598 Just so we have everything consistent with what 46 00:01:52,598 --> 00:01:54,180 we're giving out in the distro. 47 00:01:54,180 --> 00:01:56,430 And also, you can see here there are a lot of comments 48 00:01:56,430 --> 00:02:00,150 to highlight as you're reading through it-- maybe a little bit more iteration 49 00:02:00,150 --> 00:02:02,025 upon which I've described already in lecture. 50 00:02:02,025 --> 00:02:04,608 Now before we get to actually coding some improvements to this 51 00:02:04,608 --> 00:02:06,740 and using push, I want to explain a few functions 52 00:02:06,740 --> 00:02:08,073 we're going to be talking about. 53 00:02:08,073 --> 00:02:11,190 So the first one is love.graphics.setDefaultFilter. 54 00:02:11,190 --> 00:02:13,740 It takes in a min and a mag. 55 00:02:13,740 --> 00:02:17,460 And this essentially lets us scale and de-scale scale images 56 00:02:17,460 --> 00:02:22,230 without applying, in our particular use case, any blurring to those images. 57 00:02:22,230 --> 00:02:25,530 Now normally, when you increase a image size, when you zoom in, 58 00:02:25,530 --> 00:02:26,280 there's some blur. 59 00:02:26,280 --> 00:02:29,520 There's some interpolation, specifically bilinear filtering. 60 00:02:29,520 --> 00:02:32,130 It looks essentially at a pixel, samples the pixels around it, 61 00:02:32,130 --> 00:02:33,963 and sort of calculates what that should look 62 00:02:33,963 --> 00:02:35,760 like when it's zoomed in or zoomed out. 63 00:02:35,760 --> 00:02:37,430 We just want nearest neighbor filtering. 64 00:02:37,430 --> 00:02:40,680 We just want it to essentially take the flat pixel value when it's calculated, 65 00:02:40,680 --> 00:02:45,550 when it scaled or minified so that it retains sort of a m retro look. 66 00:02:45,550 --> 00:02:48,300 We don't want any of that blurried look because when we zoom in, 67 00:02:48,300 --> 00:02:50,202 we start using fonts and images and the like. 68 00:02:50,202 --> 00:02:53,160 Especially when we get to Mario, it just does not look very good at all 69 00:02:53,160 --> 00:02:54,717 on a sort of simulated resolution. 70 00:02:54,717 --> 00:02:56,550 Another thing we're going to take a look at, 71 00:02:56,550 --> 00:02:59,592 which we didn't talk about last time even though we looked at game loops, 72 00:02:59,592 --> 00:03:02,980 is love.keypressed, which takes in a key as an argument. 73 00:03:02,980 --> 00:03:06,318 And this essentially lets us specify the behavior for whenever 74 00:03:06,318 --> 00:03:07,860 a user presses a key at the keyboard. 75 00:03:07,860 --> 00:03:11,350 If we decide we want to have escape mean something, in our case, 76 00:03:11,350 --> 00:03:13,590 we're going to make escape quit the application, 77 00:03:13,590 --> 00:03:17,370 and to do that, we're going to use this love.event.quit function, which 78 00:03:17,370 --> 00:03:21,030 literally just quits the current love window. 79 00:03:21,030 --> 00:03:23,408 And lastly, just a slide to illustrate texture filtering. 80 00:03:23,408 --> 00:03:25,200 On the right side, you see what is normally 81 00:03:25,200 --> 00:03:28,252 the default in love, which is when you scale up an image. 82 00:03:28,252 --> 00:03:28,960 It gets filtered. 83 00:03:28,960 --> 00:03:30,180 It gets blurred a little bit. 84 00:03:30,180 --> 00:03:32,880 We want point filtering or nearest neighbor filtering. 85 00:03:32,880 --> 00:03:35,790 And nearest is going to be specifically the argument we provide 86 00:03:35,790 --> 00:03:39,030 to love.graphics.setDefaultFilter. 87 00:03:39,030 --> 00:03:40,780 So I'm going to go back into my code here. 88 00:03:40,780 --> 00:03:41,970 And the first thing I'm going to take care of 89 00:03:41,970 --> 00:03:43,950 is just getting rid of that keypressed. 90 00:03:43,950 --> 00:03:49,830 So I'm going to say function love.keypressed, takes a key. 91 00:03:49,830 --> 00:03:51,750 And I'm going to do-- 92 00:03:51,750 --> 00:03:54,570 a key is just going to be given to us as a string. 93 00:03:54,570 --> 00:03:58,980 So what I'm going to do is I'm going to say if key is equal to escape, then-- 94 00:03:58,980 --> 00:04:03,240 and then is important because then is sort of like the open curly brace in C. 95 00:04:03,240 --> 00:04:06,060 It just means this is the beginning of my if statement of what 96 00:04:06,060 --> 00:04:07,810 happens within the if statement. 97 00:04:07,810 --> 00:04:12,980 So if it's the case that key is equal to escape, I want to just love.event.quit. 98 00:04:12,980 --> 00:04:13,980 So I'm going to save it. 99 00:04:13,980 --> 00:04:15,060 I'm going to rerun that. 100 00:04:15,060 --> 00:04:18,029 It's got the same look as the last time with Hello, Pong. 101 00:04:18,029 --> 00:04:20,783 But now if I hit Escape, it does indeed quit. 102 00:04:20,783 --> 00:04:22,950 So I don't have to hit the red X. I don't have to do 103 00:04:22,950 --> 00:04:25,477 Command-Q. It's very straightforward. 104 00:04:25,477 --> 00:04:27,310 A lot easier if I'm just using the keyboard. 105 00:04:27,310 --> 00:04:30,190 I don't want to mess with the mouse or any keyboard shortcuts. 106 00:04:30,190 --> 00:04:32,523 Now the next part is going to be a little bit more work. 107 00:04:32,523 --> 00:04:36,360 We want to essentially use the push library to simulate 108 00:04:36,360 --> 00:04:38,550 as if we were coding on a smaller raster size 109 00:04:38,550 --> 00:04:43,110 if we were coding, for example, the NES at 240p roughly, 110 00:04:43,110 --> 00:04:45,930 which is as big as the screen sizes were back in the day. 111 00:04:45,930 --> 00:04:51,270 To do this, the first step I'm going to do is specify a virtual width of 432 112 00:04:51,270 --> 00:04:55,440 and a virtual height of 243. 113 00:04:55,440 --> 00:04:58,770 And this is just a resolution I pick that's about 16 by 9 114 00:04:58,770 --> 00:05:01,620 but very similar to what you'd see for the NES or something. 115 00:05:01,620 --> 00:05:06,150 So it's still modern in appearance, but it has that old retro look to it. 116 00:05:06,150 --> 00:05:09,690 Now the next thing I need to do is actually import the push library. 117 00:05:09,690 --> 00:05:11,820 So push is something somebody else wrote, 118 00:05:11,820 --> 00:05:14,527 but I need to get that functionality into my main.lua. 119 00:05:14,527 --> 00:05:16,110 In order to do this, it's very simple. 120 00:05:16,110 --> 00:05:19,230 You just do push equals require push-- 121 00:05:19,230 --> 00:05:20,190 just like that. 122 00:05:20,190 --> 00:05:23,130 And it's going to automatically know that what you're looking for 123 00:05:23,130 --> 00:05:24,330 is something.lua. 124 00:05:24,330 --> 00:05:25,890 That's just the default here. 125 00:05:25,890 --> 00:05:27,720 So push equals require push. 126 00:05:27,720 --> 00:05:32,080 It's essentially looking for this push.lua file by default. 127 00:05:32,080 --> 00:05:34,890 So now the next thing we need to do is push 128 00:05:34,890 --> 00:05:37,590 operates with the window in a different way than the default 129 00:05:37,590 --> 00:05:39,060 love.window.setMode. 130 00:05:39,060 --> 00:05:43,560 Instead, we're going to do push:setupScreen. 131 00:05:43,560 --> 00:05:46,570 This colon is very important, and we'll get to that a little bit later. 132 00:05:46,570 --> 00:05:50,685 But essentially, push is an object calling a method inside of itself. 133 00:05:50,685 --> 00:05:52,560 It's sort of like a function contained inside 134 00:05:52,560 --> 00:05:54,930 of an object that has data specific to that 135 00:05:54,930 --> 00:05:58,380 object as opposed to just a global object that belongs to a table 136 00:05:58,380 --> 00:05:59,135 somewhere. 137 00:05:59,135 --> 00:06:02,010 So this colon is important, and we'll get to that a little bit later. 138 00:06:02,010 --> 00:06:05,950 push: SetupScreen is very similar to love.window.setMode, 139 00:06:05,950 --> 00:06:10,230 but it takes in four arguments at the beginning instead of two-- 140 00:06:10,230 --> 00:06:14,190 VIRTUAL_WIDTH and VIRTUAL_HEIGHT for what we want our virtual raster to be 141 00:06:14,190 --> 00:06:17,100 and then WINDOW_WIDTH and WINDOW_HEIGHT for what 142 00:06:17,100 --> 00:06:22,140 we want to actually have our physical window be in terms of its dimensions. 143 00:06:22,140 --> 00:06:25,980 Then we're going to pass in a table just like we did with love.window.setMode, 144 00:06:25,980 --> 00:06:33,190 fullscreen's false, vsync is equal to true, and resizable is equal to false. 145 00:06:33,190 --> 00:06:36,210 Now the last sort of bit here in order to get 146 00:06:36,210 --> 00:06:38,167 push to actually work-- now we set it up, 147 00:06:38,167 --> 00:06:40,500 but it's not actually going to be doing anything at all. 148 00:06:40,500 --> 00:06:46,320 What we need to do is call something called push:apply-- 149 00:06:46,320 --> 00:06:49,370 again, a method on push with the colon there. 150 00:06:49,370 --> 00:06:57,260 The colon is very important-- push:apply start and push:apply end. 151 00:06:57,260 --> 00:07:01,130 And just for a little bit of space, I'm going to do that. 152 00:07:01,130 --> 00:07:04,610 So this is a sort of a state machine way of thinking. 153 00:07:04,610 --> 00:07:06,830 And you might not have learned about this. 154 00:07:06,830 --> 00:07:10,040 But things like OpenGL, which you may have heard of. 155 00:07:10,040 --> 00:07:12,860 Essentially, that's, in graphics programming, 156 00:07:12,860 --> 00:07:15,710 you set a state, sort of a flag, or a switch somewhere 157 00:07:15,710 --> 00:07:18,570 that says things are going to be done a certain way. 158 00:07:18,570 --> 00:07:21,030 And when we say push:apply start, we're essentially saying, 159 00:07:21,030 --> 00:07:23,180 we're going to be drawing things the push way. 160 00:07:23,180 --> 00:07:24,985 Anything that happens after that is going 161 00:07:24,985 --> 00:07:26,610 to be done with our virtual resolution. 162 00:07:26,610 --> 00:07:30,380 And once we hit push:apply end, it's like flicking off the switch. 163 00:07:30,380 --> 00:07:32,683 And now things are going to be drawn the normal way. 164 00:07:32,683 --> 00:07:35,600 And you'll notice that everything, all of our draw calls in this case, 165 00:07:35,600 --> 00:07:39,890 the only draw call, printf, is contained within sort of that nestling there 166 00:07:39,890 --> 00:07:42,200 of push:apply start and push:apply end. 167 00:07:42,200 --> 00:07:45,140 Now an important thing to be aware of is we have currently 168 00:07:45,140 --> 00:07:47,630 WINDOW_HEIGHT and WINDOW_WIDTH, but our window 169 00:07:47,630 --> 00:07:49,230 is actually not that size anymore. 170 00:07:49,230 --> 00:07:50,900 Our window is going to be drawn-- 171 00:07:50,900 --> 00:07:53,810 it's going to be drawn at 1,280 by 720, but it's 172 00:07:53,810 --> 00:07:57,860 going to be a raster of 432 by 243. 173 00:07:57,860 --> 00:08:01,460 So what we want to do is change this from WINDOW_HEIGHT and WINDOW_WIDTH 174 00:08:01,460 --> 00:08:04,540 to VIRTUAL_HEIGHT and VIRTUAL_WIDTH. 175 00:08:04,540 --> 00:08:06,170 And to do that, I'm going to save it. 176 00:08:06,170 --> 00:08:07,520 I'm going to run the program. 177 00:08:07,520 --> 00:08:10,940 And we do, indeed, see Hello Pong there in the middle of the screen. 178 00:08:10,940 --> 00:08:12,240 Now it looks a little weird. 179 00:08:12,240 --> 00:08:15,170 It looks a little bit blurry because, just as we talked about before, 180 00:08:15,170 --> 00:08:17,680 love is applying filtering to the font. 181 00:08:17,680 --> 00:08:22,850 Now to fix that, we looked at a function that of love.graphics.setDefaultFilter. 182 00:08:22,850 --> 00:08:25,130 So all we need to do to fix this is go up 183 00:08:25,130 --> 00:08:29,060 here and do love.graphics.setDefaultFilter 184 00:08:29,060 --> 00:08:32,309 of nearest and nearest. 185 00:08:32,309 --> 00:08:33,590 I'm going to rerun it. 186 00:08:33,590 --> 00:08:36,890 And we there do see now, hopefully you can see on your screen, 187 00:08:36,890 --> 00:08:38,900 Hello Pong much more crisp. 188 00:08:38,900 --> 00:08:43,480 And now we're running not at 1,280 by 720 in terms of our raster 189 00:08:43,480 --> 00:08:49,790 but 432 by 243, though we do get to use a 1,280 by 720p window. 190 00:08:49,790 --> 00:08:52,080 So that was a low res update that was using push. 191 00:08:52,080 --> 00:08:56,520 And let's go back to our slide deck here. 192 00:08:56,520 --> 00:08:58,800 For pong2 being the next update, we're going 193 00:08:58,800 --> 00:09:00,563 to take a look at actually drawing paddles 194 00:09:00,563 --> 00:09:03,480 on the screen, rectangles on the screen, which will get things looking 195 00:09:03,480 --> 00:09:04,860 a little more visual interesting. 196 00:09:04,860 --> 00:09:07,500 So see you soon for pong2. 197 00:09:07,500 --> 00:09:08,000