1 00:00:00,000 --> 00:00:00,140 2 00:00:00,140 --> 00:00:01,140 COLTON OGDEN: All right. 3 00:00:01,140 --> 00:00:03,605 We just took a look at setting up our environment 4 00:00:03,605 --> 00:00:05,660 so that we could run lua and love. 5 00:00:05,660 --> 00:00:09,260 Now we're going to actually dive into the code base for the Pong Track 6 00:00:09,260 --> 00:00:11,450 with pong0 the day0 update. 7 00:00:11,450 --> 00:00:13,220 And you'll get access to source code that 8 00:00:13,220 --> 00:00:15,230 has all of these individual sections listed out 9 00:00:15,230 --> 00:00:18,590 with this exact same numbering scheme so you can follow along 10 00:00:18,590 --> 00:00:21,500 with the final product of each lesson. 11 00:00:21,500 --> 00:00:24,830 So the day0 updates goal is to get a screen 12 00:00:24,830 --> 00:00:26,670 up looking something very similar to this. 13 00:00:26,670 --> 00:00:29,630 And actually you'll notice that it's almost identical to what 14 00:00:29,630 --> 00:00:33,620 we did before, the only difference really being that the window size is 15 00:00:33,620 --> 00:00:38,870 now 16:9 aspect ratio as opposed to a square, which is Love's default. 16 00:00:38,870 --> 00:00:41,448 And also the text is centered in the middle of the screen 17 00:00:41,448 --> 00:00:43,740 instead of at the very top left, because we're actually 18 00:00:43,740 --> 00:00:47,270 going to be using a different function, as we'll find out here pretty soon. 19 00:00:47,270 --> 00:00:51,140 Now, before we get into all this stuff, we should take a step back and really 20 00:00:51,140 --> 00:00:54,482 start looking at what makes a game. 21 00:00:54,482 --> 00:00:57,440 As you're learning how to program, and you're taking a computer science 22 00:00:57,440 --> 00:01:01,460 class, an intro class, you're probably under sort of the understanding 23 00:01:01,460 --> 00:01:03,950 that an infinite loop is usually a bad thing. 24 00:01:03,950 --> 00:01:06,320 And it usually is in most contexts. 25 00:01:06,320 --> 00:01:10,790 It's often the result of a bug, an erroneous while loop or the like, 26 00:01:10,790 --> 00:01:13,102 that doesn't have an end condition. 27 00:01:13,102 --> 00:01:14,810 Or a spinning beach ball, if you might be 28 00:01:14,810 --> 00:01:17,660 using a graphical application on Mac or Windows 29 00:01:17,660 --> 00:01:20,090 or the like that might have a bug in it. 30 00:01:20,090 --> 00:01:23,630 With games, infinite loops really are what 31 00:01:23,630 --> 00:01:28,220 a game is at sort of the most distilled sort of basic form. 32 00:01:28,220 --> 00:01:31,730 You have, as you see here, this illustration shows input, 33 00:01:31,730 --> 00:01:33,830 updating, and rendering. 34 00:01:33,830 --> 00:01:37,010 So as you know, a game really is just something 35 00:01:37,010 --> 00:01:38,420 that goes on over and over again. 36 00:01:38,420 --> 00:01:41,503 You're a character in a world or maybe you're solving puzzles or the like, 37 00:01:41,503 --> 00:01:43,860 but they always seem to go on forever. 38 00:01:43,860 --> 00:01:46,370 And they change depending on how you interact with them. 39 00:01:46,370 --> 00:01:49,550 This is really the key difference between an infinite loop 40 00:01:49,550 --> 00:01:53,190 that's a bug versus an infinite loop that's been used properly. 41 00:01:53,190 --> 00:01:57,030 Now, the main key steps here really are processing input. 42 00:01:57,030 --> 00:02:00,592 So we need to take in keyboard input or mouse input or the like 43 00:02:00,592 --> 00:02:02,300 so that we can move things on the screen, 44 00:02:02,300 --> 00:02:04,590 we can select options and menus, et cetera. 45 00:02:04,590 --> 00:02:06,980 We need to update the game afterwards, which is usually 46 00:02:06,980 --> 00:02:11,060 a byproduct of processing input, and also calculating things like AI 47 00:02:11,060 --> 00:02:13,670 and velocity of things that we've set previously. 48 00:02:13,670 --> 00:02:17,510 This might happen multiple times, as is shown by the clock icon there, 49 00:02:17,510 --> 00:02:21,185 depending on how much time has passed since the last frame. 50 00:02:21,185 --> 00:02:24,310 And lastly, once things have updated, we want to render them to the screen. 51 00:02:24,310 --> 00:02:27,530 We want to actually show how something's xy position might have changed 52 00:02:27,530 --> 00:02:30,110 and maybe its color, maybe a bunch of things. 53 00:02:30,110 --> 00:02:33,320 And then as you see, at the very bottom of that is another arrow that 54 00:02:33,320 --> 00:02:35,190 leads back to processing the input. 55 00:02:35,190 --> 00:02:39,800 And this happens over and over again, oftentimes 60 times a second 56 00:02:39,800 --> 00:02:43,040 on most modern machines and consoles. 57 00:02:43,040 --> 00:02:46,340 So some important functions we should look at before we dive into the code 58 00:02:46,340 --> 00:02:50,330 are some of the most foundational functions using love. 59 00:02:50,330 --> 00:02:53,940 They are love.load, love.update, and love.draw. 60 00:02:53,940 --> 00:02:57,110 And now, love.load is really just a bootstrap function. 61 00:02:57,110 --> 00:03:00,242 It just has whatever you want to put into it to start your game, 62 00:03:00,242 --> 00:03:03,200 whether you want to maybe create some variables, initialize the window, 63 00:03:03,200 --> 00:03:04,910 as we'll see here pretty soon. 64 00:03:04,910 --> 00:03:08,240 Love.update is the update portion of our game loop. 65 00:03:08,240 --> 00:03:10,700 It actually lets you change things depending 66 00:03:10,700 --> 00:03:15,620 on this variable, this argument, called dt, which is short for delta time. 67 00:03:15,620 --> 00:03:18,050 We'll take a closer look at delta time in a couple 68 00:03:18,050 --> 00:03:21,140 of sort of iterations down the track. 69 00:03:21,140 --> 00:03:23,810 Love.draw is where you should just place anything 70 00:03:23,810 --> 00:03:25,910 that draws something to the screen. 71 00:03:25,910 --> 00:03:29,240 And behind the scenes, love will actually call love.draw 72 00:03:29,240 --> 00:03:32,870 after it calls love.update. 73 00:03:32,870 --> 00:03:35,690 Now, a couple of functions that are a little bit less foundational 74 00:03:35,690 --> 00:03:39,350 but are important to this iteration are love.graphics.printf, 75 00:03:39,350 --> 00:03:44,660 which is similar to print but is, like C's printf, customizable in as much 76 00:03:44,660 --> 00:03:47,960 as you can choose a few different ways to style your text-- 77 00:03:47,960 --> 00:03:50,480 centering it right, aligning it, and so on. 78 00:03:50,480 --> 00:03:53,000 And love.window.setMode is how we can get 79 00:03:53,000 --> 00:03:56,210 past just having a square window to having something a little bit more 80 00:03:56,210 --> 00:04:01,350 along the lines of modern screens, a 16:9 aspect ratio. 81 00:04:01,350 --> 00:04:02,783 So that's it for the explanation. 82 00:04:02,783 --> 00:04:04,700 I'm going to transition out of the slide deck, 83 00:04:04,700 --> 00:04:07,190 and we're going to actually implement pong0. 84 00:04:07,190 --> 00:04:09,990 So what I'm going to do is back in my Home directory, 85 00:04:09,990 --> 00:04:15,560 I'm going to create a new directory inside of Pong. 86 00:04:15,560 --> 00:04:18,380 I'm going to call this pong0. 87 00:04:18,380 --> 00:04:20,420 And then I'm going to just drag this over 88 00:04:20,420 --> 00:04:27,350 to vscode right here so that it opens up as a folder in vscode. 89 00:04:27,350 --> 00:04:29,630 And this is important for me because of that plug-in 90 00:04:29,630 --> 00:04:31,443 we talked about in the last lecture. 91 00:04:31,443 --> 00:04:32,735 I'm going to create a new file. 92 00:04:32,735 --> 00:04:34,930 I'm going to call this main.lua. 93 00:04:34,930 --> 00:04:37,712 Now, remember, love expects a main.lua file. 94 00:04:37,712 --> 00:04:38,670 This is very important. 95 00:04:38,670 --> 00:04:42,790 This is where it sort of bootstraps the whole entire game application. 96 00:04:42,790 --> 00:04:46,130 You can have other source code files, other lua files, other resources. 97 00:04:46,130 --> 00:04:51,020 But main.lua is sort of the main in C, where the interpreter, the compiler, 98 00:04:51,020 --> 00:04:54,000 just knows to go there to start your application. 99 00:04:54,000 --> 00:04:57,860 Now, we saw love.load before, and I'm just 100 00:04:57,860 --> 00:05:00,630 going to define a function using the function keyword. 101 00:05:00,630 --> 00:05:04,873 I'm going to call it love.load with curly braces, much as you've seen in C, 102 00:05:04,873 --> 00:05:07,040 and then the thing about lua that's different from C 103 00:05:07,040 --> 00:05:09,140 is that you do need this end keyword here 104 00:05:09,140 --> 00:05:12,950 to tell lua that this is the end of the function definition. 105 00:05:12,950 --> 00:05:15,980 Now, I'm going to do the same thing with love.draw, 106 00:05:15,980 --> 00:05:18,250 which we saw in the last example. 107 00:05:18,250 --> 00:05:20,660 In love.load, we're going to take a look back 108 00:05:20,660 --> 00:05:27,680 at title love.window.setMode, which is where we can actually 109 00:05:27,680 --> 00:05:30,710 decide how big do we want our window, our games screen, 110 00:05:30,710 --> 00:05:32,690 to be when we launch the application? 111 00:05:32,690 --> 00:05:35,780 Now, we haven't specified any variables or any numbers 112 00:05:35,780 --> 00:05:37,700 for how big we want it to be. 113 00:05:37,700 --> 00:05:40,430 But I'm going to define a couple of constants here. 114 00:05:40,430 --> 00:05:46,003 WINDOW_WIDTH equals 1,280 and WINDOW_HEIGHT is equal to 720. 115 00:05:46,003 --> 00:05:48,170 Now, these aren't technically constants in the sense 116 00:05:48,170 --> 00:05:51,650 that the interpreter will prevent me from assigning to them later, 117 00:05:51,650 --> 00:05:55,073 like we can do in C with const, but the fact 118 00:05:55,073 --> 00:05:56,990 that they are all capitalized with underscores 119 00:05:56,990 --> 00:05:59,420 tells the programmer that they are constants. 120 00:05:59,420 --> 00:06:01,010 They should be treated as constants. 121 00:06:01,010 --> 00:06:03,013 So in an honor system sort of way, we're going 122 00:06:03,013 --> 00:06:04,430 to be treating these as constants. 123 00:06:04,430 --> 00:06:05,840 They should not be adjusted. 124 00:06:05,840 --> 00:06:08,810 So what I'm going to do here is I'm just going to pass those into, 125 00:06:08,810 --> 00:06:12,410 and I'm going to just for size expand this out to full screen. 126 00:06:12,410 --> 00:06:16,790 I'm going to pass those two variables into the love.window.setMode function. 127 00:06:16,790 --> 00:06:19,040 And I'm going to make sure I spell height correctly. 128 00:06:19,040 --> 00:06:21,790 And then lastly-- and we alluded to this in the last lecture-- 129 00:06:21,790 --> 00:06:24,980 I'm going to pass in what's called a table to this function. 130 00:06:24,980 --> 00:06:27,260 Now, a table is very similar to a Python dictionary, 131 00:06:27,260 --> 00:06:29,270 where it takes in key value pairs. 132 00:06:29,270 --> 00:06:32,542 In lua, the table is really the only data structure. 133 00:06:32,542 --> 00:06:34,250 So whether you want to use it as an array 134 00:06:34,250 --> 00:06:37,760 or as a table or any other interesting combination thereof, 135 00:06:37,760 --> 00:06:40,110 you only have tables to choose from. 136 00:06:40,110 --> 00:06:43,370 In this case, we're just going to use it just like a regular key value pair 137 00:06:43,370 --> 00:06:45,050 dictionary or hash table. 138 00:06:45,050 --> 00:06:47,960 I'm going to specify that full screen should be equal to false, 139 00:06:47,960 --> 00:06:50,090 vsync should be equal to true. 140 00:06:50,090 --> 00:06:52,790 And resizable is going to be equal to false. 141 00:06:52,790 --> 00:06:54,410 And it's pretty self-explanatory. 142 00:06:54,410 --> 00:06:55,510 We don't want this to be full screen. 143 00:06:55,510 --> 00:06:56,802 I just want to show the window. 144 00:06:56,802 --> 00:06:59,460 Vsync just means sync it to my monitor's refresh rate 145 00:06:59,460 --> 00:07:00,980 so I don't see any screen tearing. 146 00:07:00,980 --> 00:07:04,070 And resizable just means I can't scale the window after the fact 147 00:07:04,070 --> 00:07:06,560 and distort the aspect ratio. 148 00:07:06,560 --> 00:07:09,350 Now, let's go ahead and save this and run this just 149 00:07:09,350 --> 00:07:10,490 to make sure it's working. 150 00:07:10,490 --> 00:07:13,030 And indeed, we can see that instead of a square-- 151 00:07:13,030 --> 00:07:15,830 it's a little harder to see maybe in front of the terminal 152 00:07:15,830 --> 00:07:17,400 here so I'm just going to hide that. 153 00:07:17,400 --> 00:07:20,000 But this is the window that we have now, just a black window. 154 00:07:20,000 --> 00:07:24,080 Nothing's being drawn to the screen, but it is indeed a 16:9 aspect ratio. 155 00:07:24,080 --> 00:07:25,260 I'm going to quit that. 156 00:07:25,260 --> 00:07:26,960 I'm going to go back to my text editor. 157 00:07:26,960 --> 00:07:29,240 And I'm going to go into love.draw where love 158 00:07:29,240 --> 00:07:33,770 knows that this is where you should place any of the drawing functionality. 159 00:07:33,770 --> 00:07:38,090 So what I'm going to do is I'm going to say love.graphics.printf Hello 160 00:07:38,090 --> 00:07:40,490 Pong, the string like that. 161 00:07:40,490 --> 00:07:43,413 And printf takes in sort of arguments a little bit 162 00:07:43,413 --> 00:07:44,830 differently than you might expect. 163 00:07:44,830 --> 00:07:46,640 So it does take an x and a y. 164 00:07:46,640 --> 00:07:49,460 Interestingly, I'm going to specify that x should be 0, 165 00:07:49,460 --> 00:07:53,120 y is going to be the window height divided by 2-- 166 00:07:53,120 --> 00:07:56,330 so it's actually going to be right in the middle vertically of the screen-- 167 00:07:56,330 --> 00:08:00,750 minus 6 because the font size is actually 12 pixels. 168 00:08:00,750 --> 00:08:05,510 So by going in the middle of the screen but in decreasing the-- 169 00:08:05,510 --> 00:08:07,398 sort of offsetting that by negative 6, we 170 00:08:07,398 --> 00:08:10,190 end up actually getting the font right in the middle of the screen. 171 00:08:10,190 --> 00:08:14,490 All things in love are drawn relative to their top left. 172 00:08:14,490 --> 00:08:17,090 So it's going to be drawn sort of shifted up 6 pixels. 173 00:08:17,090 --> 00:08:20,270 And because it's 12 pixels, that puts it firmly in the center. 174 00:08:20,270 --> 00:08:24,520 Now, the next argument is going to be sort of the width upon which 175 00:08:24,520 --> 00:08:26,480 we want to align this string. 176 00:08:26,480 --> 00:08:27,960 We want it to be centered. 177 00:08:27,960 --> 00:08:30,890 So the last argument's going to be the string literally centered. 178 00:08:30,890 --> 00:08:34,250 But we need to tell it how much do we want to center it within. 179 00:08:34,250 --> 00:08:36,409 We want to start it sort of at the left side, 180 00:08:36,409 --> 00:08:39,588 and I want to center it within, well, the WINDOW_WIDTH, 181 00:08:39,588 --> 00:08:41,130 because that's how big the window is. 182 00:08:41,130 --> 00:08:44,430 And we want it to be exactly right in the middle of the window. 183 00:08:44,430 --> 00:08:47,570 So I'm going to say a WINDOW_WIDTH there for these sort 184 00:08:47,570 --> 00:08:49,460 of column size of our centering. 185 00:08:49,460 --> 00:08:53,610 And then lastly, I'm going to specify the string center just like that. 186 00:08:53,610 --> 00:08:55,800 And then I'm going to run the application. 187 00:08:55,800 --> 00:08:57,860 And we do it in [INAUDIBLE] Hello Pong written 188 00:08:57,860 --> 00:09:01,040 right in the middle of the screen, almost illegible because it's so tiny. 189 00:09:01,040 --> 00:09:02,720 It's 12 pixels. 190 00:09:02,720 --> 00:09:04,730 But it works just as we expected it to. 191 00:09:04,730 --> 00:09:06,000 And it's very simple. 192 00:09:06,000 --> 00:09:09,620 And now it actually is a little bit more modern in the sense that it'll fit. 193 00:09:09,620 --> 00:09:14,690 We could full screen this, and it would fit most modern desktop screens. 194 00:09:14,690 --> 00:09:18,650 So that was a very simple sort of day0 update, pong0. 195 00:09:18,650 --> 00:09:21,020 Pong1, we're actually going to take care of the fact 196 00:09:21,020 --> 00:09:22,760 that our text is really tiny right now. 197 00:09:22,760 --> 00:09:23,718 We're going to zoom in. 198 00:09:23,718 --> 00:09:27,470 We're actually going to sort of stretch our raster, our smaller texture raster, 199 00:09:27,470 --> 00:09:33,800 to fit a 1280x720p window to give us a bit more of a retro sort of NES Super 200 00:09:33,800 --> 00:09:35,000 Nintendo era look. 201 00:09:35,000 --> 00:09:38,860 And we'll take care of that with the low-res update in pong1. 202 00:09:38,860 --> 00:09:40,000