ppizarror / pygame-menu

A menu for pygame. Simple, and easy to use
https://pygame-menu.readthedocs.io/
Other
544 stars 141 forks source link

Selector and Joystick #422

Closed AdamCyffka closed 1 year ago

AdamCyffka commented 1 year ago

Hey, me again, sorry for the delay, we had taken a break on our project.

To come back to our problem, here is a video that will be more telling of the problem with our joystick. When we go left and then return to the center, it goes to the left and then to the right and not left and nothing. Do you have any idea?

https://streamable.com/l75kqh

ppizarror commented 1 year ago

I think this is related to the calibration of the menu events. Check out the following lines:

https://github.com/ppizarror/pygame-menu/blob/da197b7a3cfd997bd4ccc105e4f965eb55b8d138/pygame_menu/menu.py#L2569-L2580

When you move the joystick to left or right it generates a lot of events that have to be "delayed" because if not one single movement of the axis would trigger 300 "move left" events. How many repeats and delay is configured in JOY_DELAY and JOY_REPEAT.

https://github.com/ppizarror/pygame-menu/blob/da197b7a3cfd997bd4ccc105e4f965eb55b8d138/pygame_menu/controls.py#L47-L58

Maybe tuning these parameters will solve your issue. You can change these values by modifying the Controller:

new_ctrl = ctrl.Controller()
new_ctrl.joy_delay = 200 # ms
menu.set_controller(new_ctrl)
ppizarror commented 1 year ago

Today I updated the library to v4.3.0 which introduces this new Controller object. https://pygame-menu.readthedocs.io/en/4.3.0/_source/advanced_controller.html

AdamCyffka commented 1 year ago

Thanks it's working!

Another tricky thing, I want to change the confirm key of a game selector and set a button (not keyboard). I know how to change i: ctrl.KEY_APPLY = pygame.K_SPACE with the space bar, but can't find a enum for buttons.

In the program, I have the event var so I can check if event.button == 8 and do something. But how can I found the equivalent of K_SPACE but for buttons.

ppizarror commented 1 year ago

Sure, as explained in the documentation, you can create a custom controller object which now has all the instructions regarding how a widget responds to apply:

https://github.com/ppizarror/pygame-menu/blob/a0c59763d96c5bd5e117c737076b7445b051e6a8/pygame_menu/controls.py#L84-L92

As you can see, the controller receives the event and widget, thus, any kind of new event can be created. In your case, you must create a new controller (or retrieve the one from the widget, as each instance of the widget has its own object) and apply it to the widget:

import pygame_menu.controls as ctrl
new_ctrl = ctrl.Controller()

def custom_widget_apply(event, widget) -> bool:
    return event.key == pygame.K_SPACE or event.button == 8

new_ctrl.apply = custom_widget_apply
mywidget.set_controller(new_ctrl)

Since v4.3.1 (to be released today) you can get the controller from a widget widget.get_controller(), and you can apply a controller to all widgets within the menu menu.set_controller(new_ctrl, apply_to_widgets=True).

Let me know if this solves your issue.

ppizarror commented 1 year ago

v4.3.1 uploaded to pip!

AdamCyffka commented 1 year ago

Nice to ear, better to update everything this way ^^ Little issue here, Event can't be found in custom_widget_apply, got this error. AttributeError: 'Event' object has no attribute 'button'

Also before that, the function custom_widget_apply said one arg is missing, I tried to add self as first arg, I don't have the bellow error with this, but still first error.

TypeError: Launcher.custom_widget_apply() takes 2 positional arguments but 3 were given

ppizarror commented 1 year ago

I think you should use ctrl.joy_select instead:

def custom_widget_apply(event, _) -> bool:
    return event.key == pygame.K_SPACE
def custom_joy_apply(event, _) -> bool:
    return event.button == 8

new_ctrl_sel = ctrl.Controller()
new_ctrl_sel.apply = custom_widget_apply
new_ctrl_sel.joy_select = custom_joy_apply

selector = menu.add.selector('select', ['a', 'b', 'c'])
selector.set_controller(new_ctrl_sel)

I can confirm this works. See updated tests:

https://github.com/ppizarror/pygame-menu/blob/4f18a571367a64116317e18c1d3ab763bcf28d2a/test/test_controls.py#L104-L140

Regarding TypeError: Launcher.custom_widget_apply() takes 2 positional arguments but 3 were given I cannot reproduce your issue. Tests from python 3.7-3.10 works https://github.com/ppizarror/pygame-menu/actions/runs/3640023933

AdamCyffka commented 1 year ago

For me, your apply function still take 3 args

image

ppizarror commented 1 year ago

Weird, as old tests had the same format, see https://github.com/ppizarror/pygame-menu/tree/e75441d5ab425404406ef6c9bd473fad3973868f and https://github.com/ppizarror/pygame-menu/actions/runs/3630490971. The test was the same. Which python version are you using?.

Today I changed that class using @staticmethod. Also, to overcome that issue you can create a custom Controller using inheritance:

class MyCustomController(Controller):
   ...

That approach should solve that issue.

AdamCyffka commented 1 year ago

python was not up to date, everything is working fine. thanks a lot