SPACE INVADERS FROM SCRATCH (PART 2) – CS50 on Twitch, EP. 22

COLTON OGDEN: Hello, world This is CS50 Twitch My name is Colton Ogden And happy 2019 Happy new year to everybody Whether you’re new or a regular from last year, welcome to our Twitch channel where we do sort of live coding, demos, tutorials, explanations, and all– excuse me– all kinds of stuff We might even get into some hardware-related stuff if some of the staff is privy to that sort of thing We’ve got a bunch of people in the chat I’m going to say hello as usual to everybody who’s here with us already And let me know if I sound OK We just completely re-setup our stream setup We took all the stuff that we had setup in this room, on our streaming room last year in December, we took it all, basically, and used it for the fair, brought it back, and then reset a lot of it up today So hopefully everything looks and sounds like it did last year if not better But definitely let me know if not I’m going to go through the chat here really fast, just to see who joined us here to begin with Looks like MKloppenburg, a regular from last year when I was doing a little test message This test received [? BavikKnight, ?] another regular Hey, everyone Hi How is everybody? Happy 2019 to everyone Happy 2019 to you as well. [? SewerTon, ?] who just followed, actually Thank you very much for the follow Hello, CS50 family with the popcorn emoji They say– Buddy2610, sup? Nice Oh, I can’t read that name at all The Gangus– oh, that’s the GangusGoat19 Also thank you for the follow I see GangusGoat19 just follow as well Thanks to everybody who followed over the break It looks like there are about 200 people that followed while we were not streaming over the winter break So I was in California I was far away from Boston over the winter for the last three or four weeks or so visiting family Back in Boston, it’s very cold today It was fairly nice temperature for the last week or so, and now it’s, like, 20 degrees today It’s freezing [? KiraU, ?] with the two clown faces, thank you [INAUDIBLE] smiley faces TuxMan29 [? int ?] new year, last year Return last year plus equals 1 That’s TuxMan29, a little bit– a little code snippet for everybody to increment the year And then [? SuraTon ?] is another thing It’s basically saying, if last year is null, age is 1, right? Because if we weren’t any year– if we weren’t any age last year, null is not a valid a valid age, so we need to be at least 1, right? [? BellaCures, ?] happy 2019 [? ForSunlight, ?] hello Colton, the regulars, and all, thank you very much Let me see, make sure I’m not missing anybody Didn’t do the assignments yet, but watched most of it and worked with [? Django. ?] Oh, that’s for the– talking about Brian’s web dev class, yes Brian actually may be in the chat today He and I chatted before the stream started [? SerotonOFX. ?] Hi, Johnny Bravo [? OFX is ?] surely a reference to my hair It is a little Johnny Bravo looking I need to get a haircut, like, super badly I haven’t gotten it cut for, like, a month It’s pretty insane Man, some of these names are hard to read because Twitch puts them in this really obnoxious blue font on black M [INAUDIBLE], hi, Colton I hope I’m pronouncing that right I’m probably not pronouncing that right Sounds good Hello, regulars Hello, everybody OK, awesome So I think I got everybody that was in the chat Thank you all so much for tuning in Looks like my head’s getting cut off I think the camera might be a little too zoomed in, but that’s OK Today’s stream is on Space Invaders Let me go ahead and switch my screen to the full view here And this is sort of where we left off last year And I noticed that the GitHub repo was actually from November So if you’re in– if you want to basically get the code base that we work with last November, I’ll write the URL here in the chat Actually, if I do that it’s going to screw up the chat overlay Basically, it’s Coltonoscopy– GitHub.com/coltonoscopy, that’s my GitHub handle, slash space dash invaders dash stream And then that will give you the code base that we worked with last year in November where we basically had the following working Let me go ahead and run this So it’s not really super feature rich yet We do have a ship that can move around And if you press spacebar, you shoot lasers You shoot projectiles But it doesn’t do anything beyond that The projectiles don’t collide with the ships, and the ships are static They’re basically just sprites that are being rendered And that’s pretty much– that’s pretty much it That’s pretty much all that’s going on One second But yeah, not a whole lot really going on there But today’s goals are– we have a few goals, actually First goal is actually get the ships to do something, to move around left and right The next goal will be once they’re moving to actually have the projectiles collide with the ships in order to trigger a death, essentially, and to give us some sort of score

And then another thing that we want to do is the game is currently in just a single state where we sort of start the game up, the ship’s there, all the enemy ships are there, and we do stuff But there’s not really a title screen There’s not, like, a game over screen, anything like that So I would say that our goals today are sort of triple faceted We want to get the ships to move, get the ships to sort of come down towards the player, move left and right, which is how it worked in the original Space Invaders Then we want to have the projectiles that we shoot from the player not only dispose of themselves after they’ve gone past the edge of the screen– for performance reasons if we just let an unlimited number of projectiles exist when we shoot, eventually, we’ll theoretically run out of memory Although they would be very difficult to do that because the projectiles currently are so small I’m not sure exactly how many bytes they take up offhand But relatively few per projectile But it could eventually end up slowing down the game And they’ll exist and they’ll update every single frame And really, the updating of the projectiles is probably going to be more of a performance issue than the Memory Cost because in our code, and I have to sort of remember how this all works But we do have– make sure it’s an update In our update function online 51 to 53, and I’ll answer some of the questions in the chat in just a second But on lines 51 to 53, we have this sort of for loop that says for every projectile in a table of projectiles that we have created in advance, an array of projectiles, you can think of it as, we want to call this update functions Update function essentially just moves a projectile up or down depending on its orientation, whether it’s going up, or it’s going down, whether it’s going towards the enemies, whether it’s going towards the player And so for every projectile we add to this array of projectiles, it’s going to add more work that gets done in this loop And eventually, this loop could get cumbersome and bring us down from 60 frames to maybe 58 frames, 40 frames It would take a lot of projectiles to do that I’m sure it would take thousands of projectiles, but it’s something that feasibly could be done So essentially, what we want to do is when a projectile goes beyond the edge of the screen if it doesn’t hit an alien, we want to get rid of it We want to just essentially set it to nil on the table or repurpose it You can use what’s called an object pool We’re just going to delete it, essentially, and then just create new ones as we press spacebar And so we’ll only ever have maybe 5 to 10 projectiles max on the screen at one time But that’s something that you want to take into consideration If you’re spawning objects, you want to de-spawn them, sort of like freeing memory in C. Whenever you alloc memory, malloc memory, you have to free it in order to prevent memory leaks It’s kind of the same idea, although a little bit more complicated in this sense, because you’re actually dealing with things that are taking up CPU cycles that are moving and doing stuff every frame But that’s the projectile side of it The ship side of it we just need to have a loop where the ships kind of move left and right and come down when they’ve moved all the way to the edge of the screen until they reach the player, essentially And then the last part we’ll be using what’s called the state machine, which is a very important concept in game programming which allows us to divide up our game into multiple different states that function sort of as modules For example, a title menu state, a game state, a game over state Rather than put all this logic in our main.lua and bloat it unnecessarily, we can divide it up using a state machine class which we’ll implement from scratch here a little bit And this is a very effective technique for modularizing your code And you can use it to not only create states for the game itself, but for individual entities within the game For example, an entity might be in an attack state, or an idle state, or a moving state, anything that you can think of If you can create a state for it and piece it out, it makes your life a lot easier when you’re dealing with the actual editing of the code And you can let other people, therefore, edit different states independently [? BevIgnite is ?] saying, yeah, he’s in the CS50-W course, the web course right now, on hold, concentrating on algorithms course of Princeton, taking on a massive load KirbytheDonkey says, what language are you using? This is in Lua So Lua is a scripting language We are using Lua and also LOVE 2D, which is a framework and sort of an engine for developing 2D games using Lua Lua is the language, LOVE 2D is the actual framework, the functions, and the runtime that allows us to do all of the things that we can, all the graphics, and sound, and input, and all that stuff If you haven’t downloaded it already, go ahead and go to love2D.org and grab the version most appropriate for your operating system And also, watch the– if you haven’t seen this, for the first part of the stream, you might want to go back and look at part one because this is a continuation of that And we’re using that code and sort of building on it and adding the new features But that’s on our Twitch channel and our YouTube You can look up CS50 on Twitch Space Invaders You can go on our Twitch [? VODs ?] and pull it up there But we have all of the stuff that we did in November of last year of the Space

Invaders is part one on GitHub, the Space Invaders stream, so you can clone that code and also add the stuff that we’re going to be talking about today to that And TuxMan29 also said the same thing Andre says, Unity’s animator controller is essentially a state machine, although it does allow blending animation so not strictly a discrete state machine Yes And Andre [INAUDIBLE] actually made a clone of a game that I created for our games course using those animator controllers If I’m not mistaken, you used those to sort of replicate that in Unity 2D, which was a really cool project I saw it on Facebook and I believe I commented on it I’m not 100% I believe I commented on it, definitely hearted it, or liked it, one of the two But yeah So thanks everybody for joining If you have any questions, definitely toss them in the chat Watch the prior stream if you’re not familiar with this stuff, maybe before digging into this one On Thursday, we’ll have– sorry, on Friday, we’ll have a completely different kind of stream with David David will be joining us to talk about Docker So that’ll be very interesting And then we’ll get into our routine again where we have these weekly going forward, although the schedule itself is kind of in flux at the moment So the three goals, again, to recap, get the ships to move, to get the projectiles to collide, and then get the game to exist in multiple different states, not just a regular game state So the first thing that I probably want to do is work on the aliens, get the aliens to actually move left and right And right now, if I just rerun the game– and again, for those unfamiliar with this, I’m using VS code as my editor You can use whatever editor you want It has built in macro for running LOVE 2D from the text editor itself You can hit command L or alt L on a Windows machine in order to do it And I think on a Linux machine you can possibly do something similar So I don’t have to click and drag my main.lua or my folder onto a shortcut on my desktop, or whatnot, or on my dock I can use a command L, run the game, and it’s super fast So I highly recommend VS code for that reason for LOVE 2D development So currently, these are the ships These are the aliens in question And I want them to sort of move from top to bottom– top to bottom, left to right, sort of back and forth, not like a scan line, strictly speaking, but kind of like a bi-directional scan line in that it will kind of go like this, almost like a snake style movement pattern, which is how the function in the original Space Invaders, if I’m not mistaken, which is a project that we created for the games course last spring, 2018 spring So essentially, what I want to do is I just want these on a tick, on sort of a frame, a time interval, to move maybe 50 milliseconds, 100 milliseconds That might be too fast Maybe 300 or 400 milliseconds I want the ships to move in little chunks And then once the far right alien has touched the right side of the screen, they should all come down and then start going the other direction, then head down and go the other direction, and so on and so forth So I kind of want to, in that case, check to see– we have kind of a for loop to check to see if the direction the aliens are moving is right, check the far right alien If the far right alien is at the edge of the screen, move everyone down, set the direction to left, and then do the reverse logic when the aliens reach the left side of the screen Check to see if the far left alien is at pixel zero If it is, bump them all down and then set the direction back to right Andre says, yep, exactly We used your course as assets for [? breakout ?] and use the animator controller to actually control the game’s states Yeah, I thought that was a super cool re-implementation of that project from the game’s course So thanks for doing that If you have a link to it or to the medium article you guys wrote about it, definitely tossed that into the chat so everyone else can take a look at it But yeah, so let’s go ahead– I haven’t done too much review of the code base since we last looked at everything So let’s just go ahead and take a look at what we have going for us here We have the ship class So the ship class was what we use to actually control the player, and it just moves left and right So that’s why we have an if, else/if for moving left and right If love.keyboard is down left, then say your Rself.x to be no farther left than pixel zero using math.max If love.keyboard is down right, do the opposite with math.min, making sure it doesn’t go past the right edge of the screen minus the ship’s width Alien size is the constant that we use for that And then if we press the space key on our keyboard, notice that here we’re doing table.insert Remember, in Lua, table.insert is how we add something to an array or a table They’re all tables, but we can sort of conceptually think of them as arrays or hash maps depending on the particular use case In this case, table.insert is going to insert into something

