Re: [pygame] [Pygame] Joystick Inputs
Inverse Tangent might be slightly easier since you don't need the hypotenuse in the calculation. I've not used it before so if anyone has a slicker way of doing it, please chime in. #x_axis is the position of the horizontal joystick #y_axis is the position of the vertical joystick angle_radians = math.atan2(y_axis,x_axis) angle_degrees = math.degrees(math.atan2(y_axis,x_axis)) Either way, the output will be from -180 degrees to +180 degrees (or the radian equivalents) rather than 0 to 360, so you'll potentially have to watch out for that in your logic. See the documentation at http://docs.python.org/library/math.html for why atan2(y,x) is probably more useful than just atan(x). -Lee- On Tue, Dec 6, 2011 at 10:44 PM, Andrew Godfroy killer...@hotmail.comwrote: Hey Lee, That was actually alot more helpful than what I have been able to find over my past days of searching! Thank you very much. I may actually be able to move forward with my ambitious school project now [image: Smile] Now all I have to figure out is how to find what angle that the Thumbstick is pointing so that I can rotate my player sprite according to which way that the player is moving. I talked to my math teacher about it, and she agreed that I should try using the Inverse of Sin to find the angle. Hopefully that works, because if it doesn’t; I'll be back at square one again. ... But if anyone has had any experience with getting the angle for a rotation based off of a Joystick Thumbstick, or Mouse Position, it would be awesome if you could share how you found it out so I could use it as a reference. *From:* Lee Buckingham *Sent:* Tuesday, December 06, 2011 12:53 AM *To:* pygame-users@seul.org *Subject:* Re: [pygame] [Pygame] Joystick Inputs Hi Andrew, For buttons I use this: if event.type == pygame.JOYBUTTONDOWN: if event.button == whatever...: etc if event.type == pygame.JOYBUTTONUP: and so on... For analog control and d-pads you have to check for axis position each time through the game loop. I do it all at once before the player objects update themselves Like this: horizontal_axis = self.joysticks[player_number].get_axis(0) vertical_axis = self.joysticks[player_number].get_axis(1) Then change the x and y speed for the player with player_number to whatever the axis positions are (times a constant, if necessary). Of course, the player_number has to correspond to the joystick collection indices pretty well for this to work. You can eliminate that part of it by replacing player_number with 0 and just make sure to check that the joystick count is 0 before you call .get_axis Hope this helps a little! -Lee- On Thu, Dec 1, 2011 at 5:51 PM, Andrew Godfroy killer...@hotmail.comwrote: Alright, I just checked over my question and I noticed I wasn’t exactly clear what I was looking for... What I am asking is how do I work the event handler for checking joystick commands such as if the Left Thumbstick-[0] or [1]- moves, or if the A button-[0]- is pressed Does anyone know how that works?
Re: [pygame] [Pygame] Joystick Inputs
That actually works really well for finding the angle. I put it into a test application that didn’t use classes (just straight load the image, then rotate and blit) and I found that if I put in “-angle_degrees” in as the angle, it acts as it would if it was 0-360 degrees. ..Though I found I’m running into a little problem when I take the code and import it into my game. Whenever I call the function, it shows the character on the screen for half a second until it gets thrown wildly (towards the lower right) outside of the window only for it to give me the “error: Out of memory” error after its x,y pos go somewhere into the 9000’s. I’m thinking it may have something to do with it not getting the topleft coordinates again, but I’m not completely sure. ( Current Class) *Portions of it class Player(pygame.sprite.Sprite): # Set Speed of Player joystick_count = 0 # -- Functions -- # def __init__(self,x,y, filename, player): PlayerX, PlayerY, Filename, Player Number(0-4) pygame.sprite.Sprite.__init__(self) # Import the Player Image self.image = pygame.image.load(filename).convert() self.image.set_colorkey(BLACK) self.image = pygame.transform.rotate (self.image, 90) # Make our top-left corner the passed-in location. self.rect = self.image.get_rect() self.rect.topleft = [x,y] # Grab the variable for Player self.playerNum = player # Count the joysticks the computer has self.joystick_count=pygame.joystick.get_count() if self.joystick_count == 0: # No joysticks! print (Error, I didn't find any joysticks.) elif self.playerNum == 1: # Use joystick #0 and initialize it self.my_joystick = pygame.joystick.Joystick(0) self.my_joystick.init() def updateangle (self): if self.joystick_count != 0: if self.playerNum == 1: x_axis= self.my_joystick.get_axis(0) #x_axis is the position of the horizontal joystick y_axis= self.my_joystick.get_axis(1) #y_axis is the position of the vertical joystick angle_radians = math.atan2(y_axis,x_axis) angle_degrees = math.degrees(math.atan2(y_axis,x_axis)) self.image = pygame.transform.rotate (self.image, -angle_degrees) From: Lee Buckingham Sent: Wednesday, December 07, 2011 12:04 PM To: pygame-users@seul.org Subject: Re: [pygame] [Pygame] Joystick Inputs Inverse Tangent might be slightly easier since you don't need the hypotenuse in the calculation. I've not used it before so if anyone has a slicker way of doing it, please chime in. #x_axis is the position of the horizontal joystick #y_axis is the position of the vertical joystick angle_radians = math.atan2(y_axis,x_axis) angle_degrees = math.degrees(math.atan2(y_axis,x_axis)) Either way, the output will be from -180 degrees to +180 degrees (or the radian equivalents) rather than 0 to 360, so you'll potentially have to watch out for that in your logic. See the documentation at http://docs.python.org/library/math.html for why atan2(y,x) is probably more useful than just atan(x). -Lee- On Tue, Dec 6, 2011 at 10:44 PM, Andrew Godfroy killer...@hotmail.com wrote: Hey Lee, That was actually alot more helpful than what I have been able to find over my past days of searching! Thank you very much. I may actually be able to move forward with my ambitious school project now Now all I have to figure out is how to find what angle that the Thumbstick is pointing so that I can rotate my player sprite according to which way that the player is moving. I talked to my math teacher about it, and she agreed that I should try using the Inverse of Sin to find the angle. Hopefully that works, because if it doesn’t; I'll be back at square one again. ... But if anyone has had any experience with getting the angle for a rotation based off of a Joystick Thumbstick, or Mouse Position, it would be awesome if you could share how you found it out so I could use it as a reference. From: Lee Buckingham Sent: Tuesday, December 06, 2011 12:53 AM To: pygame-users@seul.org Subject: Re: [pygame] [Pygame] Joystick Inputs Hi Andrew, For buttons I use this: if event.type == pygame.JOYBUTTONDOWN: if event.button == whatever...: etc if event.type == pygame.JOYBUTTONUP: and so on... For analog control and d-pads you have to check for axis position each time through the game loop. I do it all at once before the player objects update themselves Like this: horizontal_axis = self.joysticks[player_number].get_axis(0) vertical_axis = self.joysticks[player_number].get_axis(1) Then change the x and y speed for the player with player_number to whatever the axis positions are (times a constant, if necessary). Of course, the player_number has to correspond
Re: [pygame] [Pygame] Joystick Inputs
On Wed, Dec 7, 2011 at 5:49 PM, Andrew Godfroy killer...@hotmail.comwrote: self.image = pygame.transform.rotate (self.image, -angle_degrees) Your problem is here. 1: You'll get some sort of markov-chain-esque decay of your image's quality (because you're constantly rotating the image that you already rotated, which was itself a rotation of the image you previously rotated of the rotated . . .). 2: The rotate function rotates the given surface, padding with empty space. So, if you rotate a 512x512 image 30 degrees, then basic geometry tells you the resulting image will be close to 700 pixels on a side (the rotated image will be in the middle). This explains why the character appears to shoot off the screen; you're constantly rotating him, and the surface required to contain that surface keeps getting bigger, because you're setting it to itself. The player appears to move offscreen, because he's in the center of a surface that's effectively rapidly increasing in size. Because of that, you'll natually get that running-out-of-memory problem, too. Ian
Re: [pygame] [Pygame] Joystick Inputs
Alright, so If I’m getting you right, I should be using Rotozoom instead of just rotate, and build in a check to see if the previous angle is the same as the last one? Or how would you propose I would be able to fix this? From: Ian Mallett Sent: Wednesday, December 07, 2011 9:36 PM To: pygame-users@seul.org Subject: Re: [pygame] [Pygame] Joystick Inputs On Wed, Dec 7, 2011 at 5:49 PM, Andrew Godfroy killer...@hotmail.com wrote: self.image = pygame.transform.rotate (self.image, -angle_degrees) Your problem is here. 1: You'll get some sort of markov-chain-esque decay of your image's quality (because you're constantly rotating the image that you already rotated, which was itself a rotation of the image you previously rotated of the rotated . . .). 2: The rotate function rotates the given surface, padding with empty space. So, if you rotate a 512x512 image 30 degrees, then basic geometry tells you the resulting image will be close to 700 pixels on a side (the rotated image will be in the middle). This explains why the character appears to shoot off the screen; you're constantly rotating him, and the surface required to contain that surface keeps getting bigger, because you're setting it to itself. The player appears to move offscreen, because he's in the center of a surface that's effectively rapidly increasing in size. Because of that, you'll natually get that running-out-of-memory problem, too. Ian
Re: [pygame] [Pygame] Joystick Inputs
On Wed, Dec 7, 2011 at 7:51 PM, Andrew Godfroy killer...@hotmail.comwrote: Alright, so If I’m getting you right, I should be using Rotozoom instead of just rotate, and build in a check to see if the previous angle is the same as the last one? No. Think about what's happening. Try unrolling a couple calls: self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) . . . is equivalent to: self.image = pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(self.image, #something), #something), #something), #something) Now do you see the problem? Each image will be larger than the last. Plus, you're doing a transformation repeatedly, which hurts image quality. The attached image demonstrates what's happening. You're starting with an image, then rotating, and then rotating THAT, and so on. The image gets bigger and bigger. I've drawn the padding as white and black, but they probably wouldn't necessarily be those colors. Ian attachment: rotation.png
Re: [pygame] [Pygame] Joystick Inputs
Alright, Thank you for explaining it to me :) Now that I know whats happening I think I found a Solution. inside if my __init__ I added an extra variable “self.oldimage = self.image” Then inside of the rotateimage call, I have it set to: “self.image = pygame.transform.rotate (self.oldimage, -angle_degrees)” This way, it will call up the oldimage, and save to the new surface. Thank you for your help Ian From: Ian Mallett Sent: Wednesday, December 07, 2011 10:05 PM To: pygame-users@seul.org Subject: Re: [pygame] [Pygame] Joystick Inputs On Wed, Dec 7, 2011 at 7:51 PM, Andrew Godfroy killer...@hotmail.com wrote: Alright, so If I’m getting you right, I should be using Rotozoom instead of just rotate, and build in a check to see if the previous angle is the same as the last one? No. Think about what's happening. Try unrolling a couple calls: self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) . . . is equivalent to: self.image = pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(self.image, #something), #something), #something), #something) Now do you see the problem? Each image will be larger than the last. Plus, you're doing a transformation repeatedly, which hurts image quality. The attached image demonstrates what's happening. You're starting with an image, then rotating, and then rotating THAT, and so on. The image gets bigger and bigger. I've drawn the padding as white and black, but they probably wouldn't necessarily be those colors. Ian
Re: [pygame] [Pygame] Joystick Inputs
Nice catch, Ian. I would never have thought of that. On Wed, Dec 7, 2011 at 7:25 PM, Andrew Godfroy killer...@hotmail.comwrote: Alright, Thank you for explaining it to me :) Now that I know whats happening I think I found a Solution. inside if my __init__ I added an extra variable “self.oldimage = self.image” Then inside of the rotateimage call, I have it set to: “self.image = pygame.transform.rotate (self.oldimage, -angle_degrees)” This way, it will call up the oldimage, and save to the new surface. Thank you for your help Ian *From:* Ian Mallett geometr...@gmail.com *Sent:* Wednesday, December 07, 2011 10:05 PM *To:* pygame-users@seul.org *Subject:* Re: [pygame] [Pygame] Joystick Inputs On Wed, Dec 7, 2011 at 7:51 PM, Andrew Godfroy killer...@hotmail.comwrote: Alright, so If I’m getting you right, I should be using Rotozoom instead of just rotate, and build in a check to see if the previous angle is the same as the last one? No. Think about what's happening. Try unrolling a couple calls: self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) self.image = pygame.transform.rotate(self.image, #something) . . . is equivalent to: self.image = pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(pygame.transform.rotate(self.image, #something), #something), #something), #something) Now do you see the problem? Each image will be larger than the last. Plus, you're doing a transformation repeatedly, which hurts image quality. The attached image demonstrates what's happening. You're starting with an image, then rotating, and then rotating THAT, and so on. The image gets bigger and bigger. I've drawn the padding as white and black, but they probably wouldn't necessarily be those colors. Ian
Re: [pygame] [Pygame] Joystick Inputs
On Wed, Dec 7, 2011 at 8:25 PM, Andrew Godfroy killer...@hotmail.comwrote: Alright, Thank you for explaining it to me :) Now that I know whats happening I think I found a Solution. inside if my __init__ I added an extra variable “self.oldimage = self.image” Then inside of the rotateimage call, I have it set to: “self.image = pygame.transform.rotate (self.oldimage, -angle_degrees)” This way, it will call up the oldimage, and save to the new surface. Yes. This is a valid solution. Except in the trivial case, the rotated image will still be a different size, of course. Remember to offset the image correctly (I recommend calling .get_width() and .get_height()) and then subtracting half that from your player's position to get draw coordinates.
Re: [pygame] [Pygame] Joystick Inputs
On Thu, Dec 8, 2011 at 12:36 AM, Ian Mallett geometr...@gmail.com wrote: Except in the trivial case, the rotated image will still be a different size, of course. Remember to offset the image correctly (I recommend calling .get_width() and .get_height()) and then subtracting half that from your player's position to get draw coordinates. Right, you want the image to be centered on the player's position. I think the clearest way to do it is using pygame.Rect's handy positioning: rect = self.image.get_rect(center = (self.x, self.y)) screen.blit(self.image, rect) -Christopher
Re: [pygame] [Pygame] Joystick Inputs
Hey Lee, That was actually alot more helpful than what I have been able to find over my past days of searching! Thank you very much. I may actually be able to move forward with my ambitious school project now Now all I have to figure out is how to find what angle that the Thumbstick is pointing so that I can rotate my player sprite according to which way that the player is moving. I talked to my math teacher about it, and she agreed that I should try using the Inverse of Sin to find the angle. Hopefully that works, because if it doesn’t; I'll be back at square one again. ... But if anyone has had any experience with getting the angle for a rotation based off of a Joystick Thumbstick, or Mouse Position, it would be awesome if you could share how you found it out so I could use it as a reference. From: Lee Buckingham Sent: Tuesday, December 06, 2011 12:53 AM To: pygame-users@seul.org Subject: Re: [pygame] [Pygame] Joystick Inputs Hi Andrew, For buttons I use this: if event.type == pygame.JOYBUTTONDOWN: if event.button == whatever...: etc if event.type == pygame.JOYBUTTONUP: and so on... For analog control and d-pads you have to check for axis position each time through the game loop. I do it all at once before the player objects update themselves Like this: horizontal_axis = self.joysticks[player_number].get_axis(0) vertical_axis = self.joysticks[player_number].get_axis(1) Then change the x and y speed for the player with player_number to whatever the axis positions are (times a constant, if necessary). Of course, the player_number has to correspond to the joystick collection indices pretty well for this to work. You can eliminate that part of it by replacing player_number with 0 and just make sure to check that the joystick count is 0 before you call .get_axis Hope this helps a little! -Lee- On Thu, Dec 1, 2011 at 5:51 PM, Andrew Godfroy killer...@hotmail.com wrote: Alright, I just checked over my question and I noticed I wasn’t exactly clear what I was looking for... What I am asking is how do I work the event handler for checking joystick commands such as if the Left Thumbstick-[0] or [1]- moves, or if the A button-[0]- is pressed Does anyone know how that works? wlEmoticon-smile[1].png
[pygame] [Pygame] Joystick Inputs
Hey, I have been trying to experiment with Joysticks, hoping that I will be able to use on in my project. I'm having a little trouble with actually figuring out how to get stated as the only code I have found online has been to just get the values for what all the buttons, axis's, and hats are. I have been kicking myself for the past few hours just on the internet trying to figure out how to get started with it all. Considering that I haven't been able to find any information on how to actually work it; I have decided to take the last resort and ask everyone here.\ What I want to be able to do is have my players be sprites, and then have the ability to control them with the joystick. (I'll post the class at the bottom) If there is anyone that can help me it will be GREATLY appreciated as I am completely lost on how to do this. Thanks ~killerrin Pygame Version: 1.9.1 Python Version: 3.1.1 - Hide quoted text - Heres is my Joysticks Information, Class, and Player Image Image: http://dl.dropbox.com/u/28710254/Photos/Programming/Player.png ID: js.get_id() 0 Name: js.get_name() Controller (Xbox 360 Wireless Receiver for Windows) Buttons: js.get_button(button) 0 == A 1 == B 2 == X 3 == Y 4 == LB 5 == RB 6 == Back 7 == Start 8 == LS 9 == RS Axis: js.get_axis(axis_num) 0: LS X Axis Left: -1.0 Right: 1.0 1: LS Y Axis Up: -1.0Down: 1.0 2: LT, RT LT: 1.0RT: -1.0 3: RS Y Axis Up: -1.0Down: 1.0 4: RS X Axis Left: -1.0 Right: 1.0 Hats: js.get_hat(hat_number) 0: D-Pad Left-(-1,0) Upleft-(-1,1) Right-(1,0) Upright-(1,1) Up-(0,1)Downleft-(-1,-1) Down-(0,-1) Downright-(1,-1) class Player(pygame.sprite.Sprite): # Set Speed of Player speed_x=0 speed_y=0 # -- Functions -- # def __init__(self,x,y, filename): pygame.sprite.Sprite.__init__(self) # Import the Player Image self.image = pygame.image.load(filename).convert() self.image.set_colorkey(BLACK) # Make our top-left corner the passed-in location. self.rect = self.image.get_rect() self.rect.topleft = [x,y] def movement(self,x,y): # Change the Speed of the character then move it self.speed_x+=x self.speed_y+=y def update(self,walls): # Find, and Update the Player location # Get the old position, in case we need to go back to it old_x=self.rect.left new_x=old_x+self.speed_x self.rect.left = new_x # Check to see if the player is in a wall collide = pygame.sprite.spritecollide(self, walls, False) if collide: self.rect.left=old_x # If it hits a wall, we go back to before/wont update it. old_y=self.rect.top new_y=old_y+self.speed_y self.rect.top = new_y # Check to see if the player is in a wall collide = pygame.sprite.spritecollide(self, walls, False) if collide: # If it hits a wall, we go back to before/wont update it. self.rect.top=old_y player = Player( 0,0, Player.png ) player_sprite = pygame.sprite.RenderPlain((player)) player_clicker.add(player) Once again, If anyone could help me in just trying to figure out what has to be done, or can atleast point me in the right direction, I will be forever in debt.
Re: [pygame] [Pygame] Joystick Inputs
Alright, I just checked over my question and I noticed I wasn’t exactly clear what I was looking for... What I am asking is how do I work the event handler for checking joystick commands such as if the Left Thumbstick-[0] or [1]- moves, or if the A button-[0]- is pressed Does anyone know how that works?