Controller Input - Pygame Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right so in this video i'll be going over how you can implement controller input with pi game before we get started i need to go over the code that i already have here it's just a basic game loop with a window initialize and a event system for closing the window and then i also did one extra thing here where i have a square with colors and motion squares rendered here with the color based on the index of the color selected so this is zero so it'll use this color if it's one it'll use this color and then right here the motion is applied to the square's position so if this were set to one it would move to the right on the x-axis 10 pixels every frame so this is just here so i can demonstrate the controller input when i actually get the data so let's get started to use controllers in pygame first you're going to have to initialize the joystick module so pygame.joystick.init and then you have to initialize all the joysticks themselves what this does here is it goes through the account of the joysticks that pi game sees and then it initializes them with that index the controller ids are based on the indexes i'm pretty sure it's just the order that they're loaded in your operating system so you could pass it zero to initialize your first controller or one to your second in this case i'm just iterating through all of them and initializing them and just creating a list out of them with some list comprehension so this joysticks variable just contains a list of all of our joystick objects you can interface with the controllers through those objects but the event system is probably more convenient for that the pagan event system has event types for the joysticks which i'll be implementing here so there's quite a few but i'm going to implement just some of them right now and show you what the data looks like so if event dot type is joy button down print event and then if event dot type is joy button up print event if event.type is joy uh axis motion print event if event.type is joy hat motion print event all right so this is just processing a bunch of the event types for controller input and printing out their data essentially the event is actually an object but when you print it out it's formatted in a way we can see what data there is associated with it so let's run this and take a look so first of all you're going to be going to look at my console output down here is just what's coming from the present statements if i press down on the a button you can see i get some data here it's an event object with some information and the important thing to notice here is if i press a and b the button number changes here if i press x and y you'll see the buttons change again if i press the top button bumper buttons it'll change again i can also press the start and back there's also the triggers which come up as these so one important thing to note here is that all the things up here are actually buttons and then there's the of the other type of input called an axis which is used for both the joysticks and the triggers it's meant to show a gradient from like zero to one or negative one to one triggers use it because they can actually detect how far down you press them and then joysticks also use it which i'm i'm turning right now to determine the orientation of the joystick the joysticks move on two axes though it moves horizontally and vertically so each joystick is made up of two axes and data as you can see there's different axis ids depending on which one i'm messing around with so my left joystick is zero and one it goes it sets the zeroth axis to one if i go all the way to the right and it sets it to negative one if i go all the way to the left hold on there we go and then my axis number one goes all the way to one when i pull it down and it gets negative on when i pull the the joystick up one important thing to note here is that with all these different ids like the button id and the axis id these are not consistent among different controllers my controller is very similar to the xbox controllers in layout and like the way it's processed this data is passed as just a bunch of values at different indexes based on how many buttons or axis you have and the main way people actually deal with different types of controllers for their games is just with a database of the layouts of a ton of different controllers normally this is handled on like the engine or framework level although pygame does not provide a database for that and actually some engines are criticized or praised based on the quality of their database for their controllers i think i've actually heard in the past i don't know if this is currently the case that unity is pretty bad about it sometimes although it might be just relative to other stuff who knows i've just seen a lot of people complaining about it anyways those databases i haven't been able to find one you can actually look up a few different layouts online if you do some research you can find just a couple popular ones like the xbox 360 the dual shocks um and then some of the usb controllers and obviously i have my own controller so i can uh test the one i have and i'm pretty sure you could probably find like the switch pro controller as well i've also read that the layout can potentially depend on drivers which adds more variance that's a bit annoying to deal with so my recommendation is that if you're trying to implement this in your game you should probably build up a database of the different layouts for just a couple of the popular controllers and after that assume a default which i would recommend using the xbox 360 layout which is essentially what i have since a lot of the usb controllers that the cheap ones will be fairly close to that normally you can count on at least the left joystick and the abx y to be consistent the left joystick is normally the zeroth and the first axis and then the abx y or whatever they're called those but four buttons on the right are normally buttons zero through three but anything past that you're just gonna have to take a guess and my recommendation would be that you have a menu so that your users can bind whatever inputs they want you just store which index they used for some kind of control say you asked them to press the button they went for jump and you see a button let's say i press this one you see it's button one you save that number and you look for that button in the future to determine if the player jumps and that's how i've implemented in my past games it's kind of a mess but that's about them as best as you can do anyways so i'm going to implement some stuff here to actually have something to mess around with so you can see it oh also one more thing there's also the hat which you can see here sometimes the hat comes up as buttons and sometimes it'll come up as a hat the hat is the um well sometimes four directional sometimes eight directional and sometimes five directional apparently as i read meaning that it has four directions plus a center button but anyways normally it's a four directional pad and i guess in my case you could consider eight directional it's usually on the left side of your controller and that comes up a bit differently and that comes up under the joy hat motion event but yeah i wouldn't count on it actually coming up as a hat because sometimes it could come up as button numbers i think and just come up under four buttons instead of one hat and you can see the the values are tuples there with the two values so in my case actually do have well you could consider it nine directions because it knows the center it always falls back to zero zero when you're done anyways so let's implement some stuff here so if event dub button is zero and remember zero is my a button we saw it in the data that was printed out my square color equals my square color plus one percent the length of colors this just loops this uh my square color value which is an integer that represents an index of the colors that's used to select the colors under here it'll just loop it through however big this list is so that's just so i can switch the colors when i press a button and now let's implement some movement so that goes under joy access motion so if event dot axis is less than two so this is just the first two axes remember zero and one or the axes used for my left joystick the zeroth axis is horizontal and the first axis is vertical so fortunately that lines up the same way this list for my motion is used so i can assign it very directly and just go my i you can just go motion event dot axis so that's zero or one because we limited it with it with this if statement and then equals event dot value which is the negative one to the one unfortunately the directions of these axis are the same as they are in the game so that just gets applied here to do movement so this is just essentially setting the velocity based on the orientation of the joystick so here's what this looks like you've got moving around and you can change the colors with the a button and if you notice well you can't tell because you can't see my hands but i'm my hands are off the controller right now and it's drifting around that's because the values do not go exactly to zero or exactly to one or exactly the negative one a lot of times it's imprecise and it'll just kind of sit around there especially with zero but anyways you can move fast you can move slow if i tilt the joystick just slightly and that's that so this little drifting thing is easily fixed with the concept of dead zones so the idea behind dead zones is that for certain ranges you essentially just ignore the data so one option in my case would be to scale say the range of 0.3 to 0.7 all the way up to 0 to 1 so that anything below 0.3 is considered 0 and anything above 0.7 is considered 1. you could do that with some multiplication alternatively you can do dead zones a little bit differently with if statements and if you want your movement speed to be constant you can just go um well let's say we can do this like if event value is more than 0.3 then you know that you've tilted at least a decent amount to the right or down because this is two axes anyways so we're not doing that though in my case i'm just going to deal with the case of the zero it's not going all the way to zero so i'm going to do here is go if absolute of motion zero and the reason i'm using absolute is because it goes from negative one to one it can be close to zero on the high end or in on the negative side so i'm going to do if the absolute is less than 0.1 motion 0 equals 0. so that just forces it to go to 0 if it's close enough and we're going to do the same thing for the y-axis by switching the zeros to ones so now if i take my finger off the joystick it stays still because it rounds it down to zero if if the value is less than 0.1 you can mess with those dead zones as you desire um to do whatever you want for your game anyways there's one last thing i'd like to mention well two more things actually so first of all if you're interested in the different types of events or you're interested with interacting with the joystick objects directly you can check out the documentation and also um you can do joysticks.get to print out the name of well i'm going to print it out to get the string of the name of the joystick which you can use to build a database of the different layouts that's how you can tell what kind of joystick it is um so i'm going to do four joystick in joysticks and when i run it you can see that my controller's name is x input controller number one i've actually got a switch on the back my controller that allows me to switch between x input or i think direct input um and i can switch it and then get the actual name of the controller which is uh logitech dual action one annoying thing about this though is that um the controller layout comes up differently depending on which mode i use so in this case the x button on the left is now button zero so i normally use the directx layout because of that anyways the one last major thing i want to show you was hot plugging where you can unplug and plug the controller back in during the game's run time if you notice i initialized the joysticks up here so someone plugs in a joystick after that then it won't be handled so this is something you can actually only do in pi game two and for those of you that don't know pygame 2 is just kind of um a newer version of pie game has some new functionality it's built on sdl 2 instead of sdl but for the time being if you want pi game 2 you have to use certain arguments when you install pi games you can look that up by default pi game installs are not pi game 2 they're probably in 1.9 point something in the future the default might be too who knows most of you guys watching at least when this video comes out will probably not have pi game 2 so this functionality may not work for you um it's also worth noting that upgrading to pi game 2 doesn't really cost you anything it actually makes the games run significantly faster and also everything's backwards compatible so everything should work almost the exact same pie game 1.9 game should work for perfectly fine in packing two if anything better because of the performance boosts anyway so if event dot type is joy device added this is the event that fires when pi game or pi game 2 sees that a joystick has been added so when that happens i'm just going to reinitialize all my joysticks and i'll add an event for removing them as well then that type is joy device removed removed and i'm going to be doing the exact same thing again and the reason for this is that you want to update your list with uh the joysticks whenever you unplug a controller so you don't have like a dead controller listed in there i'm going to add this part here as well so we can see whatever joystick gets added so with that i should be able to turn my controller on and off like i'm plugging and plug it back in while the game is running and it should still work so i'm going to leave the console here so you can see that so controller works fine turn it off oh the remove event didn't fire oh no did fire there's just no message for it and you can see that the x input controller one came back and i can move around again now if i pull the switch on the back i'm actually not sure if this is gonna work i haven't tried it oh yep it switched to the dual action instead of the x input so it acts like it's a different controller even though it's just one controller switching its mode but that works i can switch between the different input modes right now i'm pressing x to switch but if i switch back to the other mode it's um a so i can switch back and forth to action x input dual action x input but yeah i can um unplug it and plug it back in as well and that works so that's pretty much everything for this tutorial i know it was pretty long there's there was a lot to go over here there's a lot of technical details with dealing with controllers and just in general the whole situation for pc games with controllers is kind of a mess with consoles it's less complicated because they have one controller type or at least a couple and you know what those are with pc games you've got to deal with hundreds of different types of controllers and it's all a mess anyways i hope that video was helpful and i'll see you guys later
Info
Channel: DaFluffyPotato
Views: 31,971
Rating: undefined out of 5
Keywords: DaFluffyPotato, python, pygame, pygame controller, controller, gamepad, joystick, controller layout, game controller, gamedev, programming, game development, tutorial, Controller Input - Pygame Tutorial
Id: Hp0M8iExfDc
Channel Id: undefined
Length: 17min 4sec (1024 seconds)
Published: Tue Mar 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.