that we’ve called projectiles which we pass into ship update up here Projectiles is being used as an array, I guess more like a python list than an array, like a c-array, technically speaking Because when used like this, when using table.insert, it will dynamically grow, but arrays don’t dynamically grow, at least in C, most static languages So in this case, we’re using it as a list and we’re just creating a new projectile using this constructor here, projectile taking in our self.x and self.y minus projectile length so that it spawns at the top of the ship, at the ship’s position And then notice that we’re passing in a string up, which is just how we decide we want to tell this constructor which direction that projectile should go Should it go up? Should it go down? You can use strings You can use integers You can use constants that you have defined to be strings or integers, however you want I like the readability of strings And it’s actually fairly– what’s the word I’m looking for? There’s a word I’m looking for to describe whether something is often adopted in a particular ecosystem or community Conventional That’s what I’m looking for I can’t think of words too well It’s conventional in the LOVE 2D scene to use strings that tell the function or the constructor how something should operate For example, love.graphics.rectangle is a function that will create– will draw a rectangle on the screen And the first argument of love.graphics.rectangle, like so, is a string that can be either fill or line And so that’s an example of using a string in the LOVE 2D ecosystem And that’s why I tend to like to do that sort of thing as well Oh, yeah Andre’s saying [INAUDIBLE] using the animator controller state machine on medium and posted the link in the chat there as well as they GitHub link for the project, so check that out If you’re interested in Unity and interested in state machines and breakout, which is a game that we implemented in the games course Definitely check that out It was super cool when I saw– Unity is a really awesome really awesome editor, really awesome tool So this is the ship class So this is where we create our– and really, our ship class is almost completely done at this point We will need to check to see if a bullet collides with us But we can do that in our main.Lua And if it does collide with us, then we want to essentially lose a life and go to the– we can make a simple version and go to straight to a game over if we get hit one time, but in actual Space Invaders, you have multiple lives And so what we want to do in a fully fleshed out version of this would be to go to a separate screen that just says, you have two lives left, or three lives left, or whatever, current score, and then after maybe three seconds, go back to the game, which is kind of how the actual game works The projectile class is here The projectile class is pretty straightforward It takes in a xy and a direction, which we just looked at from the ship class So self.x is x, self.y is y Pretty standard setting member variables of this class If you’re unfamiliar with object-oriented programming, you can think of a class as a blueprint for how an object should behave, what parameters it should take, the functions that define how it should operate It’s fairly common in games to have classes that all have an update and a render function so that in your main.Lua, or wherever your main game loop is, you can just iterate over every object in your game and call update in the update loop, and call render in the draw loop And if we go to main.Lua, for example, we can see we do have a update function here Functionlove.update takes a delta time parameter, DT This is provided by LOVE 2D And in this, we can see that we do call ship update, which is from our ship class We call a for loop on all our projectiles, and on each projectile we call update And then we do something here where we reset a global table for keyboard input so that we can test for discrete keyboard input outside of main.Lua And if you’re unfamiliar with all of this stuff, a lot of it is explained in much more detail in the first part of the stream This is not an advanced stream, I would say, but a more intermediate level Certainly if you’re going into this blind, I would check out the first stream a little bit more It’ll go on YouTube if you want to watch the first stream and come back to it later So definitely feel free to do that But paired with that update function, very importantly, is our draw function, love.draw And these are functions that LOVE expects to exist in your main.Lua file And note that we are indeed looking at our main.Lua file This is the main.Lua file, hence the name, that LOVE 2D looks for when it runs your game So this is sort of the starting point, just like in a C program where you’re looking for the main function or a Java program,

where looking for the main function in a class, or even Python if you’re running a module and you have if name is equal main The same idea Main.Lua is that starting point and it expects a certain set of functions to exist And if you don’t define them, your game will not run them, and therefore, it will not function like you want to function Love.draw is a function that just is supposed to take care of all the drawing stuff to the screen So everything updates first and then everything draws to the screen, right? So you move your ships, you move your projectiles, you figure out if things have collided with each other, and then you draw them to the screen, or you don’t draw them if they’ve been, for example, removed from the scene because maybe your ship got blown up, or an alien got blown up, or a projectile is off screen You don’t draw anymore, right? So here we are calling push start and push finish at the start and end, which just gives us a virtual resolution Again, we cover that in the first part of the stream We clear the screen We do a loop over all the projectiles just like we did in update, but in this case we’re calling render on all of them And render’s job on each class that we define it is just to draw whatever class it belongs to, draw that information onto the screen In this case, we’re setting our color to red or using a rectangle, again, love.graphics.rectangle, which we just looked at Takes in a fill string, x and y This one is a– I’m trying to remember That’s the width in pixels, so we want a one pixel wide rectangle and then a projectile length y length, height, of our rectangle [INAUDIBLE] width and height And I guess one should probably be projectile width as well, a constant, but since it’s just one, I guess I thought one would be good enough Nuwanda3333, that’s [? Aslee. ?] Says, hi Colton and everyone Thanks for joining us, [? Aslee. ?] Good to you again Happy new year And here, we see that we’re setting our color to 1111 after we finish drawing the rectangle, and that’s to revert our color– our sort of global state for LOVE 2D It always has one color to draw stuff with at a time We set it to red here We draw the rectangle And then, on the line after the rectangle, we set it all ones, which is all white So the newer LOVE 2D versions, LOVE 11 and onwards, they use from zero to one to create colors You might be familiar with RGBA, which takes in– well, RGBA is what we’re using, but you might be familiar with 256 valued RGBA So start at zero, end at 255 That’s how LOVE 2D used to do colors So in the old version, you would say 255, 00, 255 And that would be the same thing as the current version of 1001 But in version 11, they changed it all from zero to one floating point values So I could say, 0.1, I could say 0.15 It’s more efficient I have to dig I’d have to look back at the reason as to why exactly they had to do it From what I remember reading about, it’s a performance reason, and it also helps with shaders And underneath the hood, it’s just more performance But offhand, I don’t have the exact reason People are joking in the chat about bringing me pizza from an old sort of stream we had, where [? Aslee ?] kindly offered to get pizza for everybody, which I’m not sure of that offer still stands Hopefully it does Also, I think we were looking at projectile Earlier, before we went back to main.Lua, the projectile update function is just an if-else statement that basically says, if our direction is up, then every time we update we want to essentially decrement our y position, which is what we do here So if that y equals up to y minus projectile speed times delta time– again, anytime you need to update something in a game, or at least in LOVE 2D– typically, in most games– in order for it to run at a consistent frame rate, every time you move something or do something that can be variable, you want to multiply it by some constant value– some value that’s dependent on your frame rate– in this case, delta time Delta time will be different depending on how many frames have elapsed since the last frame, whether it’s usually one Sometimes it can be two or three It’s some floating point value that you can scale movement by so that two computers at different speeds will run your game, and things will move at the same speed, even if one is more jittery than the other one, essentially And that’s why we are multiplying projectile speed times delta time So that’s the projectile class, the ship class The alien class is empty The entity class is fairly empty This is the base class from which we inherit– the base class which we superclass the alien class from So we notice in this particular module, alien gets class This is the library we’re using to use object-oriented programming in Lua

It’s not something that you get by default Again, I apologize if all this is a little too much review I just want to make sure we’re all on the same footing, and this also kind of helps me remember the code base a little bit more But alien is a new class, and it includes everything that’s an entity And this is part of the class library that we used last stream So includes entity, and this is the class from which we want to take all the stuff that exists in that class and create a new class from it So entity is this class So aliens all have this constructor, xy sprite And they also have this render function, which draws from our global textures variable in our dependencies This is dependencies.Lua and it has all of our libraries here, using require statements It also has a global textures table here, so we can store all of our textures– all of our 2D images And then, we can store our frames, so all of our actual sub-images on those textures And we talked about this last stream, as well In this case, we’re just using an image in our graphics folder [? SewerTon ?] says, I’ve just downloaded the 2D engine What was the name of the editor you were using? I know you mentioned it, but sorry, I forgot the name No worries, [? SewerTon. ?] It’s VS Code– so Visual Studio Code It’s a very popular Microsoft editor You can get it by going to Code.VisualStudio.com Super awesome text editor You can also use Atom You can also use Sublime Text They all sort of have the same feature set, but different plugins, often I haven’t used Atom in a little while I imagine they’d probably have something similar to the plugin that I’m using for Atom If you want that plugin, it’s the pixel byte plugin So if you go if you’re in Visual Studio Code and you go to the extensions area, get the LOVE 2D support plugin by Pixel Byte Studios Awesome plugin, super recommended if you’re doing any LOVE 2D development Let’s go back to here Click there So this is our dependencies file– stores all your dependencies, all your libraries, all your textures, all your sounds, all your frames– everything that you want– all your assets and libraries I like to put them in a dependencies file, but you could also just put this all in your main.Lua and it would be totally fine– not what I would recommend, because then it gets a little bit bloated I try to keep my main.Lua fairly clean So notice it only has, at the top, require source dependencies, which basically imports all that stuff that we defined in dependencies.Lua And then, we just have all the core functions that we need for our game engine, all the core loops, and then we defer all the actual logic as much as we can to the classes themselves– the projectile class, the ship class, the alien class, entity class– all that stuff And our main.Lua file ends up being currently less than 100 lines of code It will probably be a little bit more than that eventually– hopefully not too much In our main.Lua, the actual aliens themselves get generated in our LOVE.load function So LOVE.load is a function that exists at the beginning– it doesn’t have to exist in the beginning of the file, per se, but it triggers at the beginning of your LOVE 2D application running So before you start updating, before you start drawing and checking for input, you’ll call LOVE.load LOVE 2D will call it for you You have to define it But this is all the stuff that you want to happen before you update, before you start drawing all that stuff In this case, we do a bunch of initialization We set our filter to nearest, nearest, which allows everything to be very pixelated And actually this, I realized, needs to go in dependencies.Lua before we actually import any graphics So what I did was, I took that LOVE.graphics– that’s that default filter function– and I put it before we load any textures, because on certain computers, what this will do is, even though you call a default filter nearest, nearest, we were doing it technically after the texture was loaded And as a result, certain computers will show the aliens as being blurry So put this before we actually load the textures to prevent that issue And I took it right out of my LOVE.load function, here There will be no change on my computer, because for some reason it works fine on my computer The nearest thing doesn’t cause any issues It might be a result of the push library overriding that But on certain computers, if you’re using a newer version of the push library, or your graphics card is funky, it will look kind of blurry So if that happens, just do what I just did OK The moment you toss pineapple on a pizza, it becomes a sandwich and not a pizza, says MKloppenburg We’ve got a war on pizza in the Twitch chat Yeah, a long pineapple pizza conversation going on– which is good

stuff DanCoffeeCCD is Dan Coffee who did a stream last year on Draw 50, which is an awesome tool which we actually used, I think, last Space Invaders stream Is a huge fan of pepperoni pineapple, so if Dan’s looking in the chat, shout-outs to Dan and his pepperoni pineapple pizza I’m not sure if that’s been mentioned– if pepperoni pineapple specifically was mentioned I think just pineapple and pizza generally were mentioned So anyways, back to LOVE.load, which was where we initialized all of our aliens We also initialized our ship And actually, shout-out [? Aslee ?] and Bhavik, who are in the chat right now We, last stream, ended up having a mini war on which ship we wanted to use at the start of the game– the player ship So I think if I run this over and over again, we see right here, this little ship here– this little red ship is going to potentially change to a another ship if I keep running it It’s random Yeah, so right here So I don’t remember offhand which one [? Aslee ?] chose and which one Bhavik chose, but they both had a different ship that they wanted to use, and we ended up using a little math.random two, which just gives you value between one and two And basically, used a ternary– Lua’s ternary statement, which is an and-or– well, a conditional and then an and and an or And then, what we ended up doing was, the game will randomly choose between [? Aslee’s ?] ship and Bhavik’s ship And their ships are just frame indices So if we look at our file here– let me go into Space Invaders, graphics, aliens I think was aliens six– no, it was aliens 12 I believe I’m not 100% I have to re-look and see Was it 12? It might have been Oh yeah, it is 12, because I recognize the ship here Essentially, all of these individual ships on this one texture– this one 2D image– you can split this image up into rectangles, and it’s called using a sprite sheet In LOVE 2D, they’re called quads They’re rectangles that define a sub-image on a 2D image And what we can do is, we can assign each of these an index between one and however many ships there are, counting top to bottom, left to right And by drawing our 2D image in LOVE 2D, and then referencing a quad, we can draw that sub-image And all the quads are– we split it up by 12 by 12 pixels and then put them into a table, so a one-dimensional table And so therefore, it’s from one to– I think this is 1, 2, 3, 4, 5, 6, 7, 8 It’s 16 by 16, 256 ships long So between one and 256 By sending a particular index and then drawing LOVE.graphics.draw, we can draw a particular sub-image And so that’s what we’re doing here We’re getting an index So we calculated the number We figured out what row it was on– 16 times three, and then the sixth one over is 16 times 12 And then, the ninth one over So third row and then the 12th row And that’s effectively how we did that That’s what that bit of code is there fore We instantiate a ship We put it in the middle of the screen, which is what this logic here does– virtual width divided by two, minus alien size divided by two Alien size is, I believe, 12 pixels All of the capitalized things are in constants.Lua Excuse me Constants.Lua is a good place to store constants Constants are just variables that should not change Lua does not enforce using constants, so you have to kind of use programmer, I guess, heuristics in order to use constants appropriately In this case, we do that by capitalizing– as is conventional amongst many programming languages– the variable name, and using underscore notation So anything that we see that follows this variable naming convention we can assume is a constant, and should not be assigned a value, only used read-only in our code In this case, alien size is a constant It is 12 pixels Virtual width and virtual height are the dimensions of our virtual resolutions– so how we make our screen look as if it’s retro, even though it’s not And there are some other ones here– projectile length We don’t have a projectile height, but just for good measure, projectile height is one And then, we can use that in the future when we reference that Yeah, Colton being very diplomatic about the ships It’s very important that we embrace everybody’s opinions Well, he multiplied it in a second Someone brushed on math during the holidays Oh yeah, because last year I was not able to, on the fly, figure out what 16 times 16 was And I was made fun of for it It’s 256– something that most programmers should probably know, and I was not included amongst that category of programmers, unfortunately

