 Oh yeah, now I think we're into the normal process. Going live, we're live, okay, there we go. We'll probably give it a couple of seconds. I assume it will probably take a second to catch up. So I will do that, while I'm doing that, let's rearrange a couple of the windows here so I can see the chat and then we'll do an introduction. So thank you, I don't know if anybody did anything on YouTube to make that work, but thank you. Not sure what was going on there. Let me get those chats around. See in here, thank you. Okay, okay, now we're ready. Sorry for the, I'll start there. Let me pause these streams so we don't really need a million previews, I'll pull this back over. This has got our camera, camera's actually live. Okay, YouTube is good, thank you, appreciate it. The heads up, okay. All right, now I think we're ready. Hello everyone, my name is Tim, and I go by FOMI guy on GitHub and Discord. Today is a very special stream, so of course today is circuit Python day, so of course happy circuit Python day to everybody. I've been checking out all the streams and the rest of the content today, and it's been a whole lot of fun. So I hope everyone else has been having a nice time. He for Restream YouTube was wrong, didn't know which one was mine, so I made a new one that is labeled. Okay, I'll have to see if I need to do anything next week or if it will sort itself out, but I can do that later on. How's it going, Gordy G? So, a quick introduction to what today's stream is all about. Today is a different stream, something that I haven't done before that I wanted to try out. We are gonna be working on a game jam, so for those that don't know, if you've never heard of a game jam, this is kind of a type of event, sort of like a hackathon, so to speak, that goes on where generally there will be a constrained period of time, so sometimes game jams go for a full week or sometimes it's a weekend or sometimes even just a couple of hours. You work for that amount of time, you try to build a game, and then at the end of it, generally this is like a communal event, so at the end of it, you can pass your game around and other folks are allowed to try and play your game and you can play other people's games and you can give each other feedback on what you like, what you don't like, what would be good stuff to add after the fact, cool features and cool ideas that you didn't have time to get to and stuff like that, so that's kind of the core idea is a time constrained game development session, so I'm gonna kick one off and I figured it'd be cool for folks to watch along. I do wanna say before I get started though, and kind of put out feelers, I'm interested if anybody else is interested in ongoing game jam activities, if we have enough interest, I'd be willing to help organize a community game jam where we could have multiple folks get involved, we could do a longer one where we go for a week or a weekend or something like that to work on our games and then have like a special game jam show and tell or something where we can all get on and show the games that we created and of course we could share the code and stuff so other people could play as well. If people are interested in doing that in the community, I'm happy to help organize that and I figured today would be a good way to show people kind of the idea of what I have in mind for that is to see if there is interest in it, so for my game that I am gonna work on, it is gonna be, I've dreamed it up a little bit, I haven't written out any of my plans or anything like that, I tried to do very minimal amounts of work before I started, I didn't wanna get a bunch of stuff done and then jump in in the middle, I really wanted to try to bust it out from start to finish as best as I could, so the idea that I have for a game is kind of a mix between old school arcade games like Galica and Space Invaders where we will have a spaceship, it's also similar I guess to asteroids in some ways, we will have a spaceship, my idea is the spaceship will probably stay along the bottom but other stuff on the screen will be flying towards you to give you that illusion that you're flying the spaceship forwards, the goal will be to shoot our lasers at a couple of different things, asteroids that contain resources, this is kind of like the primary mechanism that I'm interested in for this game is fly the ship around and then shoot like a mining beam, a tractor beam or whatever, we're shooting this mining beam at the asteroids and you will collect resources from that and then in between levels you'll be able to spend your resources to upgrade your ship so you might get a better laser blaster or you might get a better armor, you might get faster flying or slower flying or just more control over your speed, you might get a secondary laser where you can shoot two at a time or something like that, I'm not 100% set on whatever all the upgrades are gonna be but the core idea is flying the ship around, shooting the asteroids to collect resources and then spending the resources to upgrade your ship, that's kind of the main game loop if you will and then eventually we'll probably, I think have some kind of enemy ships or something that will shoot back at you to add some fun to the game so that's kind of the core idea and I'm gonna jump right in, might be able to whip up some quick spray sheets for assets, nice and if I will say before I jump in one more thing, if folks are interested in a larger scale game jam stream, if other folks are interested in participating in one of these in the future, relating to Circuit Python, that's kind of my idea, there's lots of these game jams that occur all the time for just general stuff, people make PC games and web based games and all that kind of stuff. I'm interested in a Circuit Python one where we could work on handheld devices like the device I have today, which I should mention is a Pimeroni Pico system, that's the device I'm gonna make my game for today, but of course there's PyGamer and PyBadge and several other possible devices, Pew Pew devices like the Shippu's device from the chat there. So there's all kinds of other devices, this is the one I'm gonna start with for today but if we did have this larger idea of a game jam, of course you could work on whatever hardware you wanted. So if that's something you're interested in, ping me over in the Discord at some point and if we have enough folks, we will get something put together. So I'm gonna jump right in, I already have, basically the only thing that I have done is I have one image asset that's ready to go, it's a bitmap, I've already got it converted and I've got it just put on my screen with an on-disk bitmap just to make sure I got the transparency right and all of that and so that's what's showing right there. So that is basically where we're starting from which is almost nothing. The first thing I'll do is let's get some control on the ship and in order to get some control on the ship, I think I will make it into its own class. So right off the bat I'm actually gonna go ahead and say new file, I don't have a name for this game, I should have probably come up with something, I'll say space miner, I don't know, space miner. Yeah, we'll call it that for now. I will actually, let's put this as helpers I like to do helpers as the name of the file for these space miner helpers. I'm gonna just make a ship, so class ship. I think I'm gonna make my ship extend group for right now, import display IO, display IO dot group. Liz would be interested, nice, yeah, okay. Let's see, how big do I want each tile in this case? So I haven't got into tile grids yet but in this case my ship is, it is 32 pixels wide and I don't remember the height. I think it's, yeah, 33 we came out to, interesting. I could have swore I did 32. 33 pixels wide, 25 pixels tall, but I'm gonna render it and the rest of the grid, I mean the rest of the screen won't be a grid. I mean it's a grid of pixels but the ship will be able to move one pixel at a time so it's not as though the ship will have to go an entire tile width at a time. We'll have more fine-grained control, is the ID at least. So we're gonna make this extend group. We're gonna make init function for it. Oh, I should mention too well I'm getting going here, the constraints. So I have not set an exact timeline for my constraints. I'm gonna go for a couple hours tonight. We're gonna see where I end up. I think I will probably pick up where I left off on a stream tomorrow. So I normally stream on Saturday mornings at 10 a.m. central time for folks that don't know. So I'll probably pick this back up and work on it some more tomorrow. And then I'd like to see where I'm at after that. I don't know if I'll keep going after that but the whole idea is the constrained thing so I'm thinking like two streams is kind of where I'm gonna start couple hours tonight, couple hours tomorrow and then see where I'm at. I'm not gonna give myself like a hardcore deadline that I absolutely cannot pass but that's kind of the rough ideas. Couple streams, probably about four or five hours total something like that depending on how things go. Individual BMPs, this one for right now this is individual BMPs but we could eventually have it be a spreadsheet that has like different animations on it for like explosions or when you shoot the laser there could be animations or something like that. So we could eventually do a spreadsheet for now though. I am just going with individual bitmap for the ship and then I think the asteroids as well once we get to those. So this needs to call super.init because we want to initialize our group and then from there I'm gonna add the ship to it. I'm gonna start with just copy pasting this I'm gonna do it as a on disk bitmap but eventually we might make this image load especially if we do go on to have some kind of manipulation of the ship either like flying animations or explosion animations or animations for when you collect a resource or something like that. If we end up wanting to make those kinds of things then we'll probably switch this over and not use on disk bitmap but change it to image load. In my code pie I'm gonna make a main group as a new group. I wanna spell that one correctly and then we will make a ship. Ship equals new ship which we will import from our new helpers file that we created. That's this one but you don't want this part of it. Group we can import from display.io. All right I guess to add it like that would work as well. I'd definitely be interested in CirquePython Game Jam but I can't promise I'll have the energy to participate in any particular day. Yeah no worries I think. If we do go about this we open to the whole community but it will still be not strict. My intention is not to make it so that you have to feel like you have to participate or that you have to feel like you have to participate the entire time or something like that. We'll definitely be going super wide open, participate as much or as little as you want. If you don't have it in you on a particular day or whatever that's totally no big deal at all. We may even make it a longer range like maybe call it a week or two weeks or something but that way you have time you could work on it during that time whenever you want. So yeah we'll definitely keep it very organized but loosely organized. We're not necessarily looking to make a ton of rules about how you do it and how much you have to do it and all that kind of stuff. We just want to have fun with it for sure. So I'll make the main group, I'll add the ship to it. I'll put the main group on the display. We will, we have a tile grid in here so we want to go self append so that we're putting our ship onto our self instance of group. I'll save that and maybe we'll get a ship back. Yeah, looks like we've got a ship back. So I'm going to then do some ways to move. So I think what I'm going to do is make a function called left arrow button. Events, button, btn event. And I'm going to go ahead and actually just do a right one while we're here, def, right arrow, btn event. So yeah, whenever this gets called we will want to move the ship left or right by one pixel. So when the left arrow is pressed and then we got to decide do we want to move, I think we want to move the super instance of group. So what we'll say is just self.x we'll go minus equals, minus equals one but we'll only do it if self.x is greater than zero. We don't want to run off the left side of the screen. And for here we'll do a similar thing if self.x is less than, I'm going to want the display size. So I think what we can do is maybe inside of a init here we could say display size and then self.display size, display size, ship movement, sprite sheet. Let me check that out. Oh yeah, my show and folder thing is being weird today. Ah, there we are, nice. So you got some different rotations in there. Ah yeah, so my initial plan is unlike asteroids we will not be changing the angle. My initial plan is we will stay facing forwards but we'll move back and forth laterally along the bottom and then the rest of the stuff will kind of fly at you. So it's a bit like Galaga and the other one, Space Invaders I think where your player character is at the bottom and you stay there just back and forth a bit. Maybe eventually we'll go forward and back some too, I'm not sure but that's the plan to start with. So unlike asteroids we're not going to fly our ship to the center of the screen and then be able to point all around. Oh, that's the original Galaga, I see, okay. While mining, mining, yeah, so we're gonna shoot the asteroids in order to get resources, that's what the mining is. You will shoot the mining laser at the asteroids that will give you the resource and then you'll be able to update your ship with those resources to get better stats and stuff like that. Okay, display size, we'll be able to have this now and then when we create it here we'll go, it's just gonna be a tuple display dot width display.height and one thing is we want a height and a width of our ship. So what I'm gonna do is make properties, property, depth, height, return self dot, we're doing a one by one tile grid so these are just gonna be actually the same for us. I don't think it actually does matter. Oh, we will need self dot, I'm gonna call this ship bitmap, eventually we might have other ones like for the lasers or maybe those will be their own class, I'm not sure. We'll call this ship bitmap, that way we can be extra descriptive in our code. Save that, oh, okay, yeah, this will need to be self then. Question, while mining got it, question, and then you buy resources with microtransactions to get a better ship. Yeah, we're gonna skip the microtransactions in my version but I will open source it and if anybody wanted to, they could try to add that unfortunately. But yeah, we're gonna be going full on free for trying to avoid the pitfalls of some of the mobile development landscape of the world. So all free, free to play, I'll share the code, everybody can do it. It would be kind of funny though to make, it would be kind of funny to do like a, what's the right word I'm looking for, like a parody or something. It would be funny to have a microtransaction page where it says buy a better ship for $10 or whatever and you can go in there and click it and it just gives you the better ship without actually paying. I don't know, I would find that a little bit funny but I also don't wanna mislead people about it or have anybody get crazy on me and think that it's actually real. But it is something I would find that pretty funny, truthfully. So here we're gonna go display size one which will be the width, no, okay, actually we want zero which will be the width. So we're gonna go the width of the display minus the width of the ship, self.width. I never did make width, let's do that. Okay, and then of course we don't, I was about to go press the buttons but obviously we've not called this code from anywhere so nothing's gonna happen yet. Do we wanna just hook up the buttons and then start testing or do we wanna test it before we hook up the buttons? Let's go ahead and hook up the buttons I think, yeah, why not? So I have TO connected, I'm gonna go import board, sir board, how did the D-pad work on this one? Is it off or down, left, right, up, AB, all this stuff? I think I'm gonna use keypad. I think I'm gonna use keypad and then hook up each pin individually to a keypad object. Whenever I need to use keypad, I head to this guide which is pretty much like the sacred text of keypad. We want one with multiple individual pins which is pretty much how this one works I think. And so I like doing it this way where my objects are gonna have these button event functions that way at the code pie level, we're just listening to the hardware and calling those functions which would make it super easy if you wanted to go and port this code to a different device. If you don't have a Pico system but you have a pie game or something you wanna play at the same game, you have to hook up your buttons differently. This allows you to do that hooking up of the buttons inside code pie and then you just change what you hook up your own button events and then call these functions so you can swap it over to a different device really easily. So we're gonna import keypad, set it up with one of these. I'll start with just left and right. Let's see where that gets us. I forgot to mention as well, I do have the YouTube chat open but I don't have it on the screen this time. But you can feel free to ask questions or interact in the YouTube chat or the Discord which is the one that's on the screen there. So we've got our keypad object, we need to read it inside of our main group here so we'll say event, hit event. So we'll see if that prints. Okay, it didn't crash. Here we go. Okay, that's looking good. Event, is it dot action or what is the thing that's on it? Um, pressed or released. Okay, so we'll say if event dot pressed, pressed property and see. So eventually I guess we'll want to be able to hold down. So yeah, let's say pressed else released. So I don't know if this is gonna be the exact way I end up doing it in the long run but this is how I'm gonna start is by saying left button is down equals false. Right button is down equals false. If event dot key number equals one is right. Actually let me just keep the print here I think. If key number is one that's the right button we're gonna say right button is down equals true. Then type key number is zero. Left button is down and we basically wanna do the same thing but set them back to false here. So I think what I'll do is read all the key events, process everything, set these state variables and then after we've done all of that then we go ahead and look at our state variables and actually update the game, draw the next frame essentially. We could intermix it but again this I think will make it easier when it comes time to try to port this to a different device to separate these things out. So what I'll say here is if right button is down, shipped, my ship go, not called ship it is. Ship right arrow, if left button is down. Ship dot left arrow button. I call it event I guess in this case it's actually being held down. Maybe event is not the best name for it. Come so far as to create a button class dot py file modified for specific device handy for having difference between touch and physical buttons. Yeah, there is also a cursor control which is good for that. Cursor control is a way to basically get a cursor that will allow you to click touch screen buttons using a d-pad. Okay, there we go. So it is much too fast but it does move here. So I'm gonna make also a game object, this minor game, this is also gonna be group. It's actually just gonna take the same thing as the other one. Oh, we won't have this. This is really what I meant to copy, initialize the group. And we're actually gonna go ahead and move the ship set up into here, level width and height, add the game to the group. And then so here we will not be calling ship but instead we're gonna have similar functions on game as well. And these are actually just gonna go ahead and call probably took over the chat. Apparently I opened up the help of PyCharm accidentally. We're kind of just passing this through. And if we did that correctly, we're basically still in the same state. Looks like we didn't. Game, right arrow button event, self dot ship. There we go. Okay, so for slowing this down, we are going to make it tick function. I'm gonna pass for right now. Gonna make some more variables. First one will be let's say frame delay. This is gonna be the amount of milliseconds between, no, it's gonna be in seconds actually. This is gonna be the amount of seconds in between each game frame. So let's make it 0.1 for now. We'll say 10 frames per second. Eventually we may tweak this to make it something else, I don't know. We have that. We're gonna want last update time, 0. Import time. Inside of tick, we're now gonna say if time dot, actually let's make now. And we'll want this later. Now equals, I'm not monotonic. If it's greater than last update time plus frame delay, then see what we wanna do. Basically this is where we wanna limit the speed at which we're calling these things. Okay, so I think actually what I'm gonna do is move these state variables into the game object. And one thing I could do is actually make a state object but I think for now I'll just start with these variables. I think the ship explosion larger spreadsheet but eventually, oh, but evenly spaced. The tiles are the same size. Didn't check if they're divisible correctly though. I gotcha. Here, okay. Now is greater than the last update time plus frame delay. That means we waited long enough. That is when we're gonna check our state and call our events if needed. So then back inside of here we're just gonna say, okay, these will need to be game though, game dot. And I will mention too, also like definitely possible I'm not going about this the best way, right? Like I am definitely aiming a lot more for speed than anything else. So it could be the case that I would wanna come back, change the way some of this stuff works. Could be the case that there's better ways to do some of it. But this is how we're starting for now just to see if we can get, see what we can get done quickly. Okay, so we still move pretty fast. We'll probably end up delaying this a bit more but the next thing I wanna find out though is if my time limiting is actually working. No, it's not though. It's not because we're never updating this. Last update time equals now. Okay, there we go. And that's very slow. We won't want it to be quite that slow. Let's say something like 30 frames, 30 frames per second. So one second divided by 30 frames, feel fairly slow, in 033. Dating now. So I'm trying to get a feel for if that logic is just wrong. Stream let's say now and these ones. Get a look at both of these, just see if they're making sense. Gonna spam a lot, but okay. Yeah, that looks pretty reasonable. I think that's how it's supposed to be behaving. So time we're waiting for is on the right. The time that it currently is is on the left over here and we are getting essentially about 0.03 seconds in each one. So if we put this to 60, does that speed up our movement? It does, but it does it. One thing I have found is that printing takes time sometimes. So sometimes if you are printing, especially in games where your main loop is running really, really fast, if you are printing, sometimes it will make things slow down. That is any faster actually. Are we moving one pixel per frame? Yes, and we can, if we do end up wanting to speed it up, we can definitely move multiple pixels instead. Wonder if this is, okay, we can totally just do that. That I do kind of like the feel of. That feels pretty good right there. Eventually the side to side speed, that could be one of the things that you can upgrade as well. So maybe you can make yourself faster. You can make yourself faster potentially by getting the upgrade. So we're moving back and forth now. We're limited a little bit. We got our game tick in there. Let's get it to, well, firstly, let's put the ship at the bottom of the screen. So to do that, when we create it, play height minus, let's work on shooting a laser. In order to shoot a laser, I need to have a laser image. Well, we could just do pixels or something, yes, but got some laser images. I'll start with a blue one. Let's do a nice basic one. I think let's just start with this one. So I am gonna go transparency, remove alpha, and use green. I like to use green for the green, like the transparency, go indexed. You're gonna go change green to zero. The other thing is there will certainly be room for improving the graphics. I intend to just go bare bones on the graphics, get a functional set of graphics together, and leave it at that for now. But we could have quit, just because it takes time to like convert from PNG to bitmap and indexed and get the right transparency index and all that, it takes time to do all of that stuff. And so instead I'll focus on just getting kind of one of everything I need and then build it around that and then we'll eventually be able to do that. Blue laser now, also how big is this? Nine by 37, we should probably make it smaller. I should have done that before. Yeah, I should have done that before I got this far. All right, this one more time. Hopefully I won't burn too much time on stuff like this, stuff I'm trying to get away from by not doing too many different graphics to start out with here. So let's shrink it first. Brink probably like 16, four pixels wide. We don't have too much corners actually, currency, laser, and eventually I think what we'll do is different color lasers will be different things. One of them will be the mining laser. One of them might be the blasting laser to shoot the enemies. Maybe we'll have different colors, our different strengths or something like that. It'll be time to do all of that I think at some point, but that's not, I won't focus on that stuff until I get the majority of the behavior out of the way and done. So let's get it to where we can shoot a laser. I think we should probably use image load, I think, or let's try on this bitmap and see how it works. If it's updating too slow, we might try image load and see if it makes a difference, but let's actually do stick with on this bitmap and see where that gets us. I think I'm going to make a list, lasers, I don't know for sure if we'll wanna keep this. Let's go down this road a bit, we may end up turning back around, we'll see. So basically I wanna have a list of different lasers and the thing will be is like eventually, like you'll be limited to being able to only shoot one laser to start with and you have to wait for it to fly off the screen or hit something until you can shoot another one, but that might be one of the things you could upgrade is the amount of lasers you're able to shoot before you have to wait to go off the screen. And I think a list is a good way to express that. You kinda have like a list of however many X lasers that you're allowed to shoot laser bullets, if you will. These will go on disk the same way. I think the game should hold these. Again, we may end up refactoring, I may change my mind on that later, but for now I think I want the game to hold this tile grid. So I think if I recall correctly, I think you can make multiple tile grids out of the same on disk bitmap. I might be wrong, I might be misremembering, but I wanna say that's the case. I think what we'll plan is we append the tile grid to lasers, that way we're gonna be able to have multiples, make transparent, let's put this stuff with ship, let's keep all the like things together here. So we never did add this to the group, so it's not gonna be showing let's get a def, assuming these are A and B buttons, yeah. And I don't know actually, do we want that to be part of the ship or do we want that to just stay inside the game? I think I'm actually gonna keep it just inside the game for now, so instead of calling ship A button press here, we're actually just gonna potentially fire a laser. And to do that, we need to basically show our laser at the ship and then start it moving upwards. So let's say right now we're just gonna have the one tile grid inside of our list. You know, to start with, let me just hard code it, eventually we're gonna obviously wanna deal with the list as a list, but to make that simpler for getting the initial logic out of the way, I'm just gonna say laser zero, I'm gonna do a few things. I'm gonna say laser zero here is gonna be hidden. So when we create it, we're gonna make it hidden, eventually we could have a for loop where we could make multiples of these and they all get hidden as we create them. When we go to fire it, we are gonna say laser zero, we're gonna get the first one in the list. We're gonna move its location, x equals, let's say ship dot x plus ship dot width over two, is there zero dot y equals ship dot y. I'll actually start just, well maybe minus one or something. So inside of tick or game, what we are gonna do is, if it's time to tick, we're gonna go through our list of lasers for laser in self dot lasers. Go over each one and then say if laser dot hidden equals false, if this laser is showing, we're looping over the list, we're checking each one. If the current one is showing, then we wanna go laser dot y minus equals one. If laser dot y greater than zero, we wanna do that. Else, well this update the one that's inside the list, I'm not actually sure if that works that way. Set it back to hidden, essentially we're gonna set it back to hidden when we get to the top of the display. So I think we're almost ready to test it. We will need to add the A button into here, which I guess is probably gonna be board dot SWA, hopefully. And then I think what we'll do is only trigger this one on the release. So you have to press and release, and that release is when we'll actually trigger this. Maybe eventually we have like a press and hold and it shoots multiple or something, I don't know. We'll see where we end up with. For now I'm gonna do it on release. We're gonna say LF event dot key number two. And this will be the number for the A button. We say game dot A button event. And eventually we could probably make a function called like fire laser or something like that. So it's a little bit more descriptive as far as what it's doing in the game logic. For now I'm gonna keep it just like this though and we'll see if it works. Does it crash? It does. Has no bitmap. What did we do? We probably copy pasted something wrong. 25, yeah. That's still working. So we didn't see anything there. Let's start troubleshooting. Get a print here, yeah. Oh, well, okay. So yeah, this is not quite right though. We want A button event. Yeah, well, okay. I guess I just didn't get all the way there. So we set in the location of it. The next thing we wanna do is self dot laser zero hidden false. So let's show it so that it's actually going and then inside of our tick. Okay, that part we do have. So I guess, yeah, we just never did set hidden to false. Oh, we never added it to the group. So to do that, let's go for laser in lasers and the laser to the self group, the self instance of group inside of game. There we go, that's what we're after. Okay. Pew, pew, pew, pew, pew, pew, pew, pew. So you see how the laser disappears halfway up the screen like that? But if I let it fly all the way, then it will go all the way. When it's disappearing like that, that's because I'm pressing A again and it's not done yet. So it's basically shooting the next laser before the other one is finished. And I had mentioned that that's one of the constraints we want. So actually what we're gonna do is, in here, we're gonna say see if laser's available. Or let's, actually let's do this a bit different. Let's say self.first available laser index equals but index here. Yeah, we do. That's a very important step in a game like this, the first pew, pew action. So we're gonna make a def property, property first available laser. That's gonna say for laser in self.lasers if laser.hidden equals brew return index. Index, comma, numerate first available laser index, I guess to be specific in is in return index. And if we make it all the way down here, return none. And then if index is not none. So I think this means we can only fire one laser until it is like reset, except for we have valid syntax, which is what the red is telling me question. Ah, yeah, function, we need to have this. What is this? No attribute, 46. Oh, I didn't change it to index. There we go. So I'm spamming fast now, but it's not letting me. It waits until it gets all the way off the screen and then I'm able to shoot the next laser. Perfect. That's exactly what I want for that. And theoretically, we would be able to just add more lasers to this list. And then I think we'd be able to shoot them faster, but still constrained by X number of them on the screen at once. So let's do something to shoot our mining laser at meteors. I'll just take one of these ones. So again, I'm gonna shrink first. And I think this should be roughly similar in size to the ship, maybe a little bit smaller. So let's say maybe 24 for that. Copy this new one of these layer, no, image mode, we're already on RGB. Let's go layer transparency, remove. Let's go paint bucket green, drop it there. And a couple of these ones, whoops. Yeah, let's do it about like that. Let's go mode indexed. Let's go color map green to zero, export. Let's say or zero, gray or zero in anticipation for potentially having different colors and also potentially having different numbers other than zero. Eventually we'll have maybe a random, like obviously there's a bunch of different shapes here. So we could eventually make multiples of these and they could be different shapes. There are actually some small ones too. I maybe should have started with one of those. See how big this is. Got a curiosity, that's 29 by 26, okay. Not bad, we'll do one of those later. We've got our first or, so let's copy that over. Gray or zero as it is called. Place that in there. And I think let's make a new object for this glass or I'm gonna keep with my tradition here. Not really tradition, but I'm gonna do the same thing again and extend group. Eventually these could maybe extend tile grid instead of group, some of them. If they don't need to hold multiple things like ship especially or, especially this is gonna be like an instance of this is meant to represent one specific asteroid on the screen. Not like all of them or anything. So technically it could be a tile grid instead of a group. I'm gonna leave it as a group for now just to make it a little more flexible and easy to work with while I'm still kind of plowing through the core functionality of the game. So, or is there, so we initialized that. We wanna set up a on-disk bitmap. I'm just gonna do it the same way here or bitmap and I'll just do the one that we have for now, gray or, whoop, that one. And yep, make a tile grid also. Or tile grid, tile grid, self or bitmap. Or bitmap, pixel shader, display IO.tilegrid. Pixel shader, or bitmap, pixel shader, pixel shader make transparent zero and for tile grid to self, that's the group. Okay, so I will go self.orors. This is also gonna be a list but I am also gonna start with just one of them. Self.orors, yeah, so let's just go self.orors.apend a new or. We need display size in here. Yeah, I think we'll want that. Maybe, maybe not, I don't know actually, we'll see. Pass it in for now. We could eventually go back and remove it if we don't need it. Create an or, we have appended it to orors but we have not appended it to the self group yet. So, actually one more thing we should do is when you create it, it should probably be hidden to start with, hidden equals true. You know what I'm gonna do actually, slightly different. Instead of doing hidden on my tile grid for this one, I'm actually gonna do hidden on my self, which is gonna be the group. That way up here, I can actually just go or.hidden. Close false. Good night to Shippu, thanks for hanging out. Here we go. We did not get an or on the screen. I was expecting it top left maybe. I'm guessing we never did actually end it to self. End it to self. So eventually we would decide which ones to make hidden and which ones to make visible. Eventually we'll have high levels and different levels will have different amounts of or. They'll spawn in different locations. They'll maybe behave differently eventually, all kinds of stuff like that. So we did get our first one to spawn there. We can shoot at it but of course nothing happens. They don't have collision checking yet. So let's work on collision checking. Actually let's work on the or moving itself around a bit as well maybe. So one question is, do we wanna call or.tick or do we wanna just go inside game.tick? We process whatever logic we want. I think let's go with, I think let's make a tick here. We'll see how that goes. Eventually we may change it up again. A lot of stuff here I'm doing on the fly with whatever the first thing that comes to mind is. Maybe not the best, maybe not what we end up with but that's where we're gonna start. So tick in here we'll go, let's keep some more details. Let's say the or, let's say the or, let's say it goes back and forth and maybe, yeah let's start with back and forth and then like towards the ship. So let's say self.moving left equals false. So we're gonna have this Boolean for moving left or right essentially. We are gonna say if so I will, I'll not worry about limiting the speed inside of or.tick instead we'll just rely on our if statement here to delay the speed. So in here we'll just let it go as fast as it can. So we're not gonna worry about time inside of here. We're just gonna say if we're moving left else if we're moving right, getting into buddy with the stripy boy looking awfully curious over here. I don't know. If we're moving the left then we wanna go self.x minus, yeah minus equals one if self.x greater than zero. Else maybe at this point we change back. Self.moving left equals false. So if we're moving left and if x is greater than zero, subtract one from x. Whenever x gets below zero, change moving left to false if self.x less than self.displaySizeWith minus self. Or I'm gonna say with self.with. Is there a way that I can like quickly just hook up the self, a property to a child objects property? Like I wanna make property def with and all it does is return self.orbitmap.with. That's all it does. Is there a shorter hand way to write this to say like use this child's property as my parent property of the same name? Feels like a thing that Python might have because it would reduce a bit of boilerplate although this is really not much I guess, right? So if we are not to the right edge then self.x plus equals one. Else if we did make it to the right edge change back to moving left. Or in ors if or.hidden false if it's showing or.tick. So to start with this should just make it move back and forth, yep, there we go. That's pretty fast, pretty fast. I do think I want it a touch slower actually so what do we wanna do? You could hook up get item with get adder. underscore underscore get item with get adder. I will have to look into that. I don't think I've ever overridden underscore or dunder get item before. Not sure how that one works. What do we wanna limit this a little bit more? I think maybe we do wanna deal with time inside of tick. We wanna pass time into here. Also pass self the game object into here so we could maybe do stuff with it inside if we needed. Yeah, let's start like that. Pick say now and game object. Let's go ahead and make a self.last update time. I don't know eventually we'll maybe make this like configurable or something. Like maybe they go faster as you progress through the game. Start there and we will actually limit it some inside of here so we're gonna say if now is greater than self last update time plus, you know what would be convenient is def next update time property return self last update time plus let's go self.this. So yeah, I'll do a self instance eventually maybe we'll change this in the constructor or something like that as you go to further levels they get faster maybe or something like that. Actually, I don't know if Cirque Python supports it but even better would be to define get adder for the parent then use get adder on the child. Then you could do parent dot thing to get parent dot child dot thing. Yeah, that sounds like what I want. I'll have to look into get adder some so I can figure out how that works but that sounds like pretty much exactly what I want with the last bit there. Parent dot thing, basically calling through to parent dot child dot thing. So yeah, we're actually gonna do this differently. If now is greater than self that next update time self that last update time now. And I think this should slow it down some. Yeah, quite a bit. Okay, yeah, I like that speed to start out with. We wanted to come towards the ship as well to give you the illusion that the ship is flying forwards. My intention is to leave the ship at the bottom of the screen but to have the rest of the stuff fly downwards at the ship. So essentially it will make it feel like the ship is flying forwards. So what we'll do is either way no matter which direction we're moving but still if it's time to update we'll say self dot, we'll say actually if self dot how we want to do it. Yeah, let's start like this again. I'm really like rough draft just blasting stuff out of my head as it comes. Almost certainly some of this I'm gonna want to change. I know I've said some version of that a few times now but yeah, let's just do it in here. Self dot why if it's less than it's less than display size dot height which is one then self dot y plus equals one because that is the direction of downwards. There we go. Okay, when it gets to the bottom, what should it do? So my eventual idea is that if the ore gets to the bottom then you just miss that ore and that's fine. As long as it doesn't run into you that would damage you if it does and as long as you don't hit it with the laser then it just flies off the bottom, you fly past it and you just keep going. Nothing else really happens with it. If it runs into you then it will cause damage and if you shoot the laser at it then you can collect it. I almost want to I think I'm going to leave it how it is for now but I'm thinking about maybe even making it move slower in the y direction than the x direction. I think for now let's just keep it how it is though. So let's make it so if the laser hits the ore you can collect it to get some resources. So in the game I'm actually going to keep track of this. So while we're looping over the lasers here we're going to say only for lasers that are showing and after we move we want to do this actually. Let's think about this for a second. We want to check each laser if it is colliding with an ore or do we want to check each ore if it has been collided with by a laser or does it matter? May not matter. Let's see, I think we're more likely to have more ores than lasers at least to start out with. So if we're going to loop over all of them we should loop over the smaller one. So I think actually what we do is inside of the ore thing here we're going to go pick the ore and then after we tick the ore we're going to say if basically check collision laser and ore if ore.x, okay so if that is, how do we do that actually? We basically want to say if the x of the laser is between the x of the ore plus the width of the ore which means that it's greater than the x. So if laser.x is greater than ore.x and laser.x is less than ore.x plus ore.width and that's not how you write and and I forgot a colon and I think this could be simplified to this one which I always know exists but don't ever remember how to write successfully the first time ore.x is less than laser.x and if laser.x is less than ore.x plus ore.width and we want to check another thing and laser.y let's say laser.y is less than, no greater than ore.y plus ore.height. I think that's right. So what do we do, let's say if they collide we want to hide them both laser.hidden equals true ore.hidden equals true game.self.collectedor plus one print captured ore, see if that works. We may need to slow it down or something I don't know, oh something's wrong. We didn't, I think what happened is that, okay so for one thing in order to make this easier to test what I'm going to do instead of doing hidden true I'm actually going to say, I'm actually just going to like reset the ore. Eventually we'll change this but port out y equals zero. We're just going to put it back to the top. Let me put it back to the top when it gets to the bottom as well. So it does, it does hit it but the collision looks wrong. We collide before we're there and then there's sometimes where it looks like we did hit it but it doesn't count it. Ah okay, if I line myself up right I can count it as a hit right when I fire. So something with the y, something with the y axis is wrong. Let's print, I already have a print actually. Let's go f string, capture door, this let's say ore.y, laser.y. Let's just print those and see what we're getting. We reset it to zero so of course it's zero but let's be print before we do that of course. So you see that one, it looked like they collided but it didn't count it and then that one they did 82 and 73. So if laser, ah okay I think I see it. We actually want, if laser is less than, so we actually want to check it a full like between. We actually need it to be the same way, same way that this one is. There's probably a better algorithm for this, collision detection between two rectangles. This probably exists, I'm probably not the one that can write the best version of this. Circle collision, that might be fun eventually, separating axis. This is JavaScript, so I'm actually gonna make a helper function on game def rect collision, collision. I don't know how to spell collision. My spelling is not very good, two Ls, rect collision and we basically need, I don't know why these aren't underscores. So I could go through the effort of troubleshooting my own if statement there but I am also confident this is a solved thing, I'm not the first one who's wanted to have rectangular collisions. If we can find some drop in code that does work, that'll save us a bit of time in troubleshooting but if it doesn't work too much messing around with it then I will probably just go back to writing mine. All that stuff is true and return true otherwise return false, format it, save it. Back into here, we're gonna comment that if self-direct collision. So we'll say the, let's say it doesn't, I don't think it matters which one is rect one and rect two so let's say rect one will be the or, or dot x, or dot y, or dot width, or dot height. Now laser dot x, laser dot y, laser dot width, laser dot height. So laser doesn't seem to have a height and a width which is because we did not make a class for laser. We made it a, oh okay, well it's a tile grid but it's a one by one so what it, it will actually have a width and height. This is just my, my stubs are out of date. It does actually have a width and a height but those are gonna be the wrong things. We actually want tile width which will be the size in pixels of the tile which in our case is equal to the size of the entire sprite. Okay, we, oh, interesting. Sometimes it works pretty good but other times it passes through. Oh, the camera froze, camera crashed. That's gonna kill my black screen too. Actually cheated this a little bit to make a screen a bit darker. We wanna change this up a bit. I'm gonna keep this one in case I wanna go back to it but I'm actually gonna write a different one. Looks like it's passing through from center to right side of the or. The left side seems consistent at resurg, excuse me, registering hits. If it's moving left, oh, that time we did get it. If it's moving left, it does seem to be a little easier to hit. So we probably, it's probably to do with the way that X and Y are the top left corner rather than anything else. I think I'm gonna tweak it up a bit though. I'm gonna make a new one of these Def Rect collision. We're gonna have all the same things but I actually wanna do it a little bit differently to this. Let's take these two and I wanna check differently. What I wanna do is check the, I'm gonna check just a single point. I'm gonna check the center point of the laser. Instead of checking the whole entire rectangle of the laser, I'm gonna check just the center point of the laser and then return true if that's inside the rectangle that represents the or. I don't know if we'll actually wanna print that for sure but then we're just gonna say if laser center zero, which is X, where we'll go, or.x. Or.x is less than that and if that is less than or.x plus or.width and if or.y less than, supposed to be less than, I feel like these ones might need to be backwards. Okay, I think this is wrong though. So if we suppose the or, let's just say it's, let's just say it's at like 100, 100. The y would be 100. It seems like it's all right actually. Looks like it's all right, over-indented. So I think that that checks the center point of the laser to see if it's inside of the or rectangle. Okay, now we're feeling pretty good. Yeah, okay. It isn't much of a game but it's enough to be kind of fun. I think that's pretty good for our collision. So what do I wanna work on next? Let's say, let's think about this for a minute. Oh, okay, let's do collision with the ship. Let's make it so if the or collides with the ship, then you will take damage. I don't know exactly how I'm gonna end up representing the life of the ship. I guess we're about to kind of figure that out. I think, I think what, I don't want it to be like, oh, oh no, okay. Wasn't scrolled, but it is. I don't think I want it to be like you get hit by an or once and that just destroys your entire ship. I think what I want is a couple of hits. That way you can eventually buy upgrades for like better armor stuff and that would increase the amount of collisions with the ship that it takes to actually damage it. So let's go inside of a knit. Let's go self.health equals, I don't know, let's start it nice and easy at 100. And our tick here for each of the oars we're already going over this. Let's go after lasers. That way, that way, if basically we wanna give the player a chance to capture the ore, the frame before it runs into them. If they manage to shoot the laser, the frame before they get hit, they should capture it not get hit. So I wanna put this after we check all the lasers. There's no four, we're just gonna say if self.ship collision and then we're gonna go if self.ship.health greater than, we'll check this after actually. Let's go self.ship.health. I don't know, maybe minus equals 10 or something. Let's just start there. We'll see minus equals 10. Oh, right, right. It's like, is that a thing? Yeah, I guess it is. It's a totally different thing though. Needs a ship damage indicator. Yeah, I think, yeah, we'll do something. Maybe we'll do a progress bar or something like that. Kind of like a fighter game where you have a health bar. I don't know if that's not necessarily probably the traditional way for this type of like Asteroids game, but I think I like something like that. That way we have a nice big range of health that we can play with the upgrades on. So let's say minus 10 and we'll play with the numbers later. If minus 10, then we just say if health is less than or equal to zero, then we'll say print game over. Eventually we'll change this to do something else as well. We can go ahead and start making our game into a state machine, state playing, zero. Actually, let's go, we'll have a state waiting to play, or I'm gonna call it, yeah, waiting to play. That one's actually gonna be zero. This one's gonna be one state game over to the inside of tick. We need to make current score, I mean state. I guess we might as well start just right away. Let's go state waiting to play. This one is state playing. I'm gonna leave it like that for now in the side of tick, but what we're gonna do is inside of a button event, if we're playing, we'll do this. Actually, let's just go else. Let's just go else, change it to state.playing. So if you press the A button while you're in the waiting to play or the game over, then it will start the game. So by default, I think that means like when we first start, our ship should not move and our asteroid should not move, which they don't. But if I press the A button, then they should start, but they didn't and instead it crashed. So we will look, ship collision spelled wrong, I think. Two Ls, one S, like I probably spelled it wrong. Well, I didn't have one yet, I guess. Yeah, it looks like I don't have one yet. You only have one ship, we don't need to pass that in. And how am I gonna do this one? I think let's do this one by saying, let's say if, I'm actually gonna make this a little bit more generic. We're gonna say def point in rect, that one's there. Or is our rect, so we go rect, x is zero. We're gonna go x, y, width, height. So zero, one is x, y, width is two, y is one. Laser center is our point, y is one, three. So this is gonna be like a tuple, x, y, width, height. This is gonna be a tuple of x, y. This way, here, we can actually abstract this a bit and say if point in rect, point is laser center. Rect is tuple with or, x, or, y, or, width. And then for ship collision, I'm gonna say, I'm gonna choose the point at the bottom center of the rectangle, basically here. If that point is touching inside the rectangle of the ship, then we're gonna consider that a collision. So or bottom center equals or dot x halfway. So x plus or dot width over two, the y is or dot y plus or dot height all the way. No dividing by two, because we want bottom. So then if point in rect, point is or bottom center, rect is ship x. We need a tuple, ship dot x, ship dot y, ship dot width, ship dot height, these are all self. Go to game over state and print game over. Eventually we'll have game over graphics it'll show a label or something, we'll do that. But for now let's try like this, camera froze again. Oh boy. I think it's like if I don't use it enough, how it knows that I haven't loaded the tab in a while and it dies or something. Okay, so I pressed A and it started. I ran my ship into it and then it just paused. Seems odd. Game over. Oh, I think we need to like, it's gonna collide every game frame. We need to like remove the or. So I think we should go, if we did collide but the game is not over, we want to go or dot y equals zero. Move it back to the top for now. Eventually we would like hide it, it would go away. We wouldn't have that or anymore, that'd be fine. That appears to be working. Let's make this go like 25 instead. That way we only have to run into or four times. Now we're back to game over state and I could play again by just pressing the A button. We should make reset. When reset happens, collected or goes back to zero. Health goes back to, let's say, ship.starting health. Go make that. The way we can tweak it later, much easier. So now if it resets, we should get our entire hundred health back. Oh, no, we're still getting game over right away. Oh, we didn't call reset. When we go from game over to playing, that's when we want to call reset. So that's in the A button press, A button event. Else here we're gonna say reset. There we go, okay. That should be the fourth one, yep. Okay, so that's working. Let's see. We have been going about two hours, got a bit of a slow start because it took me a minute to get YouTube running. I know it's definitely been a long day so I don't necessarily wanna go too much longer but I do still wanna get a little bit more done. And again, like I said earlier, I think the plan is gonna be work on this again tomorrow morning during my stream. So I stream at 10 a.m. central time on Saturdays. Typically it'll be working on CircuitPython libraries or projects or whatever I'm getting into at the time. I think what I'll do is work on this tomorrow during the stream as well. And then have those couple hours of tomorrow's stream be kind of the unofficial end of the game jam. We'll kind of see where I'm at after that. I don't necessarily think I'll have a fully feature complete game. That's not necessarily the point here. The point is to have a playable game that's kind of fun enough to be able to play with a demo and I think we're well on our way to that. In fact, I feel like we're a lot of the way there right now. This game is not very fun right now because you don't do anything with your points and it just kind of starts over but we've got the basic game loop. We've got the core sort of feedback loop working pretty well. And so I think we could spend some time tweaking and tuning and just making fun things in that feedback loop and we'll be good to go. I am gonna do I think one more thing though before I go. So let me show I think health. We have a progress bar. It would be cool to show a progress bar with the chip's health and that should be pretty easy I think. So I will try to hook that up and then after that I think call it a night. So progress bar, get hub, simple test, circup, install, progress bar. What do we wanna use for width and height? We want to use for width and height. I think, ah, this is tough. We don't have display size in here actually. Maybe we should do it inside. Do we wanna run the entire width? I don't think so. I think I want it to be in the top right corner and I want it to be not the entire width, just a portion. So I think maybe width will actually maybe just hard code. I wanna say this screen is like 240 by 240. Maybe a third of the screen is what I want but I think I'll just hard code it to 80 width is 80. Height will be really short. Start with like five and see what that looks like. X, Y, this is gonna be, so X is gonna be display width minus 80. Y is just gonna be zero. Width and height are gonna be the variables. Direction will go left to right. Here's what the default color is. Health, progress bar in that. Our value minimum. Value, you set the maximum. Max value. Start it on 100. See if that shows. It does. Yeah, it looks like it, okay. And let's make it minus each time. So when we get hit by the four, doesn't look like it. Oh, actually it is. Yeah, it's this little teeny tiny black bar in there. Actually, I do kinda see it. It's very tough on this size screen. Maybe let's go play with this a bit more. Let's say let's make the height bigger and then let's change up the colors. Maybe let's try eight, see what that's like and then let's go, we have fill color. Oh, we have a border thickness. Let's go border thickness zero. Yeah, let's actually just try like that. Seems like this usually have numerical output like octopus game for health and score. Ah, yeah, there we go. Nice. Oh, we'll need to update the inside of reset. We want to update the progress bar as well. That way it'll go back to full. Ooh, so that time we caught, if you let the asteroid go past you, since I'm checking for collision on that bottom point, it, you can kinda collide with the back half of it and not get counted. Maybe we'll add one more check to actually check the top middle pixel as well. I don't know that we necessarily need to check the entire rectangle, but we could maybe check the top middle pixel as well and that would make it so you can't really cheat by letting it fly past you too much. Okay, so yeah, eventually we'll also put the amount of ore that we've collected on the display somewhere. Right now that's not showing, but we've got our life bar, health progress bar hooked up, which is pretty nice. Eventually we'll be able to make the ship have more health or have armor that mitigates some of the damage from the ores and stuff like that. So I think I will call it there. I'm feeling pretty good about this. I've got, again, kind of the core game loop function working here, the feedback loop of the game. Obviously there's still some stuff to do to turn it into more of an actual game instead of kind of a proof of concept. I think we're pretty much kind of in like the proof of concept stage right now where the most basic stuff functions, but it hasn't been built into a game yet. We haven't gone over it with an eye towards making a fun game to figure out, where all the updates and how much the different upgrades and stuff like that are gonna cost. I think that's kind of what I'll work on tomorrow. Thank you everybody who is watching. Thank you everybody who participated in Circuit Python Day. I hope everybody had a wonderful day. This is the last stream for Circuit Python Day, so no more going on with regards to that on streams and stuff, but I will be back tomorrow morning again at 10 a.m. central time over on my own channel to follow up with the second half of the game jam. So follow me over on Twitch if you want, foamyguy underscore Twitch. You'll get notifications. The other thing you can do is if you just head to the Adafruit Discord in the live broadcast chat, I'll always post the links when I get started on Saturday morning streaming. So you can head there, look in the live broadcast chat and I'll drop links when I get going. So thank you to everybody. Especially thank you to everyone who helped get me up and running, got YouTube sorted out and pointed out some stuff like that, letting me know that we were good and live by then. Thank you to everyone who helped out on Circuit Python Day. Paul Cutler did a bunch of work today, so I definitely wanna say a thank you to Paul Cutler for everything that he's done with the panel and just a bunch of stuff today, so thank you there. Thank you, of course, to Adafruit. I will leave you with something I normally start the stream with, but I think I did not say it today because I was a little flustered by YouTube not working out yet, but what I'll say is, Circuit Python is an open source project. All of us that work on Circuit Python that get paid are paid by Adafruit to do so, so thank you to Adafruit. And if you wanna help support the project, one of the ways you can do that is by purchasing hardware from Adafruit.com. So please, if you are interested in buying some fun toys to play with, take a look over at Adafruit.com. They sell microcontrollers that run Circuit Python. They sell bits and bobs, doodads, lights, buzzers, beepers, buttons, levers, motors, all sorts of things you can imagine. They sell all of that kind of stuff, which you can write Circuit Python code to interact with. Of course, I'm working on a game today and it's on the Pico system, which I believe Adafruit stocks. I wanna say that's where I purchased mine. Yeah, Pico system 44 in stock, so if anybody's interested in the particular handheld that I have, here it is, you can purchase that over at Adafruit. It's got it like a little Mario game that you can play on it as well that you see in the video there. So lots of fun stuff you can do with this device. It's made by Pimeroni. It's not an Adafruit device, but Adafruit does stock it. And yeah, thank you again to everybody who does purchase hardware from Adafruit, because again, that's how the whole project keeps going. That's how those of us that get paid actually do get paid to put time into it. So thank you again to Adafruit and everybody who purchases hardware from them. And I think that's it for me. So I will see you all next time. Hope everybody has a good day.