 long time since I've been able to do a video, but due to the coronavirus I'm home a lot more, pretty busy, but I have a little time today. So I got a request from a viewer, a comment on one of my videos saying, hey, I'm making a similar game, you can see that here, except I want, when the key is held, the character should immediately go to left or right. For some reason the character does not move at all. So I thought what I would do is I would do like a quick kind of debugging session and see what went wrong and see if we can figure that out. Now I haven't actually gone through this yet, don't know if I'm going to be able to fix it, but we'll see how that goes. So the first thing I'm going to do is just go ahead and run the program. People are going to probably ask, currently I am using a editor called Genie, G E A N Y. It is free, it is open source. I definitely recommend it just because I like free and open source software and it does a pretty good job. So to run the program here, I want to use the function key. I'm going to press F5 and let's see what we got so far. And you can see we've got some cool stuff. The person who posted this has used a custom shape, which is really cool. And then we have some balls are falling. I'm not sure if we want to catch them or not catch them. I don't quite know how the game works, but I want to hit the arrow keys and nothing is happening. So there is no movement. So let's stop that. Now a couple good things here. There's no syntax errors. The code itself is structured correctly. It's just not doing what we want it to do. So just going down through, just kind of a cursory glance at some of the things here. I already see something I don't really like. I see two things here. I see global variables, which we always want to avoid if possible. And you can't always avoid it if you program things right, but it's best not to use global variables. And the other thing I see here is the variable name doesn't make any sense to me. Left T, right T. Something that I tell my students all the time is a variable name should be immediately clear what it is and what it does. Left T, right T doesn't mean a lot to me. It does have left in there, which is good. I'm glad it wasn't LT and RT, which would be even more cryptic. So yeah, that's something we want to try to keep an eye on is variable names. So I'm just kind of going down through. I can see this person has used some turtle methods and things that if you watch my videos, you'll see some of these things. So I assume that they came out of there. This person has also registered their own shape, head, and that's why you saw that kind of cool little bucket. I don't know what we call it, bucket at the bottom. I thought that was really well done. Let's see here. Tracer, I think this might be why it's moving a little bit slowly, which is a little odd. Usually I use a zero here. Let's just see what happens if I change that. Yeah, that makes it move a little bit more smoothly, which is probably what we want. Okay, so it is catching things. So if things collide with it, if they go into the bucket, let's watch this. Okay, so it is being caught, which is nice. So I think we kind of get an idea of what we're supposed to be doing, but we're still not moving. So let's kind of scroll down through here and take a look at some of the stuff that's being used. You see this person is using classes. He's also using the concept of inheritance. So the sprite is a child of the turtle's turtle class, turtle modules, turtle class. It's a little confusing. There's a collision method. Okay, so basically this person is using the Pythagorean theorem to measure the distance between two objects. If the distance is small, it means there's a collision. And catch. Okay, so they're using a couple, yeah, they're using basically kind of the same kind of concept here with the apples. It's catching if they've caught an apple. Okay, so basically looking at a certain area around what they call the head and to catch the apples. All right, so that's looking good. P1 sprite, let's see. Again, P1, I don't know what that means. Again, I'm just really picky with my students and their variable names, class names, variable names, really got to be clear. And I know to that person it's really, really clear, but to everybody else it's not. Something I see here now just looking at the code is we've got self.leftT and self.rightT. So this is a little bit better. So instead of, you know, these global variables up here, we've got some class variables or instance variables, I guess in this case. So I definitely like seeing that a little bit better. It's a better structure. Let's see if it's used later. Okay, so we got an apple class, very, very clear what apple is. That's the dropped shapes, I would assume in this case. And, okay, so everything seems like it's working there. I don't see that leftT, rightT thing here, which is fine. Now this is where it gets a little interesting. We've got some methods here. We got left self, right self, left y, right y. Interesting. So again, I'm not 100% sure what these methods do. I mean, I can see they change the value of leftT and rightT to false, which I get that. So again, I'm just trying to, you know, this is code that I have not written. It's based on some code that I've written. So a lot of it's familiar to me, but I can see some issues here. And you see here, we've got leftT equals true. So here's the problem that we're already going to have. So this has been declared global here. It's going to set the false. So the assumption is that by changing leftT here, it's changed everywhere, which is okay, I suppose. But I'm not sure why you would do that if you've already got leftT and rightT here inside the definition. So that's kind of a, doesn't make a lot of sense, why that's being done. So I think that might be part of the problem somewhere. Another thing that I want to point out is, you know, as when beginners program, they have this tendency to program a ton of stuff, then test it, and then debug it. Just as a matter of principle, now probably what happened is this person wrote the whole program, maybe the way I had had it and decided to update it. I'm not quite sure what happened here. But if you have a left method and a right method, you should never even consider doing that right method until you're absolutely certain the left method works, because they're basically going to be mirrors of each other. This is something I tell my students all the time, get one of them working. Okay, if that's working exactly the way you want it, then you copy, paste, and just change it. So left, change left to right, et cetera, et cetera. So yeah, just, you know, it's just good practice. And it makes your life easier. It makes debugging a heck of a lot easier when there's less code. So this right code shouldn't even be in this program right now, because it's not working. Okay, now coming down here, okay, so I can see P1. And again, I mean, you know, it's, I'm sure this is player one. It's not, you know, it's not a huge leap. Okay, to assume that. And again, also another thing, a little thing I'm just a little pet peeve about is consistency in formatting. If you're going to put a space before and after an equal sign here, put space before and after equal signs here. Okay, which just, you know, makes things easier. Now here's probably where there's, there's some problems. We have on key press, on key release. I don't even know if there is an on key release in the turtle. I've never used it myself, but I can see it. Now I can kind of see what this person's trying to do. So when we press the left key, then it calls the left method. Okay, okay, okay. Okay, I see what they're trying to do. This is also coming from like kind of an incomplete understanding of how methods work and how classes work. But I think, you know, they're, they're onto something here. It might work. The other thing I'm seeing here is with the turtle, I don't know what the turtle, how do I put it, the turtle module. When you put a method in here to be called, you can't send values. You can't do it like that. It's got to be like this. Left, okay. So what they were trying to do just simply doesn't work. In this, in the turtle module, I don't know why. It's just the way it is. There is a way around that, which I will get to in a few minutes. But yeah, so that's not being called correctly. Now left, now I understand the idea was here. Again, we're looking at the player. So, so I would say p1.left t, because it's always going to be player one in this case. Now if you want to send that value, I'll talk about that later. So what I'm going to do is I'm going to try and fix left first. Okay, kind of practice what I preach here. So if you recall, in the p1 class, there was a, an attribute, or two attributes, I have to say, left t and right t. They were set to false. And this person is saying, okay, left t is true. And check for border checking. Okay, I guess I get that. All right. Yeah, again, just the code's like really mixed up here. And it's not quite properly, not actually properly organized, but it's not organized clearly, I think. So because the movement is actually done down here. I'm going to put some spaces here and clean this up a little bit. So it's saying if left t equals true, x plus five, x plus equals five, print high. I'm assuming this was used as a test, which is a good idea. But I would call this, you know, left t is true. Yeah, it's a little bit more voluminous. So x plus equals five. Okay. So I'm going to put in here p1.left t. So I want to get, I really want to get rid of these global variables. We don't want to use those. And since this person has already kindly and wisely put them into the class, I'm sure we can eliminate those in a few minutes. Okay, so yeah, so I'm going to save that. I'm going to run it and see what happens. So again, I've only fixed left. Okay, I fixed left. Okay, so so far so good. Now it's going off the screen. Couple things. When you're going left, x is minus equals five. Okay. So let me, okay, I fixed that. Again, another thing that drives me nuts with beginners is, okay, oh, I fixed it. I know what I'm doing. Then they go and fix everything. No, no, no, no, no. Change this and test your code. Okay, so I can now go left. Let's see if can I go off the screen? Okay, so it is stopping me here. It's not stopping me right at the border, which is fine. That's an easy fix, but it's kind of working. All right. So let me go back up to here. And again, also another thing is, you know what, you probably want to comment your code, you know, check for left border. Okay, so 280 was not far enough. So let's try 260. And this is this is kind of standard border checking. Again, notice I'm not touching right right now. Once I get left working, then I can go ahead and think about right. So function five. Okay, it's kind of getting closer. Let me go ahead and terminate that and let's try 250. That's going to be enough. But let's see. Yeah, so I'm just kind of playing with the numbers. I don't know what the right number is. But I do like this up things. This is nice. So it is stopping. It's not perfect, but it goes off a little bit. But we'll take that as a win. So now, so let's say basically what we got, we've got left working the way we want it. So what I'm just going to do is I'm going to go ahead and copy this. And I'm going to go ahead and paste that. I'm going to change that to right. And this should be right. And I wouldn't use that variable name, but that's what was chosen. And this should be on the other side, it's probably greater than 250. Yeah, if you're not sure what this does, please watch the the following sky's tutorial, which is linked here. I'll put it in the description. Kind of talks about that border checking thing. Actually, a lot of my videos talk about that, but that one's more specifically related to this particular program. Okay, and then I need to come down here. Well, I already changed that. So I kind of defeated my own purpose. And I think we don't need this anymore, because we know left T is true. And also, I need to change this to P1 dot right. See, save that. And I'm going to run it and see what happens. Okay, so oops, whoa, it just went off the screen. That's funny. Let's see what went wrong there. Okay, so right, as I mentioned earlier, is plus five, not minus five. Okay, again, I made one little change. I'm going to test it. Okay, I'm going to write. Now, that's weird. So it went right off the screen there. Okay, I know what I did. Okay, so this same thing, I should have copied this also. Got a little greedy there. Got a little rushed. This should be right. And again, I don't really like these variable names, but you know, what are you going to do? But yeah, that's also a matter of kind of personal choice as well. But still, this stuff could be put into the class itself. We don't have to have separate objects for that. That would kind of do maybe a little bit more of what the original poster wanted to do. But you know, for beginner, this is a pretty good mashup of the different styles. So I'm going to go left. Okay, so that's still not working quite right, but you can kind of play around with that. So I can't catch things, which is cool. This is fun. This is very nice. Actually, it's really nicely done. And then you can see how the right border is working, sort of. Again, the problem is that the border checking shouldn't be done here. It should be done down here. So let me go, let's go ahead and fix that. Cut that out. And on the left side, so after we change the position, okay, good, this person's using spaces like I do. So we should set the position, move it, then check the border and update it. That'll get us around that problem. So again, where you put certain things in the code makes a big difference. Let's see here. Check for, I should say check for right border, sorry. Okay, and function of five. Okay, now where was I going to, okay, so we're mixing tabs and spaces now. So those are spaces. Okay, so this is not set up correctly. That's my fault. Four copies. So you cannot, in Python three cannot mix tabs and spaces. And so what I do is I just copy a bunch of, I copy four spaces. And everywhere there's a tab, I'm just pasting it in. Let's try that again. Yes. Okay, so you see how now it's stuck, it stopped there. And let me go all the way to the side and then stop there. That's, that was the result of that change. I got to say, again, I did not know about the key release, which is really good. And so when you release a key, that's cool. It's something I learned today. So it's saying this left T and right T is now false. So when you release the key, it will stop moving. So that's really cool. So thank you to the original poster. I appreciate that. That's something new for me today. I knew they had a JavaScript. I never really did it here in Python, which is cool. So I think that basically fixes what the user wanted. And again, this is something, you know, so it is working. Now a couple of things I could do is I could move these functions into the class. So let's go ahead and do that, just to keep it all, you know, object oriented. So we've got def left, like def leopard. So what I'll do is I'll go up to P one. And so I say def left self. And what was that? What was the code on that one? self dot left T equals true. So self, self dot left T equals true. Sorry, I haven't done a lot of Java lately. So yeah, why is that not defaulting to spaces? That's really annoying. Copy. So then that tells me that I have def left, def right, self, right, self, self, right T equals true. Let's see again, find that setting somewhere and fix that. And then we also had def what was it? Left, why and right, why? Weird names. Left, why self, there's spaces there. self dot left, self dot left T equals false. And again, in this case, what I did was I did I'm doing this all at the same time, because it's messy not to in this particular case. So let's have command V command V self dot right T equals. It's better work because I don't have to undo it. And of course, you're going to spell self correctly. So again, so what I did was I just took it out of that, out of the main set of the code here. And what I did was I'm putting it into the class just to keep it a little more consistent. And so then down here, what I would do is P1 dot left, P1 dot right, P1 dot left, why? And P1 dot right, why? And again, just as a side, you cannot put you know some you can't put arguments in this for some reason. To do that, you have to use a lambda. It's something like lambda x colon. I think it's that's the structure. And then you can actually, you know, call a function properly. But if you don't use a lambda, you might have to look that one up. I'm not sure if that's quite the right format, but it's close. You can do it this way. I think let's test it, keep our fingers crossed. Okay, yeah, so everything's working. So that way, you know, again, you know, the whole point of using objects and classes and things is that you want to keep your code. You want to keep your code in case it's called encapsulation. You want your whole all your code related to that object to be in that object's class as much as possible. I mean, you can't always can't do it 100% sometimes. That's a design decision. But like, yeah, you really want to in so far as possible. So everything about the that the player one, the movement, and the left and right thing and starting and design the shapes, all that sort of stuff, you want that to go into the class. So for the apples, you know, that knows all the movement is in the class. And then you could actually make a like this person already has a move method for the apples. Well, why don't we have a move method for the the player? Let's go ahead and let's go and do that. This is an interesting exercise. This program is actually really cool. And so thanks to whoever I don't want to use the person's name. In case they're they don't want to do that. But let me get rid of this now because I don't think we need those. So I'm going to go ahead and I got rid of those. I'm going to test it. Make sure there's no errors. Okay, make sure the catching still works. Yeah, I thought that would be the case. Yeah, this is a term to cool game. Yeah, I can really see you doing a lot with this. So I really like that design of that bucket you drew. I mean, you call it ahead. But so let's let's go ahead and throw in a move class. And so we keep everything inside that class. So def, def move, self, and then what was the code for that? Okay, so if okay, let's just go ahead and copy that and see what happens. I'm going to copy code and then just kind of change around a little bit. Okay, so I need to indent it one extra level. So again, because some of my editor is using tabs instead of spaces. So instead of P1, it's going to be self because we're inside the class. And then where are that other cover? Oh, I'm going to need this as well self dot P1 dot x core. So I copy that. I miss that part. You can hear my phone beeping back in the background. Now this x can be a local x. It's fine. Yeah, I guess we do it that way. Keep the code the same. It's not pretty, but it'll work. And let's go ahead and well, let's just go ahead and copy this out. Well, that's going to copy it. Copy and put that up here. Okay, and I think we're making progress here. I think this might do it. Yeah, actually, I ended up I really like this program. So thanks to again to the original programmer, self dot right. And again, you want to use self because we're inside the class now. Self. So I'm going to change all those cases. And this is why I should have followed my own advice there. Make sure left was working. And then I would I would I could just copy and paste, but I didn't do that. So silly me self. So have me get a little bit rushed. Okay, so now I can get rid of all this stuff down here. And then I can just put this is what's great about classes. Like now you just put P1 dot move. Okay, so this loop here is pretty clean, then all the actual work is done inside the class itself. Okay, so yeah, let's try a function of five. Tab spaces line 81. Okay, get some tabs there. Great. Okay. Okay, still moving borders. So again, I'm checking everything, moving all the way to the left, borders are still working. And there we go. I will put a link to this code in the description. And yeah, so again, normally I don't do this level of debugging for everybody that sends me stuff. If you have a specific question about one of my tutorials and something's going wrong, I'll help you out. I usually don't have time to do this much work. But this is kind of an interesting problem. So again, thanks to the original poster. And yeah, again, I learned a few things from this today. Just as a quick review, when you're writing a program, it's a good idea to be really consistent with your spacing and your, your variable names. And so, okay, that's fine. And, you know, just, you know, you want to be as clean as possible. So people can read it. You really want to choose really good names. Left T in this case. Yeah, what I would have used, I would have used DX, which is Delta X. And that would be like changing the X speed. It's probably how I would have done it. But yeah, again, it works. You know, that's always good. If at all possible, you want to put your code into the class itself. So each object is self contained. So if you ended up having a second player or a third player, you know, the code would work no matter what. And it's like this one was really good example. Apple, it's a sprite, etc, etc. It moves. Yeah, really well done there. And otherwise, yeah, it's pretty easy to read. And again, I like this on key press versus on key release. Yeah, this is, this is, this is really well done. So nice, nice job on that. And you could have actually made one, actually, now I think about this, you could have just made one method, like P1.stop, P1.stop, because all you got to do, because these do the same thing, basically, round out, you have to do, then you have to change it to DX instead of, yeah, this case, I see what you did there. All right. Yeah, there's a couple of different things you could do with that. But yeah, this is really good. And I like, you know, I like here, this is pretty straightforward. Again, because all of the logic is actually in the class itself. The other thing just, you know, I know when you're coding your own stuff, everything seems really logical to you and all that sort of thing. But you definitely want to comment your code a little bit better. So you know, what each section does, even if it seems obvious now, when you come back, if you're asking for help, of course, that person doesn't know, or if you're coming back to it in a week or two. Oh, I don't know, what was that, you know? So also like this little thing here where you can actually kind of draw custom shapes, that's a really cool feature. I don't really use it much. I have used it, but I did a really nice, you did a really nice job with this bucket. I really liked what the original poster did with this. So yeah, like I said, I think that covers everything. I think it's working the way it was intended to. And yeah, nice job to the original poster. This is really cool. I'm really looking forward to seeing, I hope, you know, once you fix this, that you share, you know, your finished product with this, because it's going to be a really fun game. Again, I'll put some links in the description so you can, you know, download this and play around with this and yeah, go from there. Okay. So everybody, thanks for tuning in. You know, it's coronavirus season, so, you know, stay home as much as possible. Please stay safe and I hope to see you guys in the next tutorial. Take care.