OK, so I think we’ve done a rough recap The last thing, I think, that we need to talk about is the actual loop here that initializes the aliens In this case, alien is just an inherited version of entities So it’s not really that different from an entity It’s actually pretty empty class And what we’re doing here is, we’re instantiating it at an xy with this four loop– aliens tall, aliens wide That’s how many aliens fit on the screen Sorry, that’s not how many aliens fit on the screen That’s how many aliens we want in our set of aliens We’re doing a nested loop, just kind of like how we do Mario, for y is one to aliens tall, which aliens tall is– we decided will be five So we want five by 11 aliens We do that in an yx loop, and then we insert an alien into our aliens table Aliens just another table, just like projectiles, sort of stored the same way or functioning the same way and that it’s one-dimensional and that we just iterate over it Each alien maintains a reference to its own xy position And alien is a class, which takes in an xy and a frame So frame is the number between 1 and 256 that maps to our 2D texture– all of our quads, right? And our quads, again, are this G frames table on line 22 in dependencies.Lua On line 23, we can see we’re assigning aliens– the index string aliens to the result of a generate quads function, which we wrote last week– not last week It feels like last week– which we wrote last November If we go to util.Lua That’s where our generate quads function is It just splits up a texture into quads based on how wide and tall each sprite is In this case, the sprites are 12 pixels by 12 pixels [MUSIC PLAYING] So that’s how we split it up Curehavenomana, thank you very much for following Hope I pronounced that right I imagine I did pronounce that right And [? 08Rock, ?] if I missed you, I apologize Thank you very much for following, as well All right, so I think that’s a fairly solid recap I apologize if that was a little bit cumbersome for everybody if you’re already familiar If you’re brand new to the stream or brand new to this game, then that might be of some help Certainly, I need it getting back into the code base But I think we have enough information now to where we can decide how we want to go about moving our sprites, right? So the first thing that we can do is, in our main.Lua, we do have access to the– we have access to all the aliens, right? So what I can do is– and we probably want this to be in our update function So the first thing that we can probably do– well, first, first thing that we should do is, we’re going to need a variable that keeps track of which direction the aliens are moving in, right? Because they can move to the right, they can move to the left– your right, my left To the right to the left So what we can do is, I can just call another variable And ideally, this will all be sort of encapsulated within a game state And we’ll talk about game states a little bit later And maybe even in future streams, we’ll implement things from a more state machine-focused approach from the beginning, as opposed to this sort of ad hoc everything in main approach But we kind of have to work our way up there, I feel like it, as it might be a little bit too much to jump into that right off the bat But what I want to do is, I want to create a variable called alien direction And I’m just going to assign it a string called right And again, using strings as the way of classifying our variables, because strings kind of make sense Oh, they’re talking about the sound MKloppenburg, and Nwanda, and Andrej says, the same song from Khan Academy for following? Yeah, it’s– I had thought that we had used that follow sound for a long time It may be the case that you all didn’t hear it prior to this stream when we reconfigured our audio setup a little bit But yeah, that’s just the follow sound that OBS, or I guess Twitch lets you have in your channel every time someone follows or subscribers, all that sort of thing So it’s a nice little sound effect I like it When I hear it, I have monitors back here, so I know that somebody has followed So I can look up at the screen and see and thank them So that’s pretty great So we have a variable called alien direction that we’ve declared in main.Lua, which is going to be the direction that the aliens move each frame until they reach the end of the screen And then, it should get set to the other direction When it gets set to the direction, they should move to the other side,

check to see if they’ve reached that end, and so on and so forth And then, when the do reach either end, they should all move down They should get closer to the player That’s how the game works– the actual Space Invaders game works So I can say if alien direction is equal to right– again, just comparing it directly to the string right, because that’s going to equal either left or right Excuse me And I’m going to preemptively say an else here It can only be right or left, so we don’t need any we don’t need another conditional statement We can just say else What I want to do is, I want to set every single alien’s position to the right just a little bit Well, I should say, I don’t want this to happen every frame I want to actually be on a timer So what I should do is– and do I want this to be using a timer library? Probably not Probably not yet That might be a little bit too much So I’m going to say, alien movement timer is zero And then, I’m going to say, in our constants– I don’t have constants open Constants.Lua, I’m going to set a alien movement interval [MUSIC PLAYING] That startled me a little bit Djoker07, thank you for following That name looks familiar I thought that Djoker was already falling, but if not, I apologize Alien movement interval, I’m going to set that to be– this is in milliseconds Is it in milliseconds? No, I think LOVE 2D measures DT in fractional seconds So let’s say I want the aliens to move every 0.4 seconds And again, this is a constant This isn’t going to change I could make this a variable that does change if I wanted the aliens to move faster the closer they get to the player, which is kind of, I think, how it works in– no, that’s not how it works in Centipede I don’t think so I think it just looks like they’re moving faster I don’t remember offhand But basically, it’s going to be a constant in this case And the timer itself is going to keep track of how much time has passed each frame And we’re going to add to it And once alien movement timer is greater than alien movement interval, which means 0.4 seconds have elapsed, then I should move all the aliens to the right or to the left, do the condition to check and see if they’ve reached the edge of the screen And then, I’m going to reset the timer back to zero, or at least back to timer minus alien movement interval, in case they went over 0.4 just a little bit, right? And shout out to David in the chat He says, thanks for tuning in today, everybody Thanks so much for tuning in, as well Djoker07 says, happy new year, Colton Thanks, Djoker, very much appreciate it Everybody’s talking about their amount of RAM– 16 gigs If it’s in idle, it won’t take any RAM, says OneDayMyLove I might be lost in the conversation there Oh, two instances of unity, open, plus one instance of blender And everybody’s saying hello to David Awesome Cool, cool So we have a timer now We can keep track of how much time has elapsed since the last frame We can cumulatively add this until we’ve gone past that amount of time So what I’m going to do is, before I actually– well, I’m going to keep the if statement there, but it’s actually going to be nested within my other if statement I can say, alien movement timer gets a movement timer, plus DT, right? Remember, DT is a variable that we get every frame passed into LOVE.update by the LOVE 2D framework And this is going to be measured in fractional seconds So it’s going to be 0.013, 0.0013 I forget offhand I think it’s 0.013 And if alien movement timer is greater than or equal to the constant that we’ve defined, which is alien movement interval, then– and this is where we nest that bit So I say, if alien direction is equal to right– so they’re going to the right What we need to do is, we need to increase every single alien’s x position, right? So that means we need a loop So I can say, four_alien in pairs, aliens do alien.x is equal to alien.x plus– and then we have to figure out how much we want to move the alien by So I guess we can say, alien size, alien step length We’ll call it that, alien step length And we’ll say that’s going to be five pixels I’m not entirely sure A lot of this you’re going to have to kind of do by feel, too, especially if you’re doing things that are based on time when you’re moving stuff, getting speeds right It’s a little tricky to kind of guess everything correctly right off the bat unless you know your specs in advance

I don’t know the specs advance, so I’m just going to take a guess And then, we can fine tune it as we need to go along And this has a role to play in game balancing, because this movement of the alien x– if it’s too small, the game will be too easy, because the aliens will take a long time to get to the bottom of the screen If it’s too big, the aliens will get to the bottom of the screen really fast, and as a result, it’ll be harder for the player to defeat all of them in time So we need to sort of keep this in mind as we’re balancing the game out– tweak it, play test it, and get a sense of it This is part of the QA testing side of making a game So we’re going to say, alien step length So we have alien.x is equal to alien.x plus alien step length In this pairs function, again, is how you iterate over tables in Lua So it takes in a table, in this case aliens, and will give you every single alien, every single key, and every single object within that– every key value within that table In this case, all the values are aliens– alien objects So we do that here And then, we do the same exact thing here, right? Except instead of setting the alien x equal to alien x plus the step length, we want to minus the step length so they move to the left instead of to the right And again, it’s mirrored to you to To the left, to the right, but I have to think of it the opposite way I can’t see that name It’s in black text WinLogon, happy to be here, taking 650 GD at edX Awesome Thank you so much Well, glad to have you with us WinLogon? WinLogon? I hope I’m pronouncing that correctly I’m probably not Colton’s saying, cool Colton’s sounding Jake Peralta I’m not entirely sure that is I should look that up Cool So this is how we move the aliens on a timer And then, once we have moved all the aliens, we want to set alien movement timer to alien movement timer minus– what’s it called? The alien movement interval That way, in case we do go over 0.4 to, like, 0.41, or something similar to that, it’ll take that into consideration– that overlap into consideration, and we won’t kind of get extra time added to our loop, which is what you do if you just set it to zero and don’t account for that overlap Alien movement timer gets alien movement timer minus alien movement interval That’s great So that’ll roughly be zero, if not 0.01, 0.001, or something like that And that will move the aliens to the right and to the left Now, if we run this, it should work They’ll move So this is roughly what we want things to look like It might be a little fast But notice that when they go to the right edge of the screen, they just keep going forever, because we haven’t actually implemented checking for the edge, right? So that’s something we want to do We want to say, if the far right alien is at the right edge of the screen, then downshift everything down by a few pixels– maybe even the step length, we could do that Or maybe step height, maybe we want to define step height as a separate constant So I can say step height And maybe we want that to be eight pixels, a little bit more than the step width They’re moving a little fast, so I think the interval should maybe be 0.5 seconds We’ll see if that’s any better That should be fine And this is a lot up to your tastes more than anything, so you kind of want to tweak it depending on what you like best So we’ve done that We’ve got the aliens moving Now, we need to actually figure out when the aliens are at the edges of the screen And for that, what we can do is, we’re just going to assume that all the aliens are sort of– even if they are destroyed, they’re there So we can always test the far right alien and we can always test the first alien to be our left and right edges, right? So our alien, or rather our far right alien, is 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11– our 11th alien So we can just kind of know our 11th alien will always be where we can indicate the right side of the screen So I’m going to say, if aliens at 111- so because we added to our table– actually, I’m going to use best practices here I’m not going to use 11, I’m going to use far right alien and far left alien And aliens wide is also the same index as far right alien in this case, but we’re going to separate them just so that our code is more readable

This is important You want to make variables that are readable so we can, at a glance, know that we’re checking the far right alien here We’re not checking some random 11, which doesn’t make any sense I’m just reading it offhand, if you’re not familiar with the code base So if aliens far right alien.x is greater than or equal to– and this is where we want to check to see if it’s at the right edge of the screen, right? So we’re moving right So I want to say, if aliens far right alien.x is greater than or equal to virtual width– that’s the far right edge of the screen– minus alien size, and minus alien size because we want it to be when the right edge of the alien touches virtual width, not the left side of it Remember, everything in LOVE 2D is based on its top left coordinate So if we check for just virtual width, the alien will get all the way to the right side– like, past the right side of the screen before it actually checks the condition We want it to check when the right edge of it touches virtual width, right? So I’m going to say, if aliens far alien.x is greater than or equal to virtual width minus alien size– if the alien is right at the right at the right edge of the screen, this is where we want to set the direction– which the variable is up here It’s alien direction We’re going to say, alien direction is equal to left It’s no longer right We’re no longer moving to the right Now, on the next frame, this is going to be false and this is going to be true And it’s going to tick all the aliens to the left And this process will continue– assuming that we fleshed out this if statement here, this else statement– this will continue infinitely So what we can do is then say, alien direction is equal to left, and this will have the result of– it could be possible that the aliens move slightly past the right edge of the screen and we need a bit of logic to sort of reverse that But we can solve that I guess it’d be fairly easy just to figure out what that difference is, and then subtract that from every alien’s x But we won’t worry about that yet It’s not super important What we’re going to do first is just get the loop working infinitely So in this case, now, we want this to be right So in the else statement, so when they’re moving to the left, we’re going to– we still have it decrementing their position, but now we don’t want far right alien to be tested for We want far left alien to be tested And we want it to be less than or equal to zero, which is the left edge of the screen, not virtual width minus alien size Now, we’re checking to see if the left side of the left alien– the leftmost alien, the first alien– is right at the left edge So if aliens far aliens.x is less than or equal to zero, than alien direction is equal to right So then we’re going to go back to the right And we’re missing one last step, and that is, we want every alien to move down when this happens So what we can say is, again, another loop 4_alien in pairs of aliens, do alien.y equals alien.y plus– and then we just defined it– alien step height here And then, I want to bring this same exact code over here, just like that So if everything is according to plan and my logic is correct, when these aliens reach the far right side of the screen, they should bump down Let’s test and see Yeah, it looks like it jerked a little bit to the right there a little funkily So yeah, that’s the– am I changing all of their things to the right size? I might want to do greater than, not greater than or equal to, so that it doesn’t do that weird sort of diagonal jump Let’s see if that fixes it No, I don’t like how that looks It looks a little bit weird This might be acceptable for now, just in the sake of time 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, boom

