 Welcome to space arena the ultimate python turtle graphics game tutorial part 19 where we make enemy missiles, or at least we try Welcome everybody. It's been a long time since I've been able to continue this particular Tutorial series. I do apologize for the delay. So, you know, I have channel memberships now I'd like to shout out to Kevin and Paul my very first two members So there'll be a link down below if you're interested. So let's take a look and see what we have here We've got space arena. So in the last Lesson we did this splash screen and what we want to do today is we want to add the ability for enemies to shoot missiles Hopefully at the player. So I haven't quite figured this one out yet We're just gonna let her rip and see what happens. So we've got our player player rotates space bar fires and We kill an enemy. It's you know Changes the level and we get more enemies. There's different types of enemies red ones attack I think pink ones run away and orange ones sit there and chill for a while So yeah, so what it is we want to make it so that these enemies can now shoot at the player And what I want to do is I'm going to go ahead and just make a copy of the missile class For those of you who are curious, I get this question a lot. I am using the editor called genie It's free. It's open source. Check it out at genie.org So what I'm going to make go ahead and make I'm just going to copy this class And make a new class called enemy missile And I might not have to do it this way, but I think it's going to be easiest So I'm going to go ahead and copy it and paste it And then I'm going to go up here to change the name. I'm going to call this enemy missile note the the style here it's it's uh Like it's camel casing. So or just Pascal casing. Anyway capital e capital m and I want to Use this class now. So what I want to do here is go to Where I create the missiles and to be honest, I don't remember where that's at But I think if I do a little quick search, I can do The missiles dot append it should be there somewhere Yosh, that's what we wanted So I'm going to close that and you can see here. I've made three missiles But what I want to do is I want to add one more. So I'm going to say Let's go ahead and say add enemy missiles now since this is a copy of the This is a copy of the Missile class for the player I'm going to just basically do the same thing. So missiles dot append I think this is going to give us an not an error error, but it's going to it's going to work really weird And we'll fix that later So I'm going to go ahead and put zero 100 just like I did here I'll make the enemy missiles circles as well and we'll just make them red So that we know which one is which So I'm just going to try this and see what happens. So Now watch what happens when I run the program if I run it I'm going to be sitting through this splash screen every single time and I don't want to do that I'm I'm kind of an impatient person sometimes. So what I can do is if I Go up to here before just before I do the splash screen. I'm going to say win dot tracer zero I think that will do it Yeah, so that's going to speed that up Okay, so now oops So you can see now the missiles aren't working Okay, and the reason is I did some kind of bad coding. I think the last time when I did this um So the missiles now have there's because there's four missiles in the uh Missile list So if I go to player And where the player fires So you can see here where I look for a number of missiles and I have one two and three hard coders This probably wasn't the best design choice. So to fix that I'm going to go back to where I made that missile And I'm just going to search for that. So it was missiles dot append And instead of appending to the missiles, I'm going to go ahead and just Append that straight to the Sprite list. I don't know if it's the right choice But I think it's going to work and I'm going to say sprites dot append Okay, and then I'm just going to go ahead and run that and see if we've got a missile anywhere And start Okay, now I don't see the missile which that probably is a good thing actually But now firing is working again So sprites dot append sprites So when we start the game, I'm just kind of trying to remember how the game works. You see we've got game dot start level So if I go up to start level, you'll see sprites clear So oops, so I'm going to go back to uh where I just was And where was that actually? I should have made a note of that because this is now a very long program And what I could do is I could separate the classes out into a separate file if I had to but let's just keep it one file um, so here at enemy missiles, let's go ahead and Cut that out of here and let's go put that into the Game start level and just one thing you notice how Yeah, I'm kind of making little mistakes here. Now. I actually did look at this earlier I kind of figured that wasn't going to be the right spot, but I do want to see you see I want you to see me making mistakes Everybody makes mistakes You know, it's just it's just a part of life's imperfections. So I want to put that here and let's see what happens now Okay, so I'm not seeing it on the screen, which is probably a good thing So It should be at zero one hundred and missile missiles writes a pen Uh, I think I know why and this is this is by design because we don't want them to appear at the beginning so where is The enemy missile class So the state is ready Um, so unless it's active, we won't see it. So let's go ahead and make the state active and see what happens By default just we're just testing here And watch quickly Oh, we got an error There's no shape name circles. Did I really do that? Really? Uh, let's see one of those days. Um back to start level Um start level on start Yeah, I really put circles there. Oh my gosh I should have my license taken away for this. Okay, and you can see now we had a little bit of a Missile there So now what we want to do Is we want to Have that missile fire Now that's gonna have to happen in the main loop Actually, I should put that back to enemy missile Uh, make sure it's not active when we start. So ready and Now in the main loop You know with the regular missile with the player missile When the player pushes space, that's when it fires But since the enemies don't really fire Um, that's not really going to work for us or you know, we have to figure out a way to get them to fire So what I'm going to do Is when I'm playing the game Let's see here update sprites playing clear Render sprites Check for end of level Well, okay There's a lot of stuff going on here. Um, so why don't I do this? Game state equals playing And before we check for collisions, let's go ahead and just put this in here. It doesn't have to be here But we can put this here. So fire enemy missiles So the first thing we have to determine Is we have to find the enemy missile Um So let's think how we want to do this Okay, I know Again, I didn't plan this one out ahead of time. So that's why there's it's not quite as smooth as I usually Like to think I am at least so I'm gonna go back to Uh start level And you can see what I did here is add missiles. So I'm gonna try and just kind of copy that So for I'm gonna say for enemy missile In enemy missiles, I know I haven't created it yet missiles Sprites append Enemy missile I'm gonna cut that out Yeah, I'm sorry for all these changes, but again, I think it's important to see this process That nothing ever works The way we plan them, um So yeah, so let's go ahead and give this a shot here and then finally I gotta come back down to Uh Missiles dot append I find that again So I'm just gonna basically do the same thing But with enemy missiles. So enemy missiles Equals and that's a list and for now we're just gonna have one missile in range One I'm gonna say enemy Missiles dot append as I copied that earlier So then up in the game dot start. This is game dot start level. Um, so let's see We did that And then down here now we gotta go down to the main loop. I know this is jumping around a lot, but This is life. Um Can I do that over here? Nope. Okay, so we created the missiles Okay, so you can see down here think No Okay, so now what I gotta do is for enemy Missile in enemy Missiles if enemy Missile dot I think it's state equals Ready Need to fire the missile Now to do that We need the missile to go where there is an enemy Okay, so for now what we'll do is we'll say for sprite in sprites if is instance Sprite an enemy so if it's an enemy We'll say enemy Missile dot go to enemy dot x enemy Dot y I think actually it might not be right. It's been a what such a long time since I looked at this code Um, let's go back to enemy Okay, sprite Let me just check out the sprite class Yes, that there's an x and y. Okay, so I'm just gonna go and try this and see what happens Oh, and then I need to also Uh, should go back down where I was We need to And I'm gonna say enemy underscore missile dot state equals Active and notice I haven't given it a direction or anything like that. We'll get to that in a minute Let's go ahead and see what happens here huge thinking this will work Okay splash screen This logic has no attribute go to yeah, so enemy missile Dot x equals Uh Yeah, this is totally wrong. It's been a while You're gonna hear that a lot probably in this tutorial sprite dot x and enemy Missile Dot y equals sprite dot y Okay, so let's try that again So basically I'm just trying to find the first enemy I can in my list of sprites And then move the missile there instead. It's active Okay, there's the enemy now since this enemy is not moving. That's not gonna do much Okay, so you saw that you saw the missile there so you see how the missile keeps appearing Okay, so this this is what sort of what we wanted to happen Um Now it's stuck there for some reason so something went wrong with the code, but that's okay. We can we can live with that um So we need to target the Missile at the player Okay, so I think that code is in here somewhere Let's see if I can do a little search for a tan New cancel a tan two Oh cancel Alrighty, this is gonna be a problem Um, I think I know how to do it though um So Let's see here. I'm pretty sure to do this. It's been a while since I tried this, but I've got math. Okay. Let's try it What the heck let's get a shot um So basically we need to set the heading of the Missile to Towards the player Okay, set heading So To find the heading It's heading equals math dot a tan two And i'm pretty sure it's player dot x player dot y minus Sprite dot y Comma player dot x minus Sprite dot x And let's say print heading and see what happens Uh Because I want to see that I also want to see enemy Missile dot heading equals heading I think this will do it maybe it's still not gonna move but that's a different problem Okay, so you can see over here the heading 2.8 2.5 2.10 The numbers are pretty consistent. Let me move the player See if those numbers change at all Okay, good. Yep. Okay. This is good Okay, so these numbers this this formula gives you that heading in radians Um radians is just some math system. Um, so We need it in degrees so radians is Uh To get radians to degrees you need pi over 180 over pi Uh times I think it's 180 over 3.14159 Pies that's about pi. Um, let's try that two times I think that's right No That's not right Oh, so Okay, so that's wrong. So enemy Missile dot heading Okay, let's try that print that out. Okay, this is good. So 36 degrees Which is about right now the player is moving. So now yes, it's working. This is this is what we want to Okay So you can see how the the bullet's still firing But it's not moving. Okay, so that's that's fine. We can live with that. Um, so now Now we need to get the missiles dx and dy matching the heading So how do we do that? How do we do that in other other areas? Um Let's see here Let's go to let's go to missile. Let's see how the missile class does it Oh, okay Okay Interesting Okay, this makes it really easy. Okay. So what we got to do Thank god, uh, it's fairly simple is We've got a fire the missile So we've set the heading an enemy missile dot fire And that should send it towards the player I think Oh for heaven's sakes fire Seriously Let's take a look at this Oh Well, okay All right. So x y heading. Okay. So I need to send these values So x y heading dx dy. Okay So Now this dx and dy was from the The speed of the already moving object and this x y is its own x y Okay, yeah, I can do that. All right. I think that's gonna do it So This is not the prettiest prettiest tutorial ever as I do apologize, but I think it's gonna work So all this stuff I did here. We don't have to do We can actually except for the heading we need to calculate the heading So what I need to do here is I'm gonna put In here it's that fire. So x is going to be the sprites dot x that we're firing from The sprites dot y the heading we just calculated Um, it will set the active state for us. We don't want to deal with that anymore And Heading we need to calculate and dx and dy is going to be the sprite dot dx and the sprites Dot dy normally we're previously with the missiles We were firing from the position of the player, but now we're firing from the position of this sprite that we found Okay, so let's go ahead and try that Fingers crossed Okay, so you can see It's firing, but now Not quite the right direction, but that that's a start um All right, I can live with that. That's that's that's reasonable. Um, for x y sprite dx sprite dy I want to go ahead and print that heading again. So print enemy This little dot heading And just make sure the heading part's working Okay, so we're we're getting the wrong Formula there Oh That's right So we gotta actually change the heading so that we get the values there. So I think that's gonna fix it So let's comment that out for now Okay, so you can see it's shooting towards the player roughly Okay, so that that's working. That's oh, that's what we wanted Okay, I'm liking this now. I'm pretty happy. Okay So it's not particularly accurate, which is okay. We don't want the game to be too hard. Um Let me think about that for one second. Uh, that was good Okay, I can see it's always going to fire from that one enemy. We'll fix that in a little bit Let's let's get the collision working now. So that there's a collision between the uh player the, uh Missile enemy missile so Let's try this here. So let's deal with that So enemy Collisions Okay, so, um So this is for sprite in sprites Okay, so if is instance Sprite Enemy missile Need that extra Where this is there and get rid of that I could have it wouldn't hurt anything Uh Sprites Dot State equals active And Sprite Dot collision. Sorry is collision player Okay, so sprites Dot resets that resets the missile Player dot health Minus equals let's say 10 just try that I think that's it. Let's try it. See what happens So if it's a so if it's a miss enemy missile And if it's active and it collides with the player Reset that sprite I think and then Set the player health minus 10 so to get close enough that I can get shot here Um Oh, it went down. Oh my gosh, it works. Yeah, it's not particularly accurate. That's that's a different problem It's not accurate because the uh other player is moving I think Hey, let's let me shoot it. This person see what happens Um Oh, yeah. Oh, yeah, so I'm getting shot here and Okay, so you see that's still shooting at me Okay, it works. Okay, so I guess it's working. Um, the only thing I don't like about this is it always shoots from the same Uh enemy so what I'm gonna do and this isn't probably that pretty but um What I'll do is I will gonna make a list of enemies And let's go up to that code. Um So for enemy missiles and enemy missiles, um Um So right here what we're doing is if the enemy's missile state equals ready, then we're gonna fire that missile um Okay, and then for sprite and sprites So what we're gonna do is find all Find all enemies okay, so So I'm gonna make a little list of enemies And what I'll do for sprite and sprites if it's an enemy Uh enemies append Sprite So that gives me a list of all the currently current active enemies And then what I'll do Is I want to choose one enemy. So enemy equals random dot choice enemies So that gives me one enemy and then I just need to Undent this I think that's it and player player Sprites and then this needs to be changed to enemy Yeah, there's probably a better way to do this, but I think this is gonna work and it's pretty straightforward um It's also I want to get this done in a few minutes. So enemy oops enemy and So we'll have to get this to level well first. I'll see if it still works on level one Okay, so you see how it's shooting at me. It's hitting me boom, okay, so let's Go ahead and shoot back now We've got okay now. You can see how sometimes it's shooting from one Okay, we got we got a little error there Um, okay, so it's shooting. Okay, so you can see how it's shooting from different directions now This is pretty cool. Um, now it makes it really challenging Um, so we might have to add some kind of timer so that it doesn't keep shooting constantly And you can see I've got some kind of error there with like a hidden enemy showing up But we'll just let that go for now. Okay. That's one of those things we'll fix later. Um, but yeah So that's that's it. Um, it actually works. I'm pretty happy with it Um, again, I know there's a lot of like going back and forth on some of the code because like I said I haven't looked at this this code in ages and but I will put this this finished version Up on github so you can link down below where you can download that Um, so just you know watch back through the video, but basically what we did Was we created a new enemy missile class And it's just a copy of the missile class that does all the same stuff And you know, we might end up changing that a little bit later Letting the enemy missiles function a little bit differently, but for now we'll use those and then um We made a list of those missiles somewhere enemy missiles and You know, we could make more than one but for now we'll just use one and Then in the Game.start level boy, this is complex We added those missiles to the sprites list Which is which is important And then down here in the main loop We uh, basically checked and see if there were any Uh missiles I'm still scrolling down If any of the missiles were ready and if so Find all the enemies choose one at random and shoot at the player from that Spot and then finally we had to check for a collision Between the enemy missile and the player and we took off 10 health So those are the different parts that we did today. Wow, that was intense Um, I hope that helped more than it hurt and I hope uh, this uh satisfies your need for more space arena Until the next time. Take care. Keep on coding