why can't my code detect button down on a joystick - python

I am using the pygame.joystick method to use joysticks in my game, however, my code can only detect the model of the joystick, and cannot detect what buttons are down.
import pygame
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
# This is a simple class that will help us print to the screen
# It has nothing to do with the joysticks, just outputting the
# information.
class TextPrint:
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 20)
def print(self, screen, textString):
textBitmap = self.font.render(textString, True, BLACK)
screen.blit(textBitmap, [self.x, self.y])
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
pygame.init()
# Set the width and height of the screen [width,height]
size = [500, 700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
#Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# Initialize the joysticks
pygame.joystick.init()
# Get ready to print
textPrint = TextPrint()
# -------- Main Program Loop -----------
while done==False:
# EVENT PROCESSING STEP
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
# Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
if event.type == pygame.JOYBUTTONDOWN:
print("Joystick button pressed.")
if event.type == pygame.JOYBUTTONUP:
print("Joystick button released.")
print('EVENT')
# DRAWING STEP
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(WHITE)
textPrint.reset()
# Get count of joysticks
joystick_count = pygame.joystick.get_count()
textPrint.print(screen, "Number of joysticks: {}".format(joystick_count) )
textPrint.indent()
# For each joystick:
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
textPrint.print(screen, "Joystick {}".format(i) )
textPrint.indent()
# Get the name from the OS for the controller/joystick
name = joystick.get_name()
textPrint.print(screen, "Joystick name: {}".format(name) )
# Usually axis run in pairs, up/down for one, and left/right for
# the other.
axes = joystick.get_numaxes()
textPrint.print(screen, "Number of axes: {}".format(axes) )
textPrint.indent()
for i in range( axes ):
axis = joystick.get_axis( i )
textPrint.print(screen, "Axis {} value: {:>6.3f}".format(i, axis) )
textPrint.unindent()
buttons = joystick.get_numbuttons()
textPrint.print(screen, "Number of buttons: {}".format(buttons) )
textPrint.indent()
for i in range( buttons ):
button = joystick.get_button( i )
textPrint.print(screen, "Button {:>2} value: {}".format(i,button) )
textPrint.unindent()
# Hat switch. All or nothing for direction, not like joysticks.
# Value comes back in an array.
hats = joystick.get_numhats()
textPrint.print(screen, "Number of hats: {}".format(hats) )
textPrint.indent()
for i in range( hats ):
hat = joystick.get_hat( i )
textPrint.print(screen, "Hat {} value: {}".format(i, str(hat)) )
textPrint.unindent()
textPrint.unindent()
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 20 frames per second
clock.tick(20)
# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit ()
Here is the code I used to test my joystick: here
Sorry, I had to make it a drive document.

The code is initialising the joysticks every update-loop. It's only necessary to initialise it once. I think it's best to move all your initialisation code into a single function. I suspect the constant re-initialisation of the joystick is interfering its proper functioning.
def initialiseJoysticks():
"""Initialise all joysticks, returning a list of pygame.joystick.Joystick"""
joysticks = [] # for returning
# Initialise the Joystick sub-module
pygame.joystick.init()
# Get count of joysticks
joystick_count = pygame.joystick.get_count()
# For each joystick:
for i in range( joystick_count ):
joystick = pygame.joystick.Joystick( i )
joystick.init()
# NOTE: Some examples discard joysticks where the button-count
# is zero. Maybe this is a common problem.
joysticks.append( joystick )
# TODO: Print all the statistics about the joysticks
if ( len( joysticks ) == 0 ):
print( "No joysticks found" )
else:
for i,joystk in enumerate( joysticks ):
print("Joystick %d is named [%s]" % ( i, joystk.get_name() ) )
# etc.
return joysticks
Then in your main code, call this initialiser once, outside the loop.
done = False
all_joysticks = initialiseJoysticks()
# -------- Main Program Loop -----------
while not done:
# EVENT PROCESSING STEP
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
# Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
elif event.type == pygame.JOYAXISMOTION:
axis = [ 'X', 'Y' ]
print( "joystick: %d, movement: %4.2f in the %s-axis" % ( event.joy, event.value, axis[event.axis] ) )
elif event.type == pygame.JOYBUTTONDOWN:
#print( "Joystick button pressed." )
pass
elif event.type == pygame.JOYBUTTONUP:
print( 'joystick: %d, button: %d' % ( event.joy, event.button ) )
# DRAWING STEP
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill( WHITE )
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 20 frames per second
clock.tick( 20 )
# exit
pygame.quit()

Related

Assigning Variables to newly added Sprites

I'm trying to let the user press and hold the right mouse button to make squares, then move them around with the mouse by left clicking. I was able to make a sprite that could be moved around with left click and to make new sprites when the user right clicks:
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
elif event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
quit()
elif event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1:
if x <= m_x <= x + tilesize_w and y <= m_y <= y + tilesize_h:
m_xrom = m_x - x
m_yrom = m_y - y
down = True
elif event.button == 3:
m_xrom = m_x
m_yrom = m_y
elif event.type == pg.MOUSEBUTTONUP:
if event.button == 1:
down = False
elif event.button == 3:
tiles.add(Player((m_xrom,m_yrom), 876567, abs(m_x - m_xrom), abs(m_y - m_yrom))
m_x,m_y = pg.mouse.get_pos()
if down:
x = m_x - m_xrom
y = m_y - m_yrom
color = 279348
lvl = Level((x,y), color, tilesize_w, tilesize_h)
lvl.run()
However I don't know how to the move the sprites that the user makes. I would like to be able to make several different user-made sprite that can move independently.
This is a somewhat simple process once the code "saves" the newly drawn boxes somehow. I think a good way to do this is to create a PyGame sprite object for each new box, and keep them in a sprite Group.
At the end of a "mouse drag" operation, we have a start-position - the mouse-xy of the MOUSEBUTTONDOWN event, and the end-position is the mouse-xy of the MOUSEBUTTONUP event. With a bit of fiddling to handle negative-ranges, we calculate a PyGame rectangle object (Rect), using it as the basis for a BoxSprite:
class BoxSprite( pygame.sprite.Sprite ):
""" Rectangular, coloured box-sprite """
def __init__( self, drag_rect ):
super().__init__()
self.image = pygame.Surface( ( drag_rect.width, drag_rect.height ) )
self.rect = drag_rect.copy()
self.image.fill( GREEN )
Looking at the BoxSprite, it's really not much more than a coloured Surface, sized and positioned over the original drag_rect.
Once we have a Sprite to hold the box, PyGame has the super-useful Sprite Group class. This can be used to hold all the BoxSprites, and provides easy drawing, membership and collision functions.
So now the code can "remember" every box, how can we determine if the user clicked on one? An easy way to do this is to test if the click mouse-position is inside any of the group members. A simple approach would be to iterate through every sprite in the group, checking each sprite's Rect. Or if we can somehow treat the mouse-click as a sprite-object, we can use the existing Sprite Group's "Sprite Vs Sprite-Group" collision-test function. This operation returns a handy list of collided sprites from the group. Nice.
Once you have this list, how you treat them is up to you. In the example below I implemented a drag-existing sprite, so clicking on an existing Box "grabs" it until the mouse button is released.
import pygame
# window sizing
WIDTH = 500
HEIGHT = 500
MAX_FPS = 60
BLACK = ( 0, 0, 0)
RED = (255, 0, 0)
GREEN = ( 20, 200, 20)
YELLOW= ( 255,255, 0)
pygame.init()
window = pygame.display.set_mode( ( WIDTH, HEIGHT ) )
pygame.display.set_caption( "Box Dragging Demo" )
###
### This is a sprite we use to hold each rectangular box the User creates.
### Once the user completes an on-screen draw operation, the box gets stored in
### an instance of a BoxSprite
###
class BoxSprite( pygame.sprite.Sprite ):
""" Rectangular, coloured box-sprite """
def __init__( self, drag_rect ):
super().__init__()
self.image = pygame.Surface( ( drag_rect.width, drag_rect.height ) )
self.rect = drag_rect.copy()
self.image.fill( GREEN )
def moveBy( self, dx, dy ):
""" Reposition the sprite """
self.rect.x += dx
self.rect.y += dy
def setColour( self, c ):
self.image.fill( c )
###
### Sprite Groups have no function to test collision against a point
### So this object holds a position as a "dummy" 1x1 sprite, which
### can be used efficiently in collision functions.
###
class CollidePoint( pygame.sprite.Sprite ):
""" Simple single-point Sprite for easy collisions """
def __init__( self, point=(-1,-1) ):
super().__init__()
self.image = None # this never gets drawn
self.rect = pygame.Rect( point, (1,1) )
def moveTo( self, point ):
""" Reposition the point """
self.rect.topleft = point
# Sprite Group to hold all the user-created sprites
user_boxes_group = pygame.sprite.Group() # initially empty
rect_start = ( -1, -1 ) # start position of drawn rectangle
drag_start = ( -1, -1 ) # start position of a mouse-drag
mouse_click = CollidePoint() # create a sprite around the mouse-click for easier collisions
clicked_boxes = [] # the list of sprites being clicked and/or dragged
clock = pygame.time.Clock() # used to govern the max MAX_FPS
### MAIN
exiting = False
while not exiting:
# Handle events
mouse_pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
exiting = True
elif ( event.type == pygame.MOUSEBUTTONDOWN ):
# MouseButton-down signals beginning a drag or a draw
# Did the user click on an existing sprite?
mouse_click.moveTo( mouse_pos )
clicked_boxes = pygame.sprite.spritecollide( mouse_click, user_boxes_group, False ) # get the list of boxes clicked (if any)
# was anything clicked?
if ( len( clicked_boxes ) > 0 ):
drag_start = mouse_pos # yes, begin a drag operation
for box in clicked_boxes:
box.setColour( YELLOW )
else:
# Nothing clicked, not already drawing, start new rectangle-draw
rect_start = pygame.mouse.get_pos()
elif ( event.type == pygame.MOUSEBUTTONUP ):
# MouseButton-up signals both drag is complete, and draw is complete
# Was the user dragging any sprites?
if ( len( clicked_boxes ) > 0 ):
# drag is over, drop anything we were dragging
for box in clicked_boxes:
box.setColour( GREEN )
drag_start = ( -1, -1 )
clicked_boxes = []
# Was the user drawing a rectangle?
elif ( rect_start != ( -1, -1 ) ):
# Rects are always defined from a top-left point
# So swap the points if the user dragged up
if ( rect_start > mouse_pos ):
swapper = ( mouse_pos[0], mouse_pos[1] )
mouse_pos = rect_start
rect_start = swapper
# create a new sprite from the drag
new_width = abs( mouse_pos[0] - rect_start[0] )
new_height = abs( mouse_pos[1] - rect_start[1] )
if ( new_width > 0 and new_height > 0 ):
new_sprite = BoxSprite( pygame.Rect( rect_start, ( new_width, new_height ) ) )
user_boxes_group.add( new_sprite )
rect_start = ( -1, -1 ) # done drawing
elif ( event.type == pygame.MOUSEMOTION ):
# The mouse is moving, so move anything we're dragging along with it
# Note that we're moving the boxes bit-by-bit, not a start->final move
if ( len( clicked_boxes ) > 0 ):
x_delta = mouse_pos[0] - drag_start[0]
y_delta = mouse_pos[1] - drag_start[1]
for box in clicked_boxes:
box.moveBy( x_delta, y_delta )
drag_start = mouse_pos
# Handle keys
keys = pygame.key.get_pressed()
if ( keys[pygame.K_ESCAPE] ):
exiting = True
# paint the window
window.fill( BLACK ) # paint background
user_boxes_group.draw( window ) # paint the sprites
# If we're already dragging a box, paint a target-rectangle
if ( rect_start != ( -1, -1 ) ):
# Use a lines instead of a Rect, so we don't have to handle width/height co-ordinate position issues
box = [ rect_start, ( mouse_pos[0], rect_start[1] ), mouse_pos, ( rect_start[0], mouse_pos[1] ) ]
pygame.draw.lines( window, RED, True, box, 1 )
pygame.display.flip()
clock.tick( MAX_FPS )
pygame.quit()

PyGame - RaspberryPi 3b+ with a ps3 controller

I am trying to use pygame with the raspberry pi to use a PlayStation 3 controller as an input for a car.
I have tested the controller with a demo code, and everything works fine. Then when I try to use it in my program, it reads 0.0 as the input, when the joysticks are moved. attached is my current code:
import pygame
class controller:
def __init__(self):
pygame.init()
pygame.joystick.init()
global joystick
joystick = pygame.joystick.Joystick(0)
joystick.init()
def get_value(self, axis):
value = joystick.get_axis(axis)
return value
control = controller()
val = control.get_value(0)
while True:
print(val)
I am aware that this test is only for axis 0, but the output is still 0.0 for all axes.
Below, i have attached the demo code, where all the values are properly read.
import pygame, sys, time #Imports Modules
from pygame.locals import *
pygame.init()#Initializes Pygame
pygame.joystick.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()#Initializes Joystick
# get count of joysticks=1, axes=27, buttons=19 for DualShock 3
joystick_count = pygame.joystick.get_count()
print("joystick_count")
print(joystick_count)
print("--------------")
numaxes = joystick.get_numaxes()
print("numaxes")
print(numaxes)
print("--------------")
numbuttons = joystick.get_numbuttons()
print("numbuttons")
print(numbuttons)
print("--------------")
loopQuit = False
while loopQuit == False:
# test joystick axes and prints values
outstr = ""
for i in range(0,4):
axis = joystick.get_axis(i)
outstr = outstr + str(i) + ":" + str(axis) + "|"
print(outstr)
# test controller buttons
outstr = ""
for i in range(0,numbuttons):
button = joystick.get_button(i)
outstr = outstr + str(i) + ":" + str(button) + "|"
print(outstr)
for event in pygame.event.get():
if event.type == QUIT:
loopQuit = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
loopQuit = True
# Returns Joystick Button Motion
if event.type == pygame.JOYBUTTONDOWN:
print("joy button down")
if event.type == pygame.JOYBUTTONUP:
print("joy button up")
if event.type == pygame.JOYBALLMOTION:
print("joy ball motion")
# axis motion is movement of controller
# dominates events when used
if event.type == pygame.JOYAXISMOTION:
# print("joy axis motion")
time.sleep(0.01)
pygame.quit()
sys.exit()
any feedback will be much appreciated.
The code is losing the reference to the initialised joystick. It needs to maintain an internal link to it. Note the use of self. in the class below. This keeps the reference inside the class, making "self.joystick" a member variable of the class. Python classes need the self. notation (unlike lots of (all?) other object orientated languages). While editing I changed some of the names to match the Python PEP-8 style guide, I hope that's OK ;)
class Controller:
def __init__( self, joy_index=0 ):
pygame.joystick.init() # is it OK to keep calling this?
self.joystick = pygame.joystick.Joystick( joy_index )
self.joystick.init()
def getAxisValue( self, axis ):
value = self.joystick.get_axis( axis )
return value
Maybe you left the extra code out of the question, but a PyGame program without an event loop will eventually lock up.
import pygame
# Window size
WINDOW_WIDTH = 300
WINDOW_HEIGHT = 300
class Controller:
""" Class to interface with a Joystick """
def __init__( self, joy_index=0 ):
pygame.joystick.init()
self.joystick = pygame.joystick.Joystick( joy_index )
self.joystick.init()
def getAxisValue( self, axis ):
value = self.joystick.get_axis( axis )
return value
### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
clock = pygame.time.Clock()
pygame.display.set_caption( "Any Joy?" )
# Talk to the Joystick
control = controller()
# Main loop
done = False
while not done:
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
# Query the Joystick
val = control.getAxisValue( 0 )
print( "Joystick Axis: " + str( val ) )
# Update the window, but not more than 60fps
window.fill( (0,0,0) )
pygame.display.flip()
clock.tick_busy_loop(60)
pygame.quit()

Pygame Xbox One Controller

I am trying to run some code that will allow the user to control with an Xbox Controller. I have it working with the Xbox 360 controller using Pygame. Then when I try to use the Xbox one controller and it is able to read the as "connected" but it doesn't read the actual button presses.
I tried running the joystick analyzer found on the Pygame website and it shows it connected again but no button input is taken.
The code for this can be found at the bottom of this documentation page:
https://www.pygame.org/docs/ref/joystick.html
import pygame
# Define some colors.
BLACK = pygame.Color('black')
WHITE = pygame.Color('white')
# This is a simple class that will help us print to the screen.
# It has nothing to do with the joysticks, just outputting the
# information.
class TextPrint(object):
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 20)
def tprint(self, screen, textString):
textBitmap = self.font.render(textString, True, BLACK)
screen.blit(textBitmap, (self.x, self.y))
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
pygame.init()
# Set the width and height of the screen (width, height).
screen = pygame.display.set_mode((500, 700))
pygame.display.set_caption("My Game")
# Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates.
clock = pygame.time.Clock()
# Initialize the joysticks.
pygame.joystick.init()
# Get ready to print.
textPrint = TextPrint()
# -------- Main Program Loop -----------
while not done:
#
# EVENT PROCESSING STEP
#
# Possible joystick actions: JOYAXISMOTION, JOYBALLMOTION, JOYBUTTONDOWN,
# JOYBUTTONUP, JOYHATMOTION
for event in pygame.event.get(): # User did something.
if event.type == pygame.QUIT: # If user clicked close.
done = True # Flag that we are done so we exit this loop.
elif event.type == pygame.JOYBUTTONDOWN:
print("Joystick button pressed.")
elif event.type == pygame.JOYBUTTONUP:
print("Joystick button released.")
#
# DRAWING STEP
#
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(WHITE)
textPrint.reset()
# Get count of joysticks.
joystick_count = pygame.joystick.get_count()
textPrint.tprint(screen, "Number of joysticks: {}".format(joystick_count))
textPrint.indent()
# For each joystick:
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
try:
jid = joystick.get_instance_id()
except AttributeError:
# get_instance_id() is an SDL2 method
jid = joystick.get_id()
textPrint.tprint(screen, "Joystick {}".format(jid))
textPrint.indent()
# Get the name from the OS for the controller/joystick.
name = joystick.get_name()
textPrint.tprint(screen, "Joystick name: {}".format(name))
try:
guid = joystick.get_guid()
except AttributeError:
# get_guid() is an SDL2 method
pass
else:
textPrint.tprint(screen, "GUID: {}".format(guid))
# Usually axis run in pairs, up/down for one, and left/right for
# the other.
axes = joystick.get_numaxes()
textPrint.tprint(screen, "Number of axes: {}".format(axes))
textPrint.indent()
for i in range(axes):
axis = joystick.get_axis(i)
textPrint.tprint(screen, "Axis {} value: {:>6.3f}".format(i, axis))
textPrint.unindent()
buttons = joystick.get_numbuttons()
textPrint.tprint(screen, "Number of buttons: {}".format(buttons))
textPrint.indent()
for i in range(buttons):
button = joystick.get_button(i)
textPrint.tprint(screen,
"Button {:>2} value: {}".format(i, button))
textPrint.unindent()
hats = joystick.get_numhats()
textPrint.tprint(screen, "Number of hats: {}".format(hats))
textPrint.indent()
# Hat position. All or nothing for direction, not a float like
# get_axis(). Position is a tuple of int values (x, y).
for i in range(hats):
hat = joystick.get_hat(i)
textPrint.tprint(screen, "Hat {} value: {}".format(i, str(hat)))
textPrint.unindent()
textPrint.unindent()
#
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
#
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 20 frames per second.
clock.tick(20)
# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit()
Does anyone have any insight into why this is?
Bluetooth may not be enabled yet try enabling it or checking the controllers batteries!
I have tried this same script with an Xbox One Series 2 Controller and can confirm that it works flawlessly. I connected the controller to the PC with the charging cable, not wirelessly (because I have an Xbox in the same room).
You should try the same first and be able to open the Xbox Game Bar by holding down the button, otherwise check your Xbox settings on the PC and update your drivers from the device manager (while wired).
Also, make sure that you have the last Pygame version, I tried with 2.1.2 on Windows 10.
Hope this give you a hint.
try running a controller testing tool if it doesn't work there then it is probably a problem with the controller also try reinstalling pygame and checking if you have drivers correctly installed

Python 3: cx_Freeze freezes a working program into a NOT working program

Yes, it looks like it's a duplicate question (already asked here), however, I have a problem with a Pygame app, not a Console app. It works fine when launching it from IDLE or Python Code Executer (just double-clicking the file :) ), but crashes with no tracebacks. It just keeps crashing (looks like it crashes on the drawing step, I don't know) every time I launch the EXE. The full code is here:
import pygame
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
# This is a simple class that will help us print to the screen
# It has nothing to do with the joysticks, just outputing the
# information.
class TextPrint:
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 20)
def print(self, screen, textString):
textBitmap = self.font.render(textString, True, BLACK)
screen.blit(textBitmap, [self.x, self.y])
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
pygame.init()
# Set the width and height of the screen [width,height]
size = [500, 700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("JoyMonitor V.1.1")
#pygame.display.set_icon("icon.ico")
# Get ready to print
textPrint = TextPrint()
#Loop until the user clicks the close button.
nondone = True
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# Initialize the joysticks
pygame.joystick.init()
# -------- Main Program Loop -----------
while nondone:
# EVENT PROCESSING STEP
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
nondone = False # Flag that we are done so we exit this loop
# Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
if event.type == pygame.JOYBUTTONDOWN:
print("Joystick button pressed.")
if event.type == pygame.JOYBUTTONUP:
print("Joystick button released.")
# DRAWING STEP
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(WHITE)
textPrint.reset()
textPrint.print(screen, "JoyMonitor: Joysticks, Gamepads & Steering Wheels")
textPrint.print(screen, "Connecting/disconnecting devices requires restart!")
# Get count of joysticks
joystick_count = pygame.joystick.get_count()
textPrint.print(screen, "Number of game input devices: {}".format(joystick_count) )
textPrint.indent()
# For each joystick:
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
textPrint.print(screen, "Device {}".format(i) )
textPrint.indent()
# Get the name from the OS for the controller/joystick
name = joystick.get_name()
textPrint.print(screen, "Device name: {}".format(name) )
# Usually axis run in pairs, up/down for one, and left/right for
# the other.
axes = joystick.get_numaxes()
textPrint.print(screen, "Number of axes: {}".format(axes) )
textPrint.indent()
for i in range( axes ):
axis = joystick.get_axis( i )
textPrint.print(screen, "Axis {} value: {:>6.3f}".format(i, axis) )
textPrint.unindent()
buttons = joystick.get_numbuttons()
textPrint.print(screen, "Number of buttons: {}".format(buttons) )
textPrint.indent()
for i in range( buttons ):
button = joystick.get_button( i )
textPrint.print(screen, "Button {:>2} value: {}".format(i,button) )
textPrint.unindent()
# Hat switch. All or nothing for direction, not like joysticks.
# Value comes back in an array.
hats = joystick.get_numhats()
textPrint.print(screen, "Number of POVs: {}".format(hats) )
textPrint.indent()
for i in range( hats ):
hat = joystick.get_hat( i )
textPrint.print(screen, "POV {} value: {}".format(i, str(hat)) )
textPrint.unindent()
balls = joystick.get_numballs()
textPrint.print(screen, "Number of trackballs: {}".format(balls) )
textPrint.indent()
for i in range( balls ):
ball = joystick.get_ball( i )
textPrint.print(screen, "Trackball {} value: {}".format(i, str(ball)) )
textPrint.unindent()
textPrint.unindent()
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 60 frames per second
clock.tick(60)
# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit ()
According to Making an .exe for pygame with cx-freeze, you need to use a system font if you're not going to include the default font of pygame.font.Font(None,20)
One solution is to replace:
self.font = pygame.font.Font(None, 20)
to:
self.font = pygame.font.SysFont("arial", 20) #or you can use any other system font
Or, you can include the ttf file of the default Font font in your setup.py, which you can get using pygame.font.get_defaultfont()

Problems using pygame with a gamepad

Hi i'm using pygame for a school project but it seems to not work correctly.
First of all i try to use it with a gamepad and to make it return me joystick position but even when i use their own program
import pygame
# Define some colors
BLACK = ( 0, 0, 0)
WHITE = ( 255, 255, 255)
# This is a simple class that will help us print to the screen
# It has nothing to do with the joysticks, just outputing the
# information.
class TextPrint:
def __init__(self):
self.reset()
self.font = pygame.font.Font(None, 20)
def print(self, screen, textString):
textBitmap = self.font.render(textString, True, BLACK)
screen.blit(textBitmap, [self.x, self.y])
self.y += self.line_height
def reset(self):
self.x = 10
self.y = 10
self.line_height = 15
def indent(self):
self.x += 10
def unindent(self):
self.x -= 10
pygame.init()
# Set the width and height of the screen [width,height]
size = [500, 700]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("My Game")
#Loop until the user clicks the close button.
done = False
# Used to manage how fast the screen updates
clock = pygame.time.Clock()
# Initialize the joysticks
pygame.joystick.init()
# Get ready to print
textPrint = TextPrint()
# -------- Main Program Loop -----------
while done==False:
# EVENT PROCESSING STEP
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
# Possible joystick actions: JOYAXISMOTION JOYBALLMOTION JOYBUTTONDOWN JOYBUTTONUP JOYHATMOTION
if event.type == pygame.JOYBUTTONDOWN:
print("Joystick button pressed.")
if event.type == pygame.JOYBUTTONUP:
print("Joystick button released.")
# DRAWING STEP
# First, clear the screen to white. Don't put other drawing commands
# above this, or they will be erased with this command.
screen.fill(WHITE)
textPrint.reset()
# Get count of joysticks
joystick_count = pygame.joystick.get_count()
textPrint.print(screen, "Number of joysticks: {}".format(joystick_count) )
textPrint.indent()
# For each joystick:
for i in range(joystick_count):
joystick = pygame.joystick.Joystick(i)
joystick.init()
textPrint.print(screen, "Joystick {}".format(i) )
textPrint.indent()
# Get the name from the OS for the controller/joystick
name = joystick.get_name()
textPrint.print(screen, "Joystick name: {}".format(name) )
# Usually axis run in pairs, up/down for one, and left/right for
# the other.
axes = joystick.get_numaxes()
textPrint.print(screen, "Number of axes: {}".format(axes) )
textPrint.indent()
for i in range( axes ):
axis = joystick.get_axis( i )
textPrint.print(screen, "Axis {} value: {:>6.3f}".format(i, axis) )
textPrint.unindent()
buttons = joystick.get_numbuttons()
textPrint.print(screen, "Number of buttons: {}".format(buttons) )
textPrint.indent()
for i in range( buttons ):
button = joystick.get_button( i )
textPrint.print(screen, "Button {:>2} value: {}".format(i,button) )
textPrint.unindent()
# Hat switch. All or nothing for direction, not like joysticks.
# Value comes back in an array.
hats = joystick.get_numhats()
textPrint.print(screen, "Number of hats: {}".format(hats) )
textPrint.indent()
for i in range( hats ):
hat = joystick.get_hat( i )
textPrint.print(screen, "Hat {} value: {}".format(i, str(hat)) )
textPrint.unindent()
textPrint.unindent()
# ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Limit to 20 frames per second
clock.tick(20)
# Close the window and quit.
# If you forget this line, the program will 'hang'
# on exit if running from IDLE.
pygame.quit ()
It detect the gamepad but doesn't return me anything buttons/hats/joystick all the value stays at 0.
Even when i try it with my keyboard it detect the device but always return me 0 even when keys are pressed with pygame.key.get_pressed()
The problem is that i dont have a gamepad to experiment most of the time, so i tried with my keyboard to detect key which are pressed but i doesn't work either. My program was :
import pygame
import time
pygame.init()
while True:
print(pygame.key.get_pressed())
time.sleep(3)
But it doesn't matter which keys are pressed the value remains to 0 for all of them
Try going through and initializing all the joysticks only once outside of the loop and then remove the code that initializes them that's currently inside the loop. It may be that when you do that it clears-out some sort of input buffer giving you zeroed-out values. But without having a gamepad on hand to test this theory, this is just my guess.

Categories