Yeah Another thing you could do is, you could count the number of steps that are ideal between each– oh actually, do we want to do– if we do this logic before the aliens move to the left and the right, it might look a little bit better And then, do an else, like that, and indent that So this way, the aliens will move all the way, and then set the direction, and then skip that iteration so that it looks a little bit more like the original game Let’s see if my logic is correct If not, I’ll just revert it and we’ll accept it for now Mechanically, it needs to be adjusted a little bit But the logic works, it just doesn’t look perfect But I worry if we spend too much time, because we’re already an hour in, and we have collision and game states to worry about, we might not have enough time for a three-hour stream But we’ll see So let me go ahead and do what I just did again OK Else, indent this, end Let’s try and see what this looks like Hopefully this looks acceptable If not, I’ll have to just revert Oh, that looks great OK Does it look OK on the left side too? It’s OK It could be a little bit better I feel like I need to maybe change the left side so that it’s checking for, like, two pixels instead of zero, because it goes a little bit past the left edge– yeah like, four pixels So if I do single to four, see if that fixes it While that’s going, I will read the chat, or at least try to You ever heard of [? byte ?] paths, says OneDayMyLove? I’m not familiar with what that is Oh, that looks great OK, now let’s see, since now it’s going off of four pixels, see if it screws up the right side too Hopefully not Nope, that’s excellent OK, cool This looks awesome So let me read through the chat here So I missed OneDayMyLove saying, have you ever heard of [? byte path? ?] I’m not familiar with what that is I apologize Bhavik Knight says, maybe we can make it variable and make levels in the game With level up, we can increase the speed by some amount Yeah, we could do that I recommend definitely taking it and trying to do that yourself, if you can I don’t think we’ll have time I don’t think I’ll have time to implement that on stream today with the other stuff that we want to implement, but it’s a great exercise, certainly And I think we’ve– I mean, we’ve done something similar to that before with Snake I think we did levels and stuff [? ISOTV– ?] hello, everyone, happy new year Sorry I’m late I was on vacation until today Did I miss anything special? So good to see you [? ISO. ?] Nothing too special We did a review I imagine you probably saw the last Space Invaders stream, I don’t remember offhand If you did, then most of what we talked about for the first hour was review– or not first hour, 40 minutes or so was review of the code base, figuring out what the next steps are, kind of saying hello, happy new year Now, we’ve actually for the last 20 or 30 minutes got into the meat of the game We’ve added aliens moving, so the next few steps are to be collision detection with bullets, make aliens shoot, that sort of thing Yeah, and game states That’ll be another thing, yes [? Suraton ?] kindly said, talking about what we implemented last year Correct [? Aslee ?] says, why is it doing that jump? The logic was a little bit screwy It was checking to see if– it was basically moving before it checked every time, and so it would move in a weird position and then jump down And the logic was slightly messed up But we fixed it Everything’s good So now it actually does the check before it adds x, or subtracts x,

from the aliens And it does it with an if-else, so it won’t do them both in the same turn So we do get block movement on the frames– or not the frames, but on the part of the interval where we actually do move the aliens down We don’t move them down and then move at the same time That was the core issue It wasn’t in and if-else Now it’s in an if-else, so that problem is fixed Yeah, essentially what Bhavik said When it reaches either left or right extreme, pause for a time step, go down that time step That’s what we did Yeah, it felt. Awesome Cool So aliens look good now The movement looks good The next step is probably collision, right? So I can move around I can move the ship around and I can shoot, but it doesn’t do anything It actually just goes straight through the aliens through the other side And that’s not ideal behavior So a couple couple of things we want to do As we mentioned earlier, we want the projectiles to be only around as long as they’re visible So when they’ve gone past the top edge of the screen, if they haven’t hit an alien, we want to get rid of them We want to get rid of them if they hit an alien And if we hit an alien, we want not only to get rid of the projectile, but also to get rid of the alien itself So a few steps, a few pieces There’s a long block of code, too– 58 to 86 to do the alien movement We could separate that out, I guess So you can call this, like, tick aliens And then go down to the bottom here Just modularize our functions a little bit, see if it still works, which it should So it’s a good habit to make your update and draw functions kind of as small as you can In this case, we have this big block of code that does something very specific So take aliens We just took it out, made it its own function Now, our code looks a lot more readable We can say, OK, in our update function, we update the ship, we update projectiles We probably can put this in there, as well And then, we tick the aliens So we move the aliens So boom, that’s done Cool Essentially, just a copy-paste out of the update function It’s not better engineered, necessarily, but it’s easier to read It looks a little bit better It’s more easy to keep track of what’s going on You’re not navigating through a monolithic code base to figure out what the functions do When you have functions that you can reference by name, you can also reuse them in multiple places if you wanted to, and mix and match them– puzzle pieces It’s useful OK so now, collision detection with our projectiles So the projectile class, here What we can do is probably define a collides function We want a collides function that works with every entity in the scene, because we want to check to see– I mean, essentially, we only want projectiles and ships to collide with stuff So we could just define a collides function on a projectile that takes in something that has an xy width and height The aliens– do the entity have a width and a height? No, they don’t So in this case, we can probably set self.width is equal to alien size Is alien size the one in– alien size, yeah It’s always going to be 12 But this way, each object has a width and a height now, and we can use that in our collides function So we can go to projectile I’m going to create a new function called collides I’ll do it before update and render And it takes in an entity And this entity is assumed by this function to have an xy width and a height, which is why we just added width and height to entity The ship and the alien will all inherit from entity And therefore, they will all have an xy width and a height So this is aa, bb collision detection I think we covered this in a prior stream I forget offhand which stream it was Maybe somebody in the chat knows which stream we covered it in I remember drawing it– or at least I thought we did Pong, yep, there it is OK Did we cover that in 3D Pong? Did we really do that? I thought for 3D Pong we did Unity’s collision to systems, so we didn’t need to do aa, bb We cover aa, bb in the games course for the G50, but for stream I don’t remember if we covered it

Essentially, check to see whether two rectangles– whether one rectangle’s opposite edge is past the other edge of another rectangle That means that they impossibly cannot collide, and therefore it’s a simple check And it assumes the rectangles are on the same axis They’re not rotated rectangles They’re axis aligned, so completely orthogonal– is that the right word? Perpendicular to the axes, or orthogonal to the axes And therefore, it’s a very inexpensive operation and a very simple operation So I can say if self.x is– and so we’re checking the left side of the rectangle So if the left side of this rectangle– this projectile– is greater than entity.x plus entity width, then that means that this rectangle’s left side is beyond the right edge of another rectangle Therefore, it’s impossible for them to collide, essentially, right? And we do that same logic for all four sides of the rectangle And then, if any of these are true, then there’s no collision Otherwise, there’s a collision So if self.x is greater than entity.x plus entity.width, or self.x plus self.width is less than– that’s the right edge of the projectile If it’s less than the– oh this doesn’t have a width and a height So we need that as well So this needs to have a width So projectile– do I not have projectile width and height defined? Projectile height Oh, that’s not projectile height, that’s width My bad I screwed up the constant in dependencies I called it projectile height It should be projectile width– width and length, which is fine So self.width is projectile width Self.height is projectile length So it’s one and five, respectively– small rectangle If self.x is greater than entity.x plus entity.width, or self.x plus self.width is less than entity.x, or– fairly long if statement– self.y is greater than entity.y plus entity.height– so if this is below the other rectangle– or self.y plus self.height is less than entity.y– above the rectangle– then we want to return false, so it does not collide Else, we return true Both of these For a long if statement, it gets kind of obnoxiously formatted But that’s essentially it Check to see if opposite edges are beyond each other If they are, it’s not a collision If not, it is a collision Cool Simple And now, we can, in our main.Lua, say, for every alien– or I guess for every projectile, rather– projectile update Now, the thing is, if we want to update each projectile so each projectile takes in– it updates, right? So it ticks It says, if the direction is up, move it up Self.y minus projectile speed times all the time And the same thing goes for moving it down, right? So we can update all projectiles And maybe ideally this exists in the update function for a projectile, but it would probably be ideal to do that– from within projectile test a collision against each entity, say, for each entity in the scene do this, blah blah blah What we’re going to do instead is, we’re going to do that in here So we’re going to move every projectile And then, since we have access to all the aliens and the player ship within this function here, since we’re in main.Lua, we’re just going to check collision here in another four loop So we’re going to say, for _alien in aliens, pairs aliens two So we’ve moved the projectile, and now we’re going to say, if– I’m trying to think Because if we do that, we also need to get rid of the projectile

So we would have to set that projectile to nil Hmm But we can worry about that in a second So if projectile collides with alien, do– and then, OK, so P key So projectile key, and A key So that’s what we’re doing We’re saying P key and A key, because we want to have access to the key in the table from which we are calling it We’re going to set that key to a nil value in the instance that we collide the projectile and the alien, and then we’re going to also add an if nil check here This will allow us to set that particular alien to nil, as opposed to– do I want to set it to nil, or do I set it invisible thing so that we still have width and height access? No, we don’t need to set it to nil Invisible– probably want to set an invisible flag on the alien Defeat it, set an invisible flag And then, once we set an invisible flag, the alien will still exist We can still update its position It’ll still be hidden Yeah, that should work JPGuy says, everybody and Colton, long time no see Thanks, JPGuy for tuning in Glad to see you Make sure that I didn’t miss anything Hope you had a nice holiday season Talked about pineapple pizzas and mentioned to you The audacity, says JPGuy Does Lua have an interface support like Java interface? It’d be helpful in class, like projectiles shoot by either of ships or aliens No, there’s not really a notion of interfaces, Bhavik Knight Really, everything is very dynamic, so nothing has to adhere to anything You kind of define whatever functions– like, the best thing you could get is just by using classes, honestly There’s not really an interface It’s not going to, at runtime or compile time, determine whether you’re calling a function that’s valid on a class that implements a specific interface, because it’s dynamic It doesn’t have that notion Good question, though New Year’s is old news now, says JP Yeah, it’s getting there It’s like, what, is today the seventh, eighth? What is today? The seventh OK, so back to the code here So we’re declaring P key as the key for every projectile, and A key as the key for every alien Normally, we just use underscores, because we don’t use the key for anything when we do it in iteration We just use the– so this doesn’t throw away the variable It’s kind of idiomatic It’s a paradigm to use underscore in a lot of languages where you just toss a value away You don’t do anything with it So that’s what we were using it for But now that we need the value, and because we’re using a nested loop where we were using underscore, we need to differentiate these two keys, because we will use both of those keys here in just a second So one thing that we are going to need to do is aliens are going to need a invisible flag So we’ll just say entities can have an invisible flag And it’ll set to false by default And then, if not self.invisible, draw it, right? Because if it’s not invisible, we should draw it Pretty straightforward And then, what we’re going to do is, when we actually check to see if the projectile collided with an entity, we want to check the invisible flag Because if the invisible flag is true, then we want to ignore the collision So if projectile collides with alien and alien.and not, alien.invisible, then we want to say, projectiles at index P key is equal to nil And alien.invisible is equal to true And I think that should work I’m not 100% Oh, it looks like I messed something up Line 56, oh I put a do instead of a then Whoops Arithmetic on global delta time on line 99 How did we do that? Oh, I see OK, this needs to receive DT, and we need to pass DT into here

So remember, functions that you declare don’t have access to DT unless they’re called a reference within main So we take DT and we pass it to tick aliens so that tick aliens can do whatever work it needs to do with delta time So boom So now, if I do that, oh, it works Awesome No sound, so will it work with aliens that are beyond– yep That’s so cool It works No sound effects I feel like sound is always a super important aspect of the game, so I want to make some sound effects [? Aslee ?] says, AWESOME, in all caps Yeah It’s pretty cool I’m happy that it worked sort of on the first try I mean, I had a couple of syntax errors, but it works My logic wasn’t wrong That’s the more difficult thing to solve OK, what sounds good? Let’s see Let’s turn this up, turn my sound up little bit So if you’re not familiar, this is VFXR I’m not sure how you pronounce it It’s a sound generation program on Mac and Windows, and I think maybe Linux I’m not 100% sure It just generates sounds using simple sound synthesis, different sound waves that you can use, triangles, sine waves, saw waves, et cetera They even have whistle waves, which is interesting They have some pre-set settings here that are all kind of randomized and tweaked, so it’s super nice I’m going to make a couple sounds So the first one I want to create is, like, shooting, like a laser So they have a laser shoot category here [LASER SHOOTING] I couldn’t hear that [LASER SHOOTING CONTINUES] OK, that was a bit better That might be a little obnoxious I might turn down a little bit What do you think? Does that sound obnoxious? It sounds kind of nice, right? We’ll use that one Where are we at? In here, Space Invaders Oh yeah, VFX doesn’t let you create folders within the interface So it’s sounds, and then export wave, sounds, laser Do the aliens shoot back? Yes Not yet We will implement that Sounds, laser, and then we want something for when we defeat an alien, so explosion [EXPLOSION BOOMS] No, probably not that one [EXPLOSIONS CONTINUE] No That’s a little loud, but if we turn down– a little harsh That sounds OK, right, maybe? That sound is so much like the original Space Invaders, though, the first explosion This one? I, for one, welcome our new alien overlords, says JPGuy Not without a fight You need a short sound for the explosion Yeah, I kind of agree [EXPLOSIONS CONTINUE] Can I speed up the sound? Yeah, it should be sustain time to K time How’s that? They only eat pineapple pizza Yeah, nice OK, we’ll go with that one That’s fine So we’ll just call that one explosion.wav, and we’ll leave that open in case you want to add some new sounds I’m going to go to my dependencies So this is where we have all of our assets, g sounds, this is going to be a new table I’m going to create– a global table That’s why we’re using lowercase g at the beginning of it, because it’s a global We’re not doing that in main.Lua with some of the globals we have, because there is no real fantastic reason, I guess, because they’re all used within– well, they’re not globals, technically speaking, actually They’re all locals that are highest level in main.Lua, but they’re not technically global You can’t access them from other modules You can access them from main.Lua So I guess that’s maybe the reason g sounds equals– this is a new table, so each sound needs a string key So in this case, a laser equals LOVE.audio.new source This is how I declare an audio file, an audio object LOVE.audio.new source, sounds/laser.wav

