So the fifth step... So we're going to create some player-specific utility functions and player-specific constants. It's basically a PR that focuses on the player because at this point the rest of our components are looking pretty good. Like that small, sorry, that small improvement of using custom hooks did a lot for us. Like the other components are pretty clean and pretty reusable and we've seen just by creating the player health UI we've been able to reuse them and create something really, really fast and be certain that it's gonna work.
So if we were to use unit test for instance, if we write a single test for that use sprite or use animated sprite, custom hook, we are certain that that functionality is working. We don't have to write tests for it again and again and again for that part of the code, if we were to just have duplicate code across the components.
So let's look at the code here. So we're defining a bunch of player specific constants. I like doing that because I don't wanna pollute the global constants file because that, in its recipe for disaster, if you're gonna define all of the stuff for all of the applications in a single file, that's gonna be a mess. And even your imports are gonna be huge and lag context. If you're gonna see an import from player slash constants, then it's gonna make more sense that it relates to the players width and height instead of some abstract width or height. So as a rule of thumb, always try to add some context to your file paths, directories, your file names, and obviously constants and variables and whatnot.
So these are pretty self-explanatory based on their names, the animation length, player has three frames when he moves, how fast he moves. So if you're testing the game out and you feel like the player is walking too slow, just bump this one thing and it's gonna be way faster and easier to manage as well in the future. And we can do A, B testing. And I don't know if some play testing, somebody says it moves too fast, some say it's too slow, it's really easy to maintain. And I will show you the code that was before that related to the speed and how hard it would have been to change that and tweak that. And we have an object that basically defines our inputs. So it says that the space bar and the entry keys will allow us to interact with objects. Up and well, the rest of the directions are mapped to WASD and the arrow keys. It's a very nice way. Again, look at it as a concept, defining objects like that is very common and a lot of the times saves you a lot of code and if conditionals or switch conditions. For instance, if you replace this with an enum and there will be an example like that in future PRs. You can very easily, so to speak, automate your fetching the data from an object and you can be certain of the type if you're using an enum or something like that.
Moving on. And you can see that we've removed it from the player component, we've removed the constants into a separate file so that we can reuse the same values in the component as well as the utility functions for the player. Okay, so one more thing that I've skipped in the description. Having a understanding of basic concepts, in this case, as vectors from math, and by no means am I a math nerd I'm pretty bad at maths, but this concept allows us to define a direction, basically, saying where the player is gonna be facing. For instance, this is what we're gonna be using the vectors for. So we've created a class that allows us to do that, and we've created a bunch of static methods on it, like zero giving no direction, it's just a static, it's not moving in any way. A up function that says that the player is going up, down and so forth and so not. And this is what we're gonna be using and applying into. So instead of having, where was it? Just say down. We're gonna have vector down that's gonna be way more useful for us in the future. You will see a little bit below how we're gonna use that concept to remove code and streamline the idea of movement. Because it's very, very important to not write code the way you think of it. If you think, okay, the player is moving down, then I have to, let's say, add to the Y position the speed. You're gonna end up with very verbose code that is very hard to manage. Instead, try to apply a concept to it like vectors in our case. And please come up with such ideas for your own project as well.
So, let's actually, I just wanna find that one piece of code with the vector right here. So this is another function. We're gonna go through the functions in just a second. But basically the idea is that we're simplifying all of this stuff here and here into a single function call that says get the direction from the input. So if you press the W key, or the arrow keys, it's gonna tell and set the direction to a specific vector pointing in that direction. And we're just gonna use that as an input for our move function. And from get-go, when you first open this file, you're gonna see, okay, so we're getting the movement direction and we're moving the player in that direction. It's very easy to understand and grasp the concept of it and change it in the future.
So let's go through the utility functions and we have a bunch of them, but they're all very, very simple. It's basically the same code that was before in the player, just moved outside with very few tweaks. What to start with? I guess the top. Well, let me remind myself what this is. Okay. So we're using the sprite position by basically getting the proper animation position. It's game-specific, so I can just go to the next function. So the draw frame is basically drawing the same thing as it's similar to the use sprite hook. Although this is just a function in our case because we don't need hooks because we wanna change it within an interval. Paul, I'm gonna get back to your question. It's a good one. So here's our get input vector that is so helpful to us. We're basically nesting conditionals and honestly looking at it now, we don't need the else here because we're returning. But basically, based on the input constant we've defined before, we check if that object key, if you remember it's an array, includes the key that we've just pressed. Let's say the arrow key, then it's gonna give us the proper vector or direction of movement and we're just returning that. And if there's no input that we're interested in, then we're just returning no direction, no movement whatsoever. And this is the next important one, how to simplify it. Now we've simplified the movement of the player by just not doing anything if there is no movement, no direction, and then just multiplying the direction by the speed basically. So if we're moving to the left, then we say we wanna move to the left that much. And unfortunately, this horrible piece of code is just because of the...