I am trying to get a controller object working using Pyget. I have been following this documentation, but am not sure how to set up button listeners.
This is a pared down version of my code:
#test_2.py
import arcade
import sys
import os
import pyglet
controller__cursor = None
def initiate(maingame_window):
global controller__cursor
controller__cursor = CursorControl(maingame_window)
class CursorControl():
active_cursor_list = [] # (player, cursor_x, cursor_y, controller_num, colour)
initiated_controller_namelist = []
joystick_count = 0
controller_manager = pyglet.input.ControllerManager()
class ActiveController():
pos_x = 0
pos_y = 0
controller_obj = None
cursor_colour = arcade.color.GREEN
assigned_player = None
def __init__(self, controller_obj, assigned_player):
self.assigned_player = assigned_player
self.controller_obj = controller_obj
self.controller_obj.open()
print("openning controller")
self.controller_obj.event = self.on_button_press(self.controller_obj.event)
@controller_obj.event # This throws an error because controller_obj = None, but it is set in __init__
def on_button_press(controller_obj, button_name):
print("on_button_press called")
if (button_name == 'a'): print("a pressed")
elif (button_name == 'b'): print("b pressed")
def __init__(self, maingame_window):
all_gamepads = self.get_controllers()
if (len(all_gamepads) > 0):
for a_controller_num in self.get_controllers():
print(f"Connection initial controllers: {a_controller_num}")
self.connect_new_controller(a_controller_num)
else:
self.connect_new_controller(0) # On controller plug-in, add the controller to player 1
# Controller Manager
@controller_manager.event
def on_connect(controller):
print(f"Connected: {controller}")
@controller_manager.event
def on_disconnect(controller):
print(f"Disconnected: {controller}")
def get_controllers(self):
return_list = []
for a_device in self.controller_manager.get_controllers():
return_list.append(a_device)
return return_list
def connect_new_controller(self, controller_obj):
print("Connecting new controller: " + controller_obj.name)
screen_w, screen_h = getScreenDims()
self.initiated_controller_namelist.append(controller_obj.name)
# Controller is opened (controller_obj.open()) in the __init__ of self.ActiveController
self.active_cursor_list.append(
self.ActiveController(controller_obj, "Player_Name")
)
class MainGame(arcade.Window):
cursor_colour = arcade.color.GREEN
stage_status = "menu_main"
player_list = [] # populate this on game selection (or load). It will hole the player info (name, cursor x&y)
def __init__(self):
super().__init__(600, 600, title="Trivia Quest")
self.set_mouse_visible(True)
# Starting location of cursor
self.x = 100
self.y = 100
#print("Initial: " + str(arcade.get_game_controllers()))
initiate(self)
update_tick_count = 0
def update(self, delta_time): pass
def on_update(self, delta_time):
self.update_tick_count += 1
if (self.update_tick_count % 60 == 0): self.on_update_second()
def on_update_second(self):
pass
#controller__cursor.on_step(self)
# Creating on_draw() function to draw on the screen
def on_draw(self):
arcade.start_render()
arcade.draw_circle_filled(self.x, self.y, 25, self.cursor_colour)
#arcade.finish_render()
# Creating function to check the position of the mouse
def on_mouse_motion(self, x, y, dx, dy):
tq_menu.controller__cursor.mouse_move(x, y, dx, dy)
self.x = x
self.y = y
def on_mouse_press(self, x, y, button, modifiers):
self.cursor_colour = arcade.color.BLUE
def on_mouse_release(self, x, y, button, modifiers):
self.cursor_colour = arcade.color.GREEN
MainGame()
arcade.run()
And this is the error message:
Traceback (most recent call last):
File "...\test_2.py", line 12, in <module>
class CursorControl():
File "...\test_2.py", line 19, in CursorControl
class ActiveController():
File "...\test_2.py", line 34, in ActiveController
@controller_obj.event # This throws an error because controller_obj = None, but it is set in __init__
AttributeError: 'NoneType' object has no attribute 'event'
I'm not sure how to set @controller_obj.event with controller_obj not as None when that object is set through the init. I'm sure there is something I am missing about this process.
I found out the answer. The listener has to be assigned after the initialisation. It works when the "bind_button_press" function is called to assign the functions. Here is the updated "ActiveController" class, with stick, trigger, dpad, and button listeners:
class ActiveController():
pos_x = 0
pos_y = 0
controller_obj = None
cursor_colour = arcade.color.GREEN
assigned_player = None
def __init__(self, controller_obj, assigned_player):
self.assigned_player = assigned_player
self.controller_obj = controller_obj
self.controller_obj.open()
self.bind_button_press() # Set the assigns to be after the initialisation
def on_trigger_motion(self, device_obj, trigger_name, value):
if (trigger_name == "righttrigger"):
print(self.assigned_player + " goes pew pew")
def on_dpad_motion(self, device_obj, left, right, up, down):
pass
def on_stick_motion(self, device_obj, stick_name, xaxis, yaxis):
self.pos_x += xaxis
self.pos_y += yaxis
def on_button_press(self, device_obj, button_name):
if (button_name == 'a'):
print("a pressed")
elif (button_name == 'b'):
print("b pressed")
def bind_button_press(self):
self.controller_obj.push_handlers(on_button_press=self.on_button_press)
self.controller_obj.push_handlers(on_stick_motion=self.on_stick_motion)
self.controller_obj.push_handlers(on_dpad_motion=self.on_dpad_motion)
self.controller_obj.push_handlers(on_trigger_motion=self.on_trigger_motion)