And then, I think it takes in a word after that to declare whether it’s static or streaming, and then explosion So static or streaming just means whether or not it will sort of load the audio dynamically into memory when it needs to get used, and then sort of free it up Static means it’s always stored in memory So smaller sound files you can keep in memory and it’s not a problem For us for a game with a lot of music– for example, Super Smash Brothers, the new Super Smash Brothers Ultimate, has 900 songs– all, I assume, CD quality That’s a lot if you keep all those in memory at one time So those you would want to stream from disk In this case, we’re not streaming them We’re just going to keep them static They’re small sounds They’re very few kilobytes LOVE.audio.new source sounds, explosion.wav, static And then, in ship.Lua, this is where we actually instantiate the projectiles So going to say, g sounds laser play And actually, right before I do that, I’m going to call stop on it And what this does is, if the sound’s already playing it stops it and then replays it instantly And this is to solve the problem that happens because if you try to fire a sound or play a sound in LOVE 2D and that sound’s already playing, it won’t re-trigger the sound, it’ll just keep playing the sound that was already playing So you can’t, like, rapidly hit laser and have a do, do, do, do It’ll just play it only as fast as the sound itself is going until it ends, and then it’ll trigger a new one But we wanted to basically, if user presses space bar fast, we want it to trigger every single time So we’re going to call stop and then play, and that will solve that problem And then, in main.Lua when we actually do the collision, we’re going to say g sounds explosion stop, and g sounds explosion play Just like that So this should work [EXPLOSIONS AND LASERS] So a pretty easy game, I would say, at this point We might need to throttle how fast we can shoot the laser, but it works It’s pretty cool The other thing that we need to do which we haven’t done, which I mentioned we would do, is get rid of the projectile when they’re off screen JPGuy says, got to go for a while, hopefully be back before the stream ends Good luck with the Space Invaders stuff Thanks so much, JP Appreciate having you on I’ll see you next time Tune in on Friday for David’s stream He’s going to do some Docker stuff It’s going to be super cool MKloppenburg, thanks for the tip Downloading VFXR now Awesome Yes, it’s a great sound synthesis program I love it for simple, like, retro-style stuff Sustain, yep, did all that Death to them all, says JPGuy Death to all the aliens Normally, when you hear the word love, you think of romantic stuff Now, immediately thinks of LOVE.update Yeah, I’ve ruined that idea for a lot of people, I’m sure All right, awesome Everyone’s thinking that this is super cool I think it’s super cool, too I mean, the sounds really sealed the deal, right? [LASER FIRING] Now it actually feels that we’re playing a game It’s not just a little weird demo-y thing We’re actually getting somewhere with it So that’s that Let’s also take care of the projectiles being at the top of the screen So we can say, if projectile.y is less than or equal to zero minus projectile– or I guess we can just say, negative projectile length, then projectile P key is equal to nil And then, this four loop then needs to be in an L statement, because if we do this, this projectile collide function will break, because that’s now a nil object, right? Is that true? I think the object will still exist We still have reference to the object itself So I don’t think that’s necessarily true, but we should still put it into an else just for good

measure, because logically we don’t want to check to see If it’s beyond the edge of the screen, we don’t need to check to see if it’s colliding with an alien It’s impossible It’s beyond the view So we’ll do that So now, we can demonstrate that this works In my LOVE.draw, if I say, LOVE.graphics.print, projectiles, two string, length of projectiles So this should print– yeah, projectiles zero, right, up at the very top [LASERS FIRING] Yep See, they’re all set to zero So we have no projectiles left They’re all getting set to nil Pretty cool And it looks like it renders it I think it takes it a second to unload Like, the reference is nil, but for some reason it takes it, like, half a second to actually update that number So it stays– it’ll, like, instantly go to zero– everything But it works It’s good We are freeing our memory as we use it [LASERS FIRING] So we don’t need to worry anymore about sort of having a ridiculously long update loop or running out of memory Those aren’t concerns anymore We can check if the projectile is nil or now in the loop before shooting Well, we’re not going to– oh yeah, I see what you mean Yeah, we could do that It’s probably unnecessary and more code than just doing an L statement, though, to be honest, so that’s OK Probably slightly more efficient, too Oh wait, yeah Yeah, slightly more efficient, because it’s going to update iterate through every alien if we did that So we’re just saving some cycles It’s not a huge optimization, but it saves us, minimally, 55 if statements, if not more logic than that Maybe it’s more complicated than that So it turns that into just an else So it’s pretty cool We have a special guest today with us, here Who do we have on stream? You might be cut off You might need to crouch a little bit, there Hey SPEAKER 2: Hey! Nice to see everyone COLTON OGDEN: Is this the first time I’ve seen you since– SPEAKER 2: In like, since 2018 Yeah COLTON OGDEN: Yeah, I didn’t realize that actually, yeah SPEAKER 2: These streams are like a tour of my childhood, it seems COLTON OGDEN: Oh yeah Did you want to play a little bit of crappy– SPEAKER 2: Yeah, how far along are we now? COLTON OGDEN: We’ve got projectiles, and you can use the arrow keys and space bar to shoot some aliens if you want SPEAKER 2: All right Hey, that’s a lot of diverse enemies up there COLTON OGDEN: Yeah, we have it all– they’re set to a random index on a spreadsheet We just implemented getting rid of projectiles when they’re off screen, and so now the memory gets freed That was the most recent step SPEAKER 2: I still remember that sound There’s a very prototypical laser sound COLTON OGDEN: Yeah, we used a– if you remember from the games course, the VFXR tool which we used to generate sound SPEAKER 2: Yeah for sure COLTON OGDEN: You started a new course today, right? SPEAKER 2: We did We’re teaching a new course on computer science and the law at Harvard’s Law School, in fact COLTON OGDEN: How’d that go? SPEAKER 2: Good, good Doug Lloyd will be co-teaching too, so he takes over later this week So a few more lectures up this week COLTON OGDEN: Nice And then you’re coming in on Friday? SPEAKER 2: Oh, yeah, no surprise this time, though What game are we playing on Friday? COLTON OGDEN: Oh, yes It’s called Docker SPEAKER 2: Oh, yeah, so we actually use Docker, which is a containerization technology, which is a similar in spirit to virtual machines, if you’re familiar So we’re looking forward to talking about how those works and how they drive all the CS50’s infrastructure, and increasingly a lot of cloud-based services, as well COLTON OGDEN: Nice I’m excited to learn a few things about Docker, as well SPEAKER 2: Cool All right COLTON OGDEN: Have a good time SPEAKER 2: Well, I don’t want to take away from the game Good to see everyone and see you back in the chat, and thanks for tuning in COLTON OGDEN: Cool Thanks for popping by Appreciate it All right, so we did the freeing of the memory when the projectiles go off screen So the next thing that we should probably take a look at maybe is have the ships fire back at us Because currently, we can fire at the projectiles, but it’s a one-sided battle The aliens cannot actually give us any challenge Eventually, they will come down towards the player and theoretically collide with us– well, they will collide with us, certainly But yeah, actually having an adversary fire at us is probably worth implementing So why don’t we take a look at that? So in the alien class, this is probably where we want that to happen [MUSIC PLAYING] Aminebenamor, thank you very much for following And actually, now that I think about it, probably not the alien class,

because only a specific subset of aliens are going to want to be able to fire at the player Do not give them weapons This is how it starts, says [? Aslee. ?] Yeah, no Unfortunately, for the sake of having an interesting enough game to at least give us a challenge– is what Bhavik is just mentioning now– we probably want to make this a bi-directional game So my initial thought was do it in the alien class, but that’s not going to work necessarily well, because we need to have access to all the aliens We need that access to that information because we need to figure out which aliens are at the bottom row And the reason we need to do that is because if we look at the game and we see the aliens moving, if we allow every alien to fire and the projectiles will sort of indiscriminately collide with other aliens or the player’s ship, as you can imagine, all the aliens that are above the other ones will kill the aliens below them And this will therefore leave only this top layer of aliens, depending on how fast the shooting interval is, once that has passed So what we want to do– exactly, Bhavik Knight is saying The bottom row aliens only, otherwise the aliens will kill themselves That’s correct So we only want the bottom row to shoot However, we want the bottom row to shoot, and that includes aliens that we defeat from the bottom rows up So if for example, if we defeat an alien there, the alien above it should therefore be able to shoot at us now And you know, the same thing if we do it again Then, the alien in the third row now should be able to shoot at us, and so forth So we need to figure out– I guess we could sort of tweak the aliens that can fire based on the aliens above them I guess whenever we defeat an alien, we can then trigger some code that gives the alien above it the ability to fire That’s probably the easiest way to do it, honestly, is to give each alien a flag So the alien– I guess we just do it in entity, because ship and alien can fire So self can fire is false We don’t want every alien to be able to fire necessarily Now Colton is trying to build Skynet He is one of them I can neither confirm nor deny such claims– such accusations I’m going to, in main.Lua where the ship gets instantiated, I’m first going to let the ship fire Ship can fire is true This should be true And the aliens are all going to be, by default, not able to fire They’re going to be sent to can fire is equal to false So let’s go ahead and give the bottom row of aliens the ability to fire So we generated all the rows and columns, and then I’m going to say, if y is equal to aliens tall, then– So this is– OK So I’m going to do this I’m going to say, local aliens equal to this bit of code here So what I’ve done is, as I’ve taken that constructor out of the table insert function so that we can store a reference to it here So local alien equals alien at xy, math.RAM 256 for the random frame And then, I’m going to say, if y is equal to aliens tall, which means if we’re bottom row, then I’m going to say, alien can fire is equal to true Right? So this will only give aliens at y level five the ability to fire And then, in our update– did I do this in update? I guess I can in alien here Yeah I want it to be on a timer, and I want to give each alien a random interval of time that it will fire

Because I wanted to be kind of random I don’t want to be on a consistent timer, because if they are, they’ll all fire at the exact same time And it’ll be kind of like a blanket of fire, and it’ll be weird And it won’t be unpredictable It won’t be fun So also, each alien needs to have a reference to its own firing interval, right? So it needs to randomly choose a length of time It will wait to fire, and then fire And then, when it fires, it needs to reset that interval to some other random value And we can set it between maybe one and three seconds Or no, because that would be pretty fast Maybe one and seven seconds Yeah, we’ll do it between one and seven seconds One and 10 seconds? Yeah, one and 10 seconds This is all game design, game balancing, that sort of thing– again, up to taste more than anything else You want to tweak values, mess with them, figure out what works So we’re going to say– what makes the most sense, here? Do we put it in here? Because if we do that, we need to create a new constructor Just brainstorming for a second, figuring out what makes the most sense We can check if the alien has another alien in front Yeah, we could do that, but that’s going to be a little bit less– I think not as clean of a solution as I want to look for I mean, it works That’s solution would work fine, I think We can set it so that if there are fewer aliens, they shoot rapidly With more aliens, they shoot at a slower pace, says [? Bhavik Knight. ?] That’s not a bad idea That’s pretty cool, interesting sort of game design idea Certainly would work Certainly would be good I’m just trying to figure out how to structure this in my head before we actually code So the aliens that can fire need a timer– a fire timer The fire timer is going to get a random value between one and 10, and that’s the number of seconds Each one will therefore need a timer, itself So an interval and a timer– the interval will be the amount of time to wait for it to fire The timer itself will be the amount of time in delta time in seconds that have elapsed to wait for that interval to have passed Will then fire, will reset the timer, create a random new interval So yeah, we have the pieces So the best place to– I mean, dynamically, we could just do it in main.Lua We could just say, alien.timer Everything alien is going to need a timer so that we can update it Well, it will have a timer Oh yeah, so alien.timer is equal to zero Fire timer, we should call it fire timer Try to be a little bit more verbose when you can And then, fire interval And that’s going to be math.random 10 So this is the random length of time that will pass Aliens in the back have less pause, and aliens of the front have more pause to shoot Yeah, that’s a good idea, [? Bhavik. ?] Not bad I would recommend implementing something like that, for sure Try it out That’s a good example of an actual mechanic to influence the gameplay– the difficulty of the game So fire timer is zero Fire interval is equal to math.random 10 So what we can then do is say, in our update– tick aliens It could go in tick aliens, too We’ll write it in here, and then maybe we’ll make it a separate function

So for _alien in pairs aliens, do And then we’re going to say, if not alien.invisible, because the alien can’t shoot if it’s invisible If alien.can fire– if it can fire, then that means that it will have a fire timer and a fire interval So we’ll say, fire timer equals alien.fire timer plus delta time, if alien.fire timer is greater than or equal to alien.fire interval So this means that the amount of time has passed that’s the same or greater than the actual interval that we’re waiting for this particular alien It’s going to be random for each alien So this alien is set to fire after five seconds, and five seconds have elapsed, then I’m going to set alien.fire timer equal to alien.fire timer minus alien.fire interval So set to zero, or roughly zero And then, we’re going to spawn a projectile, and it’s going to go down So this is kind of what we did before Table.insert into projectiles a new projectile, which is going to get alien.x and alien.y plus alien.height And then, it’s going to be set to down So this projectile is going to move downwards It’s not going to move upwards, right? So let’s try this Oh, hey, whoa, nice OK So some of them are firing in tandem, because it’s not a floating point value It’s an integer So the random number– oh, we forgot to change this to another random value So alien.fire interval is equal to math.random 10 All right Aliens can’t shoot when they’re invisible This is in line with Star Trek As far as I recall, the Romulan spaceships couldn’t fire while they had their cloaking devices on That’s interesting I’ve not watched much Star Trek, but that sounds very apt for this particular example But the aliens are firing Now, the only thing is, they’re not shooting at us I guess I do want the alien to also do the sound effect for firing So g sounds, laser, stop, g sounds, laser, play Now, I kind of almost want to have a different sound effect [LASER FIRING] It’s kind of cool, because it’s creating, like, these obstacle courses that I have to fly through Whoa, like that Oh, it went right through me There’s no collision for the ship yet, actually, so it’s not doing anything So it can just go straight through me I forgot I, like, instinctively wanted to dodge it Yeah, the sound’s not bad, because it stops every one when it fires A different sound effect would be better, says Andrej We can do that Different sound effects, so let’s do some lasers Not that one [LASER FIRING] That sounds obnoxious [LASERS CONTINUE] Even more obnoxious That’s not bad I kind of like that I’ll do that one Alien laser Different alien projectile color, as well That makes it a little bit more complicated, because then we have to add that as a field onto the class Maybe we can make that an optional feature at the end if we have time For simplicity, we’re going to keep them the same color, just for now Dependencies– it’s a good idea, though Don’t think that it’s not a good idea I just don’t think we have the time But no, it’s an awesome idea I totally agree Alien laser equals LOVE.audio.new source, sounds, alien laser.wav, static Alien laser.wav does not exist What did I call it? I called the alien laser.wav

Oh, sonds That needs to be sounds OK Oh, so now we have to actually call the right sound effect So in here it’s alien laser [LASERS FIRING] Yeah, I kind of like it It’s a little bit deeper than the regular spaceship, so it kind of has a more even, like, a weird, very subtle, sinister difference So I kind of like it It’s pretty cool Yeah, that’s great We’ll do it Ship it Now, the projectiles should collide with the ship, as well So what we should probably do is– updating it if it’s less than projectile length, or projectile.y is greater than virtual height Remember, because these are the projectiles that go below the edge of the screen, we have to keep track of this, as well Then, set it to nil We were only checking above the top edge of the screen We also need to check the bottom edge And we need to also check to see if it collides with the ship So we can say, if– we can shortcut this, too Do I want to do that? No We’ll just say, if projectile collides with ship, ship.invisible is equal to true So because ship inherits from entity, this should result in the ship dying Yep, perfect So I’m still moving the ship around I can still move it around, but it is not visible And I want an explosion sound to play I want a different explosion sound to play than when the ships die, though I want a more dramatic sound, I think So let’s try here [EXPLOSIONS FIZZING] Oh, that one was all right It’s not quite long enough, maybe [EXPLOSIONS CONTINUE] That one’s very dramatic, but it’s kind of appropriate Cool We’ll do that one, just for the drama Death.wav Let’s go over here, we’ve got got to go into dependencies Got to add death.wav Audio.new source, sounds, death.wav, static Cool And then, here, set explosion We want death Lots of positive words All right, let’s try and die [EXPLOSIONS BOOM] There we go A very dramatic death sound, and the player does die We do not go to a different screen, unfortunately That is not yet implemented, but that’s probably the next step, honestly We’ve implemented movement We’ve implemented the ships firing We’ve implemented death on the player’s side There’s no score, yet Score is important We probably want score The title screen, probably important Yeah, that’s probably it for now The next part is going to be the largest part– the more complicated one, I suppose So let’s do that So the title screen Well, the state machine class first I’m going to create a new folder called states within source, and then I’m going to create a new file in source called state machine.Lua And a state machine is a– it’s been a blast thus far, have fun with the rest, [? says MKloppenburg. ?] Will have to watch the part later on Thanks so much for joining, [? MKloppenburg. ?] Glad to have you with us Hope you enjoy

Be sure to tune in on Friday for David’s streaming It’ll be super awesome The state machine class is a– so a state machine is essentially a finite representation of what the state of something is, whether something is– it can only be in one state at a given time, and going back and forth between states occurs during certain transition criteria, right? So you have a title screen When your game is in the title screen, it’s in a state of being in the title screen You’re not playing the game You’re not at a game over It can only be in one state at a time You can’t be a title screen and the game over screen at the same time That doesn’t really make sense You could maybe make a game that tells you you lost, but is also sort of the game over But it’s technically still going to be a different state, more than likely A state machine is what allows you to transition between the different states of your game The state machine is kind of like a thing that points at whatever state is currently active and updates it, checks for the transitions, and then transitions when it needs to do so and keeps track of that The actual states themselves are how we modularize our game, and we can then implement the title screen separate from the play state separate from the game over state, et cetera So the state machine class– first of all, it is a class So like we did before, we’re going to create it as a class The state machine has an update and a render function Just like a lot of the other stuff that we did, we’re going to call this from main It also has a change function, which will allow us to put it into a particular state And we want to actually be able to create it, so it takes in a state table which we are going to store all of our states in So when we call change state, we want to do is essentially say, self.current state We’re always going to have a current state And this state machine can apply to creatures in your game It can apply to the game state itself You can basically make a state machine for anything that changes state and that you want to modulize the state of, or encapsulate into a discrete file or module You can use a state machine for it It’s pretty flexible, and typically you use it for creatures in the game or game states, most often, but you could find multiple uses for it The state machine will always have a reference to whatever the current state is as its current state field, and that changes depending on what we call a change, and so forth So I’m going to say self.current state, exit So every state is going to have an exit function and an enter function The exit and enter functions function as the transition– sort of an abstraction of the transition of a state from one state to another state When you transition from one state to another, you call exit on the state that you’re in So it’ll clean up whatever it needs to do, do other stuff, and then it will call enter on the state that it’s transitioning to And then, it will set the current state to that state And so the enter basically lets you clean up stuff in the state they you’re currently in if you need to do so, free memory, do whatever you got to do, and then call some initialization code in your new state with the enter function And enter usually takes params, as well So that’ll be this, if taking the param is a second field of that function And then I can say, self.current state is equal to self.states state, and then, oddly, I do call it as a function, which we’ll see here in a second as to why we do that You don’t have to necessarily do it that way, but it’s a nice, clean way to do it when you have a game that uses, like, fresh states every time you do a state transition And then, I’m going to say, current state enter params Self.states is equal to states

Self.current state update, and self.current state render So we have a state machine class that will take a dictionary, it will take a map, take a table of states, and they’re actually going to be in the form of anonymous functions And we’ll see that That is why we call this here– this parentheses here, like where you’re doing a function call, because each of the self.states is actually a function [MUSIC PLAYING] It’s actually a function object Mirkyst, thank you very much for following So if I go to main.Lua here, first of all, go to dependencies.Lua and require source state machine, like so And in the LOVE.load, this is where I like to initialize the state machine I’ll usually do it after all the setup stuff And back for another half hour or so says, JPGuy Thanks for joining again Just doing some state machine stuff now, so a little bit more meaty, so to speak It’s a simple class, but a very flexible, very useful class What we’re going to do is, I’m going to create a g state machine Now, this g state machine is global because we might want to change our state from within other states Well, from outside of main.Lua, we are going to change it from within other states Each state of our game is going to be able to transition to other states So the state machine itself needs to be global So I’m going to do this here And I’m going to say title is equal to an anonymous function that returns a title state object, which we have not seen yet Play is going to be equal to a function that returns a play state, which we also have not seen yet And game over is equal to a function that returns a game over state, which we also have not seen yet And I’m going to change our state to the title state It takes no parameters And we want to make sure that if self.current state, then we want to basically put this in an if statement, because if we’re starting the very beginning of the game and we don’t have a current state enabled, then this will not work, because self.current state will be equal to nil And we can’t call exit on nil It has to be something that has an exit method attached to it, which is every state Every state needs to have enter and exit associated with it That’s part of the interface That’s how we can get this to work It assumes that any state that we implement will have that interface This is kind of like an interface, as per what Bhavik mentioned earlier But again, this is all dynamic Nothing is going to enforce that these functions exist It’s up to you to enforce that So I’m going to go into states, here, and create a new file I’m going to call this base state Not the most useful comment blocks of all time, but better than nothing, I suppose, arguably Base state is going to be the state from which every other state inherits And the reason that we want this to exist– we wouldn’t normally need this, but this is to prevent us from having to write empty enter and exit methods for our future states, because not every state needs an enter and an exit method, but our state machine assumes they exist And because it assumes they exist, we want to basically make sure every state has this interface– it adopts this interface And so we get this through inheritance So base state is then equal to a class And all base state is a bunch of empty methods Base state, update, render, enter, which takes parameters, and exit So this is all that base state is– just an empty class– well, not a completely empty class, but a class with five empty methods, an init, update, render, enter, and exit– all functions that the state machine assumes exists on each state that it works with So now what we can do is, I can say, new file in states

I can call this title state And title state is going to be equal to a class which includes equals base state, right? And so now this is essentially the same thing as copying over these five methods into title state for free So if we just saved it like this, titles class is essentially the same thing as titles state– sorry, this should be title state, not title class Title state will be the same thing as base state, essentially They have the same methods We don’t want that to be the case, though We want title state to actually have some behavior So what I’m going to say is, any function now that I define that has the same name as these, it’ll just override that It will just replace it with our own version while keeping the other ones that we inherit from base state, which is super useful So we can say it’s title state, and then this will be update and render We only need these two for now, just to demonstrate how it works So I’m going to say I LOVE.graphics.print, Space Invaders This is the title screen Actually, this is going to be printf Title screen, right, so this is going to be Space Invaders It’s going to start at zero It’s going to be roughly in the middle of the screen, virtual height divided by two minus– I don’t remember how tall the font is I’m going to assume 16, so I’m going to have minus 8 It’s going to use the width of the screen as its wrap amount, and I’m going to center it Oh, sorry, this should be in the draw function And up here in the update function, I’m going to say, if LOVE.keyboard.was pressed, enter, or LOVE.keyboard.was pressed return, then I’m going to– a bit of a brain fart g state machine change to play No parameters So maybe you see what’s happening here It’ll be clear shortly if not This is just a title screen that’s going to say Space Invaders in the middle of the screen And it’s going to check for input when we press enter or return– return taking into consideration Macbooks, which by default, the enter key is return It’s going to use that g state machine we declared in main.Lua and transition to our play state, a state that we defined as play And again, the states are all here– title, play, and game over Those are the string keys And they map to anonymous functions These anonymous functions are being stored in our state machine in self.states So self.states is just a reference to this table, here That’s what this curly bracket syntax is Remember, you can instantiate a class with its name and curly brackets if it just takes in a dictionary or table or map– however you want to look at it And these are anonymous functions that are stored there, assigned to these keys So key value– the values are function objects Those function objects will be called here, right? And remember, all they do is they just return a state– a title state, of play state, and a game over state– a fresh state, completely blank, which we so set to self.current state on line 13 here by saying, self.states at state– remember– change to state And then, we call these curly brackets That’ll actually call the function object It’ll execute that function’s code And the function’s return value is that state– depending on whether it’s a play state, a title state, or a game over state– and therefore assign it to current state, so then we have a reference to that state object– a brand new, clean state object MetalEagle says, hello CCSA TV Hello, MetalEagle Glad to have you with us Happy new year So that’s how the state machine is working That’s how it’s getting the state object and it’s keeping track of whatever state is currently active We still have a few pieces left to implement, though Why don’t we go ahead into– well, we’re already implementing the different states, the title screen Let’s add a play state The play state is essentially going to be all the stuff that we implemented in main.Lua already Play state equals class, includes equals base state And so what this is going to do is, all of this stuff here, right,

this is all going to be sent to the init function of the state Play state Right, so that’s what this does So we’re using self now So we’re no longer having these pseudo-global variables that are at the parent level of our main.Lua Now they’re actual member variables– member fields– of the object itself, these new state objects We’ve essentially taken all of our logic– we’ve found a way to take the game logic itself and put that into a class And so now we can modularize how our game flow works and not put every bit of important logic into main.Lua, so it’s super nice And that includes also these variables up here We don’t need these in main.Lua Those can be in the play state, just like that And they’re no longer a local, right? So boom, boom, boom, boom They’re self And now these– the [? Aslee ?] and Bhavik variables were just kind of stored temporarily they aren’t really ever referenced later on So we can keep those as locals We can keep the ship index as local We’re reusing it here and we’re putting that into self.ship, which is actual ship variable that we’re going to use consistently throughout the rest of the course Oh, it’s JPGuy’s birthday Happy belated birthday, JP I did not know, as well I apologize if he mentioned it before I did not know December 17th, nice Happy birthday So now, notice that self.projectile, self.aliens, self.ship is not necessary here, because we assigned it here Yeah We declared it in advance as a local because we wanted to reference it later on And if you want a local variable that you reference from within a nested scope, you need to define it above that function, which is why we did it before We don’t need to do that anymore, because we can just call it self.ship here and assign it, so super straightforward, saving a lot of code, actually All of these we can keep in main.Lua We can keep [? kush, ?] we can keep all the initialization stuff We can keep the state machine, itself, being initialized All of this stuff, though– this is all actually update code for our play state So copy that, bring it over here to our update function So this is cool Now remember, every time we have a reference to ship, it’s no longer just a reference to ship or projectiles We actually have to reference it as self.ship and self.projectiles, so that’s important that we keep track of that Let me make sure that I’m not missing any of those OK And tick aliens– remember, that was a function that was in main.Lua We no longer have access to that from within here So what we want to do is, we want to take tick aliens probably out, and take that out of main So again, saving space in main, allocating it to a different module Can I just copy it here? Right, yeah OK, and self.aliens, cool And alien movement timer, that’s a self as well, right? Yep So we want to set alien movement timer as self.alien movement timer And alien direction, as well? Yep Alien direction, that also gets adjusted So alien direction becomes self.alien direction Whoops Boom, boom, self.alien direction, perfect So that should be good That looks good to me So our main.Lua is now 68 lines of code, so we’ve actually reduced it quite a bit The draw, as well, we can get rid of that, right? So we can do this, get rid of this, go over here to make a draw function Or render, I should say And this should also be set to play state tick aliens

And this will be self tick aliens So here, we do this So pair is self.projectiles, self.aliens, and self.ship So everything is kind of coming into plan, here Code looks very good and modularized now Yep, thank you Watched the video about state machines 600– so of course someone has mentioned it before Yeah, super useful construct in game programming– ubiquitous, very useful, very helpful OK We’re going to keep if keys equal to escape in our actual main.Lua so it’s accessible from within every single game state Now, the missing ingredient is, we actually have to call g state machine render and g state machine update, right? Because if we don’t do that, then all that code that we put into play state is just kind of lost in space It still needs to be triggered And we do that from within main.Lua using the state machine object that we declared earlier and that we initialized So assuming that I did everything right, and actually I know right now that I did not actually require the states, themselves Very important that you do this Title, state And because I have a reference to it, I am going to require a game over state, and just add it really fast Game over state.Lua Game over state class Not functioning game over state Game over state is equal to class, includes equals base state Cool, now assuming that everything is in place, this should at least give us a title screen And as soon as we hit the title screen, and we press enter or return, we should get transitioned to sort of the game as we saw before So let’s take a look Cool, pretty nice We see we have the Space Invaders text in the middle Because remember we’re defaulting to the title screen– the title state So starting right off in the middle of the screen, we press Enter OK, so it’s not completely perfect Play state line 33, bad argument to insert OK, play state line 33 Let’s see what that looks like Ah, aliens needs to be self.aliens Let’s try that again Bad argument, two pairs, play state 66 Probably the same bug Yep, self.aliens And play state 112 Yep, self.aliens OK, boom, boom, boom, boom Remember, aliens by itself is no longer meaningful It needs to be self.aliens because it’s within the play state So now– OK, 78 Still have a few that we missed, which is OK Self.projectiles Yep I can’t believe we haven’t missed any other one Let’s see Yep, right here, self.projectiles OK, so hopefully that works Once again, 16 Oh man Wait, what did I miss there? What was that? Oh, projectile line 16 OK So projectile line 16 OK, takes on an entity, which gets an xy within a height So where are we referencing that for– let’s see if we have a stack trace here OK, that’s from line– oh, play state 56 OK, play state 56 This needs to be self.ship, not ship OK And this needs to be self.ship, as well A lot of these little things you’ve got to tweak If you start this off from the beginning in a state– what was the key code to press when changing two of the same names at once? Oh, if you highlight something, you can press Command-D or Control-D, and that will highlight the next thing of the same name in VS Code, and a lot of other text editors like Atom, too All right Is this working? Come on

[LASERS BLASTING] OK, that looks pretty good Let’s make sure that I can shoot other ships too OK, cool One thing that we didn’t implement, actually, which is important is that the ships above the ships that die on the bottom row haven’t been given the ability to fire, so we need to also do that But yeah, we’ve modularized everything Everything is cool We have two different states, now We have a title state and a play state And the last one will be a game over state when we die So as soon as we die, we should just do a change to the game over state, which we can very simply just kind of copy over the title state stuff, here, making sure to rename them to game over state And then, we want to set this to title And then, game over like that, which won’t do anything, because we’re not actually transitioning to it yet So from within play state, what we want to do is, when we die, we want to g state machine, change to game over Is that how I named it? Let me make sure Yep, perfect So now when we die, we should go to a game over Let’s try it [EXPLOSIONS] Awesome So we have a game over If I press Enter, we go back to the title screen If I press Enter again, back to a brand new game Now, do the ships regenerate? OK, let’s move firstly the green one and then– yep So the ships themselves also regenerate Sorry, that was a lot of sound at once MetalEagle says, why do you have call stop before play? So we mentioned this before What it does is, if you’re triggering in LOVE 2D a sound effect, and you trigger it fast before it’s finished playing, LOVE 2D will not refire it It will let it the sound effect keep playing until it’s finished And so if you want to have a rapid fire laser, for example, you will kind of just be stuck waiting for the first sound effect to finish, and it will kind of be like a weird sort of– sometimes it’ll fire, sometimes it won’t, kind of sound So if you stop the sound effect and then play it immediately afterwards, you will be able to re-trigger it instantly So you will get the effect of rapidly triggering that sound effect over and over again Good question You weren’t thinking about separating the entity class, and with modularity, look how far we’ve come with state machine Yes Yes, this is Bhavik And that’s a it’s a good point Always try to modularize stuff as best as you can I mean, I’m sure we could do a better job of modularizing what we have now It’s fairly well-structured, but you can almost always get better at organizing stuff If you see really large functions, a good heuristic is to kind of break those up and make smaller functions Separating the states is very good for game development, that sort of thing Yeah, it’s good practice Always try to make the most elegant code that you can It’s difficult if you’re in a rush and you have deadlines to meet and stuff Sometimes you can’t do it But as best as you can, as much as is realistic for your hobby projects or whatnot, it’s good practice, if anything The other thing that we were going to do is, we were going to make sure that aliens could still fire at us from the upper rows when the lower rows are cleared out And we also want a score And we want to display the score when we get a game over So what we can do is– and also we would also want to trigger a new level each time we clear out the map I’m not sure if we’ll have time to do that, but we could certainly talk about it But for now, let’s do the aliens being able to fire when the lower aliens are cleared out So what we can do is– where is the code located at? [MUSIC PLAYING] Balthazar_Bratt, thank you so much for following Appreciate it In play state– so in play state where we actually check each projectile against each alien, what we’re going to want to do there is, when we do collide with an alien– which is what we do here, when we trigger the code for clearing it out– we want to give the alien above it the ability to fire,

give it an interval, that sort of thing So what we can do is, A key will be the number– the index of the alien every time That’s what we have set to, here That’s why we needed to declare it So we’re going to say, if A key is greater than 11– and the reason that we’re setting a greater than 11– and what we should actually do is use a constant, so in this case, aliens wide, right? What this will give us is true if it’s anything greater 11, which is the length of an individual alien row So any alien beyond the top row, right? So if it’s the case that that alien is below the top row, then we want to say, aliens at A key minus aliens wide.can fire is equal to true And we have to do the same thing that we do when we basically figure out if the y level is aliens tall when we initialize the aliens So we’re going to say, can fire is equal to true, fire timer to zero, and fire interval to math.random 10, right? So fire timer equal to zero And fire interval, math.random 10 And that should work Let’s try it out [LASERS FIRING] I’m going to clear out this alien Whoops Play state 55 I forgot to do self.aliens for all of these So make sure to do that OK Clear that alien out So pay attention to that OK, so he killed the other alien, so that was an unfortunate bug Whoops Let’s try that again [EXPLOSIONS] So the reason that’s doing that is because the movement is fast It’s too fast So we can maybe tweak that So if we set constants to the alien movement interval to 0.75– [LASERS FIRING] OK, so it’s still killing the aliens below it So how did I fix this before? I’m trying to remember I solved this problem once before The simple thing to do– they’re not spawning in the middle of the ship, are they? No, they’re not That is a bug Yeah, the projectile is spawning right at the alien x We don’t want that to happen We want it spawn at alien size divided by two– alien x plus alien size divided by two That should fix it That should fix it Now it’s right in the middle [LASERS FIRING] There we go Perfect So it was spawning right at the x, right at the edge of the alien, and so it was instantly colliding with the alien right below it if there was an alien right below it So you don’t want that You want the lasers to spawn right in the middle of the alien So we fixed that problem Let’s try and figure out a [INAUDIBLE],, see what it looks like [LASERS FIRING] Whoa They can still kind of– they can still sort of kill each other Yeah, because they move in such a way that the movement itself

might be slightly off of when the projectiles themselves move So I think what we should do is set the movement interval to 0.7 and not 0.75, so it’s not in between a second, because all the lasers will always fire at a second, I think Oh, I guess not, because when we kill the alien, it changes the– oh whoa, that was weird I got an alien to die above another alien, which is probably because I shot a projectile and it moved right into it That’s pretty cool [EXPLOSIONS] So yeah, lots of fun stuff To do features where we ask a player named, score, high score, with the player name, levels, et cetera If the alien should check whether any alien is in front of it or not before shooting Yeah, that would be one way to solve the problem a little bit more appropriately The problem isn’t that there’s an alien front of it The problem is that it moves into it on the frame after it’s shot the projectile So anticipating that is a little bit trickier I could just make all the projectiles always spawn at the lowest y-level, but that’s not as convincing-looking We won’t spend too much time fine-tuning that, I don’t think We’ll kind of consider it a feature for now, just for the sake of time I think if we had more time, we’d actually implement perfect laser firing from the aliens It’s pretty good, though It works pretty well Andrej says, you could do what the other, original game did With game creation, I found some glitches that you did not initially intend to be a cool and unexpected feature Yeah, games are so crazy a lot of the time that stuff that you try out and mess up ends up actually being interesting, and demos you create end up being fun It’s pretty cool And then, Andrej said, you could do what the original game did But I’m not sure what that is Andrej, if you wouldn’t mind elaborating that’d be awesome Aliens’ lasers would be ignored by aliens Oh yeah, we could do that too I could just– yeah, I could say if projectiles down and it collides with an alien, do that It’s not super important at this point, I think We’ll just let it exist as it is It works well enough for the demo It’s probably somewhat fairly easy to fix And I encourage, actually, if you’re following along, to try to fix it, because that’d be cool Let’s implement a score mechanic in the play state, and then let’s feed that into our game over state So let’s go ahead and set a score to– here, I’m going to set the score to zero And in the render function, I’m going to draw the score after the ship So LOVE.graphics.print score, two string, self.score Just like that So that’ll print a score in our play state, which it does, very top left Pretty cool It’s not going to change, though, because we don’t get a score any time we kill an alien But that’s easy All we have to do is go to our update function, and whenever we collide with an alien– which is here Say, self.score equals self.score plus 100 Pretty easy, right? But we’re not feeding the score to our game over screen, so we can’t see what our score actually was So we should probably do that So I’m going to, in our what we call game over, which is– where is that? That is right here So game over, remember the change function can take parameters So what we’re going to do is, we can say, we’re going to pass in an anonymous table, and I’m going to say, score is equal to self.score And what this is going to do is, this is going to pass this table to the game over state with a key of score that equals the score as it is right now, self.score So in game over, I’m going to game over a state, Enter, params, self.score is equal to params.score So remember, that table is going to get passed in our state machine

This is what params is It’s going to be fed into current state enter, which is the new state that we’re getting And we’re just pass in that params as a table So then, game over state Here we have params We have access to it Self.xcore score is equal to params.score, and then here I can just say, your Score Two string, self.score So go ahead and get some points Whoa, that’s horrible, because all I did was copy and paste it So what I’m going to do is, I’m going to say, virtual height divided by two, plus 32, I think Try that OK, pretty good, not bad Not as much as I wanted it to be Let’s do plus eight Cool That’s nice That’s pretty nice We can move it up a little bit, probably, to be more vertically centered We won’t worry too much about that kind of detail That’s something that you can just solve by messing around with it But yeah, that’s pretty much it I guess one more message we could add to the title state would be the press Enter Just like that There we go Space Invaders, press Enter to play When we press Enter, we play We do this [INAUDIBLE] High score of 900 Space Invaders, press Enter to play Bhavik Knight says, what does the dot dot do in front of two string? I forgot Dot dot is the string concatenation operator, so what that does is it will just add two things together and just add one directly onto the end of the other one So in some languages, like Python, you can use use plus Two string just means convert a non-string value– a numerical value– to a string, and we’re using dot dot to concatenate your score And then, that string converted value, just adding them together All right That was pretty much all I aimed to complete for today’s stream I do want to stick around for any questions, if people have some, before we adjourn In case I went too fast over something, I would like to do that Maybe receive any ideas or suggestions for future streams That would be awesome, as well I know that [? Aslee ?] did say she wanted a typing game, so I have been thinking about that We’ll probably do something like that I might do hangman first before I do the typing game We can use hangman, build a hangman, and then use some of that code to develop the typing game, which would be cool And we could talk about what kind of typing game– just a generic typing game I’ve never made a typing test before I mean, a simple typing game would be pretty easy, just get the words correct, I suppose But yeah [? Aslee ?] says, yes, I’m dying for the typing game Hangman would also be great That’s also sort of a typing game I did debug it Oh, one thing that we do want to do is push this to GitHub, right? LS, where are we at? This is in Pong, so out of there, into streams, Space Invaders, get status, OK Final stream version, cool So now, as of right this second, the code that we did today plus the code that we did last stream is now on GitHub So if you want to clone it, mess with it, try and add some new stuff to it, definitely do so Definitely try to add new features It’s a very good exercise Maybe use it to create your own game in the future if you want to We have a full– it’s pretty much a full, I mean, proof of concept, Space Invaders It doesn’t have levels It doesn’t have a lot of bells and whistles, but it will help you if you want to start building a space shooter of some kind, certainly Did a hangman game in 60 ’01, says Bhavik Knight, for a pset There was a typing game where you got points as you typed correctly, says [? Aslee. ?] Interesting Couldn’t finish the story yet I’ll share it here when I finish [? Aslee, ?] are you building an adventure game? I don’t remember offhand If we talked about this on a prior stream, I apologize

Any questions at all about the code today, or about anything? Anybody have anything they want to chat about for a couple of minutes? We have a few minutes left, here Oh, text adventure in Unity Got it, OK Nice There is a Udemy course that teaches how to do something like that If I’m not sure if you’re using that– going through that Udemy course by Ben Tristem, I believe That’s a good course No, I got the code because I was late How was your holiday? Says [? Aslee. ?] Holiday was great So I was in California I spent a lot of time with my family It was super cool Played games with my dad and my brother and my friends Played some of the new Super Smash Brothers, which is super fun Super good game Like I mentioned it earlier, 900 or something like that– 850 or 900 songs in that game– insane Yeah, how about your holiday? And anybody else in the stream, what did we do over our holidays? Certainly the weather was a little warmer over there than it is here now It’s in the 20s today It’s a little chilly And again, more ideas for games much welcomed I personally want to start getting a little bit more into modern web dev this year a little bit, so if folks are open to more hands-on building of websites using React and other tools, that’s something that I think I might want to do and learn So I wouldn’t mind doing it on stream if people are interested in that I think probably more people care about web dev than they do about games, so I’m not sure, but let me know Definitely that’s what I’m using It’s awesome I moved past the text adventure to harder things, but I’m a sucker for writing, so I’m working on it Wow, 900 songs, that sounds like a nice holiday Yeah It’s a crazy game And yeah, it’s a good course Hopefully you can make it through I would definitely stick through it Ben has a great teaching style I’m a big fan of his course [? Aslee ?] said, I care more about games I personally think I care a little bit more about games, too But I’d like to get good at web dev It’d be cool, I think it’d fun It would be good stuff Yeah, good stuff We made Space Invaders, everybody It took us two streams, but we did it So future streams– so probably realistically, the next game stream for me is probably going to be next week It’s probably going to be Monday It’s probably going to be hangman And then, another day next week, maybe we’ll do the typing game, if not the week after that David’s on Friday doing Docker So that’ll be really cool I’m going to try and get some more people in here I’m going to try to get Nick in here after a couple of weeks Nick is still on vacation, but as soon as Nick gets back from vacation, you’ll probably get some white hat hacking streams from him on Kali Linux, and maybe some other stuff maybe on Bitcoin and who knows what else He’s a jack of all trades For me in the future, hopefully React I have to learn it That’s going to take me time It’s going to be some late nights and weekends in the future before we can do that But next week, Monday– anticipate Monday– hangman stream Friday, David with Docker Tuesdays and Wednesdays are going to be a little light, because we have a class in this room, but we might shift We might do a Monday, Thursday, Friday stream schedule We may or may not still be able to do Tuesday, Wednesday, depending on how things work out It’ll at least be about eight weeks until we resume Tuesdays and Wednesdays React, CTF, Docker– yep, that’s all stuff that I know that Nick was super interested in The CTF stuff was super cool Three days a week sounds great, says [? Aslee. ?] Yeah, three days a week is what we will strive for, if not more It depends on the room’s availability This room is very popular Sorry if you have already talked about it, but is it possible to generate an executable file? Says– I can’t read that username– [? CesarCXBR. ?] An executable file– yes it is So on LOVE 2D’s forum, their wiki, Game Distribution is the section you want to look at here on their on their wiki page And it will tell you in detail how to go about creating Windows executable, for example, if you’re on Windows, or a Mac OS app, for example And also, a .love file love a very standard way that people making LOVE applications tend to distribute their games, because it’s pretty easy It’s just a zip archive essentially, but it will run with the LOVE framework

Windows and Mac have all their instructions here for making exes So this is how you would create, using the command line, an exe using a LOVE– sorry, this is how you would use the command line to make an exe with a LOVE zip having been already created It assumes that you’ve done that It assumes you’ve created a super game.love thing, or whatever your game is .love, which is defined up here It’s part of the process You have to do that And then, you need to– essentially what you do is you add love.exe on top of super game, or whatever They say super game.love That’s just the name of their game Whatever your game’s name is .love, you add the love exe itself– the actual love exe– so that it will run when you double-click it on a Windows computer And then, it will receive the name, whatever exe afterwards And they use this forward slash b as well, which I’m not entirely sure what that is It probably means binary, appending that exe and the .love thing– the .love binary on top of it And then, you can create a batch It has instructions for creating a batch file to do it It’s the exact same thing, sort of, for Linus and OSX using the cat command So I do think that that slash b is just adding them on top of each other But yeah, fairly straightforward Creating a Mac OSX application is a little bit more complicated The Mac OSX application is– yeah, yeah have a little bit more stuff They have, like, a package with contents and some pllist files and whatnot But all the information is there on that page, so definitely check it out One, two streams per week, says Bhavik Knight Yeah, I don’t want to do only one to two I want to do at least three, so we’ll try to figure it out I have to figure out the scheduling for this room, make sure that we have the time and the bandwidth for it, make sure I can get enough people to contribute, which I know Nick’s on board when he gets back David’s usually on board once every week or two I can do one or two a week So we should have enough We’ll work on it We’ll get a schedule Am I teaching this semester in the extension school? Yes, online only, though– online-only version of the GD50 course Andrej says, any Unity streams in the near future? Probably, yeah I would love to do some more Unity stuff I’m a big fan of Unity, and I want to get better at it and practice doing it So yeah, expect some Unity stuff I’ll have to brainstorm and think of some fun stuff I really want to make a 3D platformer at some point, as I mentioned on prior streams, but that’s complicated That’s, like, a very large project So something smaller would be nice I’ll think about it I have no concrete games in mind just yet A stream to make an app would be nice with React Native, but perhaps [? Brian ?] could help with that React Native– that’d be interesting I’ll see if [? Brian’s ?] familiar with React Native I’ve been asking him to get involved in making some more streams of us He’s doing a sort of mini workshop course on campus, so he’s been a little bit bandwidth locked, but maybe after a couple of weeks have passed Any streams about functional programming in the near future? Says Bhavik Nothing planned, but I would love to do something like that, because I have also been wanting to get better at functional programming I’m a big fan of Closure And I’ve also wanted to learn Haskell So it would be fun to do some of that on stream Solving the Rubik’s cube in Unity Yeah, Bhavik Knight, that’s true I had thought about– brainstormed that briefly, actually, last year after we talked about it on stream And it would be possible, but it’s going to be somewhat difficult, and I don’t know exactly offhand how I would do it So I would need to brainstorm more, I think, before actually committing to that I don’t want to spend too much time kind of umming and ahhing over on the camera I kind of want to have a game plan before I set up so that it’s not too awkward and quiet But we’ll see I heard from a reliable source that coding your own games is easier than you think You know, you should take this online Unity course on Udemy Online Unity course on Udemy Oh, that that’s the Ben Tristem reference Yeah, because he does that Did you finish the Udemy course? I did not finish it I got through, I think, a few of the games, and then I got distracted with something I have, like, 20 Udemy courses I have to complete, including some React ones that I just bought, so we’ll see how that goes I swear I see that 25 times a day, at least Last year sounds so weird Yeah, it was last year, technically speaking I mean, it’s been almost a month since we streamed– it’s been a month since we streamed Space Invaders– more than a month The first part was November 26th, it was when I committed Udemy courses– plenty in pending there Yes It is that So I use Udemy, too, [? SisterDemure24 ?] I do Not a lot, to be honest The last time I really used it was probably two years ago, and I have recently bought some new courses to try– like I said, I want to get good at web dev, so I bought a couple of Udemy courses

on React and modern web dev, so we’ll see And some AI and machine learning courses– that is going to be a little slower-paced for me, I think, because especially if I want to understand everything really well, I think there’s going to be more math behind that We’ll figure that out But AI and machine learning are courses– topics that would be cool to have, like, Nick and someone else talk about more on camera, because I think those topics are really cool I was trying to finish the Udemy course before Colton Student surpasses the teacher Yeah, definitely do so I’ll be very proud of you, [? Aslee, ?] if you do that I honestly don’t know if I’ll get back into that Udemy course, because Catlike coding is a resource that I think I would want to work through first, and it goes into more depth than the Udemy course does The Udemy courses a little bit simpler, I think– not that it’s not very easy Not that it’s not very easy It does teach you a lot and there’s a lot of good stuff in it, but Catlike coding I think is, like, pretty next level So if anybody is not familiar, CatlikeCoding.com– I’ll pull it up here Really good resource for learning Unity Do it with the tutorial section I actually haven’t checked it recently They might have some new stuff on here The person that does this is really, really, really crazy smart– does a lot of really good stuff, really goes into, like, the low-level side of Unity, which is not something that you see a lot Like, actually has you digging into the rendering engine and doing, like, custom shaders from scratch, and all kinds of really cool stuff Yeah, really cool CatlikeCoding is a brilliant website, says [? Andre. ?] I agree Udacity– I like Udacity courses more than Udemy Udacity offers nano degree about some AI and ML courses Interesting I haven’t looked too much into Udacity, to be honest Coursera I have seen I think Andrew– I don’t know if it’s Andrew– I don’t know how to pronounce the last name– Andrew Ng, but he does an ML course, and his is very well-received And I think he’s on Coursera, if I’m not mistaken His was one that I wanted to get through, but it’s a little dense And I haven’t had time to really dig into it, or the motivation to really go all-in on Machine Learning, but sometimes soon EdX and Coursera are the best because of the affiliation with a great university Yeah, edX and Coursera are great Speaking of that, CS50 2018 materials are edX now, FCS50x, 2019 So check those out if you want to see all of the latest lectures and the latest course materials We got that shipped over the winter break, so super cool Can everybody else take an even vacation while I catch up on coding? Says [? Aslee. ?] Oh, wouldn’t that be nice, an even longer vacation? The landscape is always changing, I guess But you know, as long as you put in the effort, I think, and you’re consistent about it, I don’t think you need to worry about everybody surpassing you forever I think you’ll be just fine Just go at your own pace Enjoy the process Enjoy the journey You don’t want to spend years doing something that you hate doing, right? And eventually you learn– or at least, I learned to really enjoy the journey The destination is great– being able to build stuff But learning stuff– if you can enjoy learning, then you’ll always be on top of things, or at least relatively so You’ll always at least enjoy the process, and I think go farther than a lot of people that are less interested in it, or maybe monetarily influenced You know, because there’s so much to learn If you don’t enjoy it, then it’s not going to stick as much, in my opinion I don’t enjoy everything I learned in CS– not every single thing But I enjoy I would say I can appreciate enjoy the vast majority of it Certain things I don’t really enjoy too much I can’t think of examples offhand, but there are certain topics that are less exciting I definitely agree on almost everything I wanted to learn stuff like in The Matrix Yeah, that’d be really cool Everybody has their own time Some start a business at 25 but die at 50, and some start life after 50 and work 40 years Yep, very true Very true It’s all relative Like CS50 says, it’s not relative to other people It’s relative to how you were when you began, right? How you are now relative to how you are at x time ago is what’s important, not how good you are relative to your neighbor Is the new CS50 stuff out? Yes The new CS50 stuff is on edX now That’s the one thing I love that the professor says Yep It’s a great, great expression Very true words of wisdom

OK I think we’re about ready to wrap up It’s been a pleasure talking with all of you, and a pleasure being back in 2019 on stream I’m glad that we were able to get everything set up and working, and everything was good We learned and completed Space Invaders, so it’s a very successful stream, in my opinion It went smoothly There weren’t too many great hiccups [? Thalamus, ?] it was great to see you You rocked at the Harvard Fair Thank you so much Good to see you as well Hope to see you on TV Timing for Fridays? Says Bhavik David’s going to be on at 3:30 Eastern Standard time, so a little bit later [? Ichimasio ?] said, thanks for tuning in And that means I will go Fun fact I will go! Exclamation point Good to have you back, says [? Aslee. ?] Thank you very much Cool All right, everybody I’m going to transition to the bigger screen, here I’m going to bid all of you a awesome rest of the week until Friday, which I’ll be here with David co-hosting We’ll talk about Docker Docker is super cool, super modern It ties in well with all of the dev ops stuff that [? Kareem ?] and I have talked about before [? Kareem– ?] I’m going to try to get him on stream, as well, if we could It would be nice [? Caesar ?] says, it would be nice if you could present a minimum Super Mario game style For example, where it seems they work with some kind of maps Yeah Yeah, we could maybe do something like that We would do that in my games course, actually We implement a version of Super Mario So if you haven’t checked that out, go to CS50.gg, actually, should now point to the games course, although it’s old content Yeah, this is the games course for 2019 Table of contents, Super Mario Brothers Is it still here? No, it’s not The URLs are all– what’s it have? Sort of temporary before we actually get the class fleshed out, but if you go to CS50’s YouTube channel, our game development playlist, and type in Super Mario Brothers, I show how to implement a sort of basic Super Mario Brothers style game And we could maybe certainly take a look at doing something like that again in the future It’s a nice, fun demo Cool All right, everybody Thanks so much for tuning in See you all on Friday Enjoy the rest of your week This was– this is CS50 on Twitch And I’ll see you all next time Bye-bye