mima-engine 0.1.5__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mima-engine might be problematic. Click here for more details.

Files changed (80) hide show
  1. mima/__init__.py +1 -1
  2. mima/backend/pygame_assets.py +14 -8
  3. mima/backend/pygame_audio.py +5 -2
  4. mima/backend/pygame_backend.py +255 -57
  5. mima/backend/pygame_camera.py +63 -0
  6. mima/backend/pygame_events.py +331 -85
  7. mima/collision.py +182 -111
  8. mima/engine.py +155 -15
  9. mima/maps/tiled/tiled_map.py +3 -3
  10. mima/maps/tiled/tiled_tileset.py +1 -0
  11. mima/maps/tilemap.py +78 -15
  12. mima/maps/tileset.py +8 -2
  13. mima/maps/transition_map.py +6 -8
  14. mima/mode_engine.py +80 -0
  15. mima/objects/animated_sprite.py +23 -15
  16. mima/objects/attributes.py +3 -0
  17. mima/objects/creature.py +54 -17
  18. mima/objects/dynamic.py +30 -8
  19. mima/objects/effects/colorize_screen.py +22 -6
  20. mima/objects/effects/debug_box.py +124 -0
  21. mima/objects/effects/light.py +21 -30
  22. mima/objects/effects/show_sprite.py +39 -0
  23. mima/objects/effects/walking_on_grass.py +25 -7
  24. mima/objects/effects/walking_on_water.py +17 -6
  25. mima/objects/loader.py +24 -13
  26. mima/objects/projectile.py +21 -6
  27. mima/objects/sprite.py +7 -8
  28. mima/objects/world/color_gate.py +5 -2
  29. mima/objects/world/color_switch.py +12 -6
  30. mima/objects/world/container.py +17 -8
  31. mima/objects/world/floor_switch.py +8 -4
  32. mima/objects/world/gate.py +8 -5
  33. mima/objects/world/light_source.py +11 -9
  34. mima/objects/world/logic_gate.py +8 -7
  35. mima/objects/world/movable.py +72 -28
  36. mima/objects/world/oneway.py +14 -9
  37. mima/objects/world/pickup.py +10 -5
  38. mima/objects/world/switch.py +28 -25
  39. mima/objects/world/teleport.py +76 -55
  40. mima/scene_engine.py +19 -20
  41. mima/scripts/command.py +16 -2
  42. mima/scripts/commands/change_map.py +23 -4
  43. mima/scripts/commands/equip_weapon.py +23 -0
  44. mima/scripts/commands/give_item.py +5 -3
  45. mima/scripts/commands/move_map.py +9 -9
  46. mima/scripts/commands/parallel.py +16 -3
  47. mima/scripts/commands/present_item.py +7 -5
  48. mima/scripts/commands/screen_fade.py +30 -12
  49. mima/scripts/commands/serial.py +30 -7
  50. mima/scripts/commands/set_spawn_map.py +6 -3
  51. mima/scripts/commands/show_choices.py +16 -7
  52. mima/scripts/commands/show_dialog.py +110 -3
  53. mima/scripts/script_processor.py +41 -20
  54. mima/states/game_state.py +2 -0
  55. mima/states/memory.py +28 -0
  56. mima/states/quest.py +2 -3
  57. mima/types/keys.py +48 -0
  58. mima/types/mode.py +4 -10
  59. mima/types/player.py +9 -0
  60. mima/types/position.py +13 -0
  61. mima/types/tile_collision.py +11 -0
  62. mima/types/window.py +44 -0
  63. mima/usables/item.py +1 -0
  64. mima/util/colors.py +5 -0
  65. mima/util/constants.py +6 -0
  66. mima/util/functions.py +27 -0
  67. mima/util/input_defaults.py +109 -0
  68. mima/util/runtime_config.py +234 -30
  69. mima/util/trading_item.py +20 -0
  70. mima/view/camera.py +160 -19
  71. mima/view/mima_mode.py +612 -0
  72. mima/view/mima_scene.py +225 -0
  73. mima/view/mima_view.py +12 -0
  74. mima/view/mima_window.py +153 -0
  75. {mima_engine-0.1.5.dist-info → mima_engine-0.2.0.dist-info}/METADATA +4 -2
  76. mima_engine-0.2.0.dist-info/RECORD +128 -0
  77. {mima_engine-0.1.5.dist-info → mima_engine-0.2.0.dist-info}/WHEEL +1 -1
  78. mima/view/scene.py +0 -322
  79. mima_engine-0.1.5.dist-info/RECORD +0 -114
  80. {mima_engine-0.1.5.dist-info → mima_engine-0.2.0.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,17 @@
1
1
  import logging
2
2
  import time
3
- from typing import Dict, List, Union
3
+ from typing import Any, Dict, List, Optional, Tuple, Union
4
4
 
5
5
  import pygame
6
6
 
7
7
  from ..types.keys import Key as K
8
+ from ..types.player import Player
8
9
  from ..util.constants import AXIS_ACTIVATION, AXIS_DEADZONE, DOUBLE_TAP_SPEED
9
10
  from ..util.input_defaults import (
10
11
  BUTTONS,
11
12
  DEFAULT_JOYSTICK_MAP,
12
13
  DEFAULT_KEYBOARD_MAP,
14
+ DEFAULT_TOUCHSCREEN_MAP,
13
15
  )
14
16
 
15
17
  LOG = logging.getLogger(__name__)
@@ -32,8 +34,9 @@ class PygameUserInput:
32
34
 
33
35
  def __init__(
34
36
  self,
35
- key_map: Dict[K, List[str]] = DEFAULT_KEYBOARD_MAP,
36
- joystick_map: Dict[K, List[Union[str, int]]] = DEFAULT_JOYSTICK_MAP,
37
+ key_map: Optional[Dict[K, List[str]]] = None,
38
+ joystick_map: Optional[Dict[K, List[Union[str, int]]]] = None,
39
+ joy_to_player: Optional[Dict[int, Player]] = None,
37
40
  platform: str = "PC",
38
41
  ):
39
42
  self._last_keys: Dict[K, bool] = {}
@@ -46,7 +49,17 @@ class PygameUserInput:
46
49
  self._last_right_tap: float = 0.0
47
50
  self._last_left_motion: float = 0.0
48
51
  self._last_right_motion: float = 0.0
49
- self._key_map: Dict[K, int] = {}
52
+ self._key_map: Dict[K, List[int]] = {}
53
+ self.joystick_to_player: Dict[int, Player] = (
54
+ joy_to_player
55
+ if joy_to_player is not None
56
+ else {
57
+ 0: Player.P1,
58
+ 1: Player.P2,
59
+ 2: Player.P3,
60
+ 4: Player.P4,
61
+ }
62
+ )
50
63
  self.vd = pygame.Vector2(0, 0)
51
64
  self.joystick_input_enabled: bool = True
52
65
  if platform == "android":
@@ -62,24 +75,82 @@ class PygameUserInput:
62
75
  # for val in vals:
63
76
  # self._key_map[key].append(getattr(pygame, f"K_{val}"))
64
77
  # else:
78
+ key_map = key_map if key_map is not None else DEFAULT_KEYBOARD_MAP
65
79
  for key, vals in key_map.items():
66
80
  self._key_map[key] = []
67
81
  for val in vals:
82
+ if len(val) > 1:
83
+ val = val.upper()
68
84
  self._key_map[key].append(getattr(pygame, f"K_{val}"))
69
85
 
86
+ # print(self._key_map)
70
87
  # self._key_map = key_map
71
88
  # if joystick_map is None:
72
89
  # self._joystick_map = DEFAULT_JOYSTICK_MAP
73
90
  # else:
74
- self._joystick_map = joystick_map
75
-
76
- self.joystick = None
77
- self._init_joystick()
91
+ if joystick_map is None:
92
+ self._joystick_map = {}
93
+ for but in BUTTONS:
94
+ self._joystick_map[but] = DEFAULT_JOYSTICK_MAP[
95
+ K(but.value % 12)
96
+ ]
97
+ else:
98
+ self._joystick_map = joystick_map
99
+
100
+ self.joysticks: Dict[Player, Optional[Any]] = {}
101
+ self._init_joysticks()
78
102
  self.width = 0
79
103
  self.height = 0
104
+ self._past_events = {}
105
+ self._new_events = {}
106
+ self._collect_all_events = False
80
107
 
81
108
  def reset(self):
82
109
  self._last_keys = self._new_keys.copy()
110
+ self._past_events = self._new_events.copy()
111
+ self.all_events = []
112
+
113
+ def get_keyboard_map(self) -> Dict[K, List[str]]:
114
+ key_map: Dict[K, List[str]] = {}
115
+ for key, mapping in self._key_map.items():
116
+ key_map[key] = []
117
+ for val in mapping:
118
+ key_map[key].append(pygame.key.name(val))
119
+ return key_map
120
+
121
+ def get_joystick_map(self):
122
+ return self._joystick_map
123
+
124
+ def get_key_name(self, val: int):
125
+ return pygame.key.name(val)
126
+
127
+ def update_keyboard_map(self, kbmap: Dict[K, List[str]]):
128
+ new_keymap: Dict[K, List[int]] = {}
129
+ try:
130
+ for key, vals in kbmap.items():
131
+ new_keymap[key] = []
132
+ for val in vals:
133
+ if len(val) > 1:
134
+ val = val.upper()
135
+ new_keymap[key].append(getattr(pygame, f"K_{val}"))
136
+ except Exception as err:
137
+ LOG.exception(f"Failed to update keyboard map: {err}")
138
+ return
139
+ self._key_map = new_keymap
140
+
141
+ def update_joystick_map(self, jsmap):
142
+ self._joystick_map = jsmap
143
+
144
+ def update_joysticks(self, reassign: List[Tuple[int, Player]]):
145
+ self.joystick_to_player = {}
146
+ for item in reassign:
147
+ self.joystick_to_player[item[0]] = item[1]
148
+ # k2d = None
149
+ # for jid, p in self.joystick_to_player.items():
150
+ # if p == player:
151
+ # k2d = jid
152
+ # self.joystick_to_player[joy] = player
153
+ # self.joystick_to_player[k2d] = None
83
154
 
84
155
  def process(self, event):
85
156
  if event.type in KEYBOARD_EVENTS:
@@ -91,7 +162,15 @@ class PygameUserInput:
91
162
  if event.type in TOUCH_EVENTS:
92
163
  self._handle_touch(event)
93
164
 
165
+ # print(
166
+ # {key: val for key, val in self._last_keys.items() if val},
167
+ # {k: v for k, v in self._new_keys.items() if v},
168
+ # )
169
+
94
170
  def _handle_keyboard(self, event):
171
+ if self._collect_all_events:
172
+ self._collect_keyboard_events(event)
173
+
95
174
  if event.type == pygame.KEYDOWN:
96
175
  for but, keys in self._key_map.items():
97
176
  if event.key in keys:
@@ -102,78 +181,93 @@ class PygameUserInput:
102
181
  if event.key in keys:
103
182
  self.unset_key(but)
104
183
 
184
+ def _js_real(self, joy, but):
185
+ return K[f"{self.joystick_to_player[joy].name}_{but.name}"]
186
+
105
187
  def _handle_joystick(self, event):
188
+ if self._collect_all_events:
189
+ self._collect_joystick_events(event)
190
+
106
191
  if event.type == pygame.JOYDEVICEREMOVED:
107
- self.joystick = None
192
+ self.joystick = {}
108
193
  LOG.info("Gamepad unplugged.")
109
194
 
110
195
  if event.type == pygame.JOYDEVICEADDED:
111
- self._init_joystick()
112
- LOG.info(
113
- "Detected new gamepad device %s.", self.joystick.get_name()
114
- )
196
+ self._init_joysticks()
197
+ LOG.info("Detected new gamepad device %s.", self.joysticks)
115
198
 
116
199
  if event.type == pygame.JOYBUTTONDOWN:
117
- if event.joy != 0:
200
+ if event.joy not in self.joystick_to_player:
118
201
  return
119
202
  for but, keys in self._joystick_map.items():
120
- if event.button in keys:
203
+ if (
204
+ str(event.button) in keys
205
+ and self.joystick_to_player[event.joy] is not None
206
+ and self.joystick_to_player[event.joy].name in but.name
207
+ ):
121
208
  self.set_key(but)
122
209
 
123
210
  if event.type == pygame.JOYBUTTONUP:
124
- if event.joy != 0:
211
+ if event.joy not in self.joystick_to_player:
125
212
  return
126
213
  for but, keys in self._joystick_map.items():
127
- if event.button in keys:
214
+ if (
215
+ str(event.button) in keys
216
+ and self.joystick_to_player[event.joy] is not None
217
+ and self.joystick_to_player[event.joy].name in but.name
218
+ ):
128
219
  self.unset_key(but)
220
+
129
221
  if event.type == pygame.JOYHATMOTION:
130
- if event.joy != 0 or event.hat != 0:
222
+ if event.joy not in self.joystick_to_player:
131
223
  return
132
224
 
133
225
  if event.value[0] == 0:
134
- self.unset_key(K.LEFT)
135
- self.unset_key(K.RIGHT)
226
+ self.unset_key(self._js_real(event.joy, K.LEFT))
227
+ self.unset_key(self._js_real(event.joy, K.RIGHT))
136
228
  elif event.value[0] == -1:
137
- self.set_key(K.LEFT)
138
- self.unset_key(K.RIGHT)
229
+ self.set_key(self._js_real(event.joy, K.LEFT))
230
+ self.unset_key(self._js_real(event.joy, K.RIGHT))
139
231
  else:
140
- self.unset_key(K.LEFT)
141
- self.set_key(K.RIGHT)
232
+ self.unset_key(self._js_real(event.joy, K.LEFT))
233
+ self.set_key(self._js_real(event.joy, K.RIGHT))
142
234
 
143
235
  if event.value[1] == 0:
144
- self.unset_key(K.UP)
145
- self.unset_key(K.DOWN)
236
+ self.unset_key(self._js_real(event.joy, K.UP))
237
+ self.unset_key(self._js_real(event.joy, K.DOWN))
146
238
  elif event.value[1] == 1:
147
- self.set_key(K.UP)
148
- self.unset_key(K.DOWN)
239
+ self.set_key(self._js_real(event.joy, K.UP))
240
+ self.unset_key(self._js_real(event.joy, K.DOWN))
149
241
  else:
150
- self.unset_key(K.UP)
151
- self.set_key(K.DOWN)
242
+ self.unset_key(self._js_real(event.joy, K.UP))
243
+ self.set_key(self._js_real(event.joy, K.DOWN))
244
+
152
245
  if event.type == pygame.JOYAXISMOTION:
153
- if event.joy != 0:
246
+ if event.joy not in self.joystick_to_player:
154
247
  return
248
+
155
249
  if event.axis == 0:
156
250
  if event.value < -AXIS_ACTIVATION:
157
- self.set_key(K.LEFT)
158
- self.unset_key(K.RIGHT)
251
+ self.set_key(self._js_real(event.joy, K.LEFT))
252
+ self.unset_key(self._js_real(event.joy, K.RIGHT))
159
253
  elif event.value > AXIS_ACTIVATION:
160
- self.unset_key(K.LEFT)
161
- self.set_key(K.RIGHT)
254
+ self.unset_key(self._js_real(event.joy, K.LEFT))
255
+ self.set_key(self._js_real(event.joy, K.RIGHT))
162
256
  elif abs(event.value) < AXIS_DEADZONE:
163
- self.unset_key(K.LEFT)
164
- self.unset_key(K.RIGHT)
257
+ self.unset_key(self._js_real(event.joy, K.LEFT))
258
+ self.unset_key(self._js_real(event.joy, K.RIGHT))
165
259
  else:
166
260
  pass
167
261
  if event.axis == 1:
168
262
  if event.value < -AXIS_ACTIVATION:
169
- self.set_key(K.UP)
170
- self.unset_key(K.DOWN)
263
+ self.set_key(self._js_real(event.joy, K.UP))
264
+ self.unset_key(self._js_real(event.joy, K.DOWN))
171
265
  elif event.value > AXIS_ACTIVATION:
172
- self.unset_key(K.UP)
173
- self.set_key(K.DOWN)
266
+ self.unset_key(self._js_real(event.joy, K.UP))
267
+ self.set_key(self._js_real(event.joy, K.DOWN))
174
268
  elif abs(event.value) < AXIS_DEADZONE:
175
- self.unset_key(K.UP)
176
- self.unset_key(K.DOWN)
269
+ self.unset_key(self._js_real(event.joy, K.UP))
270
+ self.unset_key(self._js_real(event.joy, K.DOWN))
177
271
 
178
272
  def _handle_touch(self, event):
179
273
  finger_pos = pygame.Vector2(
@@ -182,39 +276,57 @@ class PygameUserInput:
182
276
 
183
277
  if event.type == pygame.FINGERDOWN:
184
278
  tap = time.time()
185
- if event.x < 0.0625 and event.y < 0.1111:
186
- self.set_key(K.R)
187
- elif event.x < 0.5:
188
- # print(f"Left Finger Down: {finger_pos}")
189
- self._left_finger_tap_pos = finger_pos
190
-
191
- if tap - self._last_left_tap < DOUBLE_TAP_SPEED:
192
- # print("Left Double Tap")
193
- self.set_key(K.SELECT)
194
- self._last_left_tap = tap
195
- # self._left_finger_pos.x = event.x
196
- # self._left_finger_pos.y = event.y
197
-
198
- # if tap - self._last_left_tap < 0.2:
199
- # print("Left Double Tap")
200
- # # self._set_key(K.START)
201
- # # self._unset_key(K.RIGHT)
202
- # # self._unset_key(K.LEFT)
203
- # # self._unset_key(K.UP)
204
- # # self._unset_key(K.DOWN)
205
- else:
206
- self._right_finger_tap_pos = finger_pos
207
-
208
- # if tap - self._last_right_tap < DOUBLE_TAP_SPEED:
209
- # # print("Right Double Tap")
210
- # self.set_key(K.SELECT)
211
- self._last_right_tap = tap
212
- if event.y < 0.3:
213
- self.set_key(K.START)
214
- elif event.x < 0.75:
215
- self.set_key(K.B)
216
- else:
217
- self.set_key(K.A)
279
+ for key, area in DEFAULT_TOUCHSCREEN_MAP.items():
280
+ if (
281
+ area[0][0] <= event.x < area[1][0]
282
+ and area[0][1] <= event.y < area[1][1]
283
+ ):
284
+ if key == K.UP:
285
+ self._left_finger_tap_pos = finger_pos
286
+ if tap - self._last_left_tap < DOUBLE_TAP_SPEED:
287
+ # print("Left Double Tap")
288
+ self.set_key(K.SELECT)
289
+ self._last_left_tap = tap
290
+ else:
291
+ self.set_key(key)
292
+ self._right_finger_tap_pos = finger_pos
293
+ self._last_right_tap = tap
294
+
295
+ # if event.x < 0.0625 and event.y < 0.1111:
296
+ # self.set_key(K.L)
297
+ # elif event.x > 1.0 - 0.0625 and event.y < 0.1111:
298
+ # self.set_key(K.R)
299
+ # elif event.x < 0.5:
300
+ # # print(f"Left Finger Down: {finger_pos}")
301
+ # self._left_finger_tap_pos = finger_pos
302
+
303
+ # if tap - self._last_left_tap < DOUBLE_TAP_SPEED:
304
+ # # print("Left Double Tap")
305
+ # self.set_key(K.SELECT)
306
+ # self._last_left_tap = tap
307
+ # # self._left_finger_pos.x = event.x
308
+ # # self._left_finger_pos.y = event.y
309
+
310
+ # # if tap - self._last_left_tap < 0.2:
311
+ # # print("Left Double Tap")
312
+ # # # self._set_key(K.START)
313
+ # # # self._unset_key(K.RIGHT)
314
+ # # # self._unset_key(K.LEFT)
315
+ # # # self._unset_key(K.UP)
316
+ # # # self._unset_key(K.DOWN)
317
+ # else:
318
+ # self._right_finger_tap_pos = finger_pos
319
+
320
+ # # if tap - self._last_right_tap < DOUBLE_TAP_SPEED:
321
+ # # # print("Right Double Tap")
322
+ # # self.set_key(K.SELECT)
323
+ # self._last_right_tap = tap
324
+ # if event.y < 0.3:
325
+ # self.set_key(K.START)
326
+ # elif event.x < 0.75:
327
+ # self.set_key(K.B)
328
+ # else:
329
+ # self.set_key(K.A)
218
330
  # self._right_finger_pos.x = event.x
219
331
  # self._right_finger_pos.y = event.y
220
332
  # if tap - self._last_right_tap < 0.2:
@@ -239,7 +351,7 @@ class PygameUserInput:
239
351
  self.unset_key(K.LEFT)
240
352
  self.unset_key(K.UP)
241
353
  self.unset_key(K.DOWN)
242
- self.unset_key(K.R)
354
+ self.unset_key(K.L)
243
355
  # print(
244
356
  # f"Left Finger moved {finger_dist} "
245
357
  # f"({release - self._last_left_tap} s)"
@@ -408,11 +520,17 @@ class PygameUserInput:
408
520
  # self._unset_key(K.A)
409
521
  pass
410
522
 
411
- def _init_joystick(self):
412
- if pygame.joystick.get_count() > 0:
413
- self.joystick = pygame.joystick.Joystick(0)
414
- self.joystick.init()
415
- LOG.info("Initialized Joystick %s.", self.joystick.get_name())
523
+ def _init_joysticks(self):
524
+ for jid in range(pygame.joystick.get_count()):
525
+ js = pygame.joystick.Joystick(jid)
526
+ js.init()
527
+ # p = Player(jid + 1)
528
+ self.joysticks[js.get_id()] = js
529
+ LOG.info(
530
+ "Initialized Joystick #%d: %s",
531
+ jid,
532
+ self.joysticks[js.get_id()].get_name(),
533
+ )
416
534
 
417
535
  def set_key(self, button: K):
418
536
  self._new_keys[button] = True
@@ -420,11 +538,139 @@ class PygameUserInput:
420
538
  def unset_key(self, button: K):
421
539
  self._new_keys[button] = False
422
540
 
423
- def new_key_press(self, button: K):
541
+ def new_key_press(self, button: K, player: Player = Player.P1):
542
+ button = _button_to_player(button, player)
424
543
  return self._new_keys[button] and not self._last_keys[button]
425
544
 
426
- def key_held(self, button: K):
545
+ def key_held(self, button: K, player: Player = Player.P1):
546
+ button = _button_to_player(button, player)
427
547
  return self._new_keys[button]
428
548
 
429
- def new_key_release(self, button: K):
549
+ def new_key_release(self, button: K, player: Player = Player.P1):
550
+ button = _button_to_player(button, player)
430
551
  return self._last_keys[button] and not self._new_keys[button]
552
+
553
+ def get_all_events(self):
554
+ return self._new_events
555
+
556
+ def _collect_keyboard_events(self, event):
557
+ kid = f"kb_{event.key}"
558
+ if event.type == pygame.KEYDOWN:
559
+ self._new_events[kid] = {
560
+ "type": "keyboard",
561
+ "id": event.type,
562
+ "button": event.key,
563
+ "name": pygame.key.name(event.key),
564
+ }
565
+ if event.type == pygame.KEYUP and kid in self._new_events:
566
+ del self._new_events[kid]
567
+
568
+ def _collect_joystick_events(self, event):
569
+ if event.type == pygame.JOYDEVICEREMOVED:
570
+ jid = f"js_{event.instance_id}_removed"
571
+ self._new_events[jid] = {
572
+ "type": "joystick",
573
+ "id": event.instance_id,
574
+ "button": "removed",
575
+ "name": "removed",
576
+ }
577
+ if event.type == pygame.JOYDEVICEADDED:
578
+ jid = f"js_{event.device_index}_added"
579
+ self._new_events[jid] = {
580
+ "type": "joystick",
581
+ "id": event.device_index,
582
+ "button": "added",
583
+ "guid": event.guid,
584
+ }
585
+
586
+ if event.type == pygame.JOYBUTTONDOWN:
587
+ kid = f"js_{event.joy}_{event.button}"
588
+
589
+ self._new_events[kid] = {
590
+ "type": "joystick",
591
+ "id": event.instance_id,
592
+ "joy": event.joy,
593
+ "button": event.button,
594
+ "name": self.joysticks[event.joy].get_name(),
595
+ "power_level": self.joysticks[event.joy].get_power_level(),
596
+ }
597
+ if event.type == pygame.JOYBUTTONUP:
598
+ kid = f"js_{event.joy}_{event.button}"
599
+ if kid in self._new_events:
600
+ del self._new_events[kid]
601
+ if event.type == pygame.JOYHATMOTION:
602
+ kid = f"js_{event.joy}_{event.hat}"
603
+ klid = f"{kid}_left"
604
+ krid = f"{kid}_right"
605
+ kuid = f"{kid}_up"
606
+ kdid = f"{kid}_down"
607
+ if event.value[0] == 0:
608
+ if klid in self._new_events:
609
+ del self._new_events[klid]
610
+ if krid in self._new_events:
611
+ del self._new_events[krid]
612
+ elif event.value[0] == -1:
613
+ self._new_events[klid] = {
614
+ "type": "joystick",
615
+ "id": event.instance_id,
616
+ "joy": event.joy,
617
+ "button": "left",
618
+ "hat": event.hat,
619
+ "value": event.value[0],
620
+ "name": self.joysticks[event.joy].get_name(),
621
+ "power_level": self.joysticks[event.joy].get_power_level(),
622
+ }
623
+ if krid in self._new_events:
624
+ del self._new_events[krid]
625
+ else:
626
+ self._new_events[krid] = {
627
+ "type": "joystick",
628
+ "id": event.instance_id,
629
+ "joy": event.joy,
630
+ "button": "right",
631
+ "hat": event.hat,
632
+ "value": event.value[0],
633
+ "name": self.joysticks[event.joy].get_name(),
634
+ "power_level": self.joysticks[event.joy].get_power_level(),
635
+ }
636
+ if klid in self._new_events:
637
+ del self._new_events[klid]
638
+
639
+ if event.value[1] == 0:
640
+ if kuid in self._new_events:
641
+ del self._new_events[kuid]
642
+ if kdid in self._new_events:
643
+ del self._new_events[kdid]
644
+ elif event.value[1] == 1:
645
+ self._new_events[kuid] = {
646
+ "type": "joystick",
647
+ "id": event.instance_id,
648
+ "joy": event.joy,
649
+ "button": "up",
650
+ "hat": event.hat,
651
+ "value": event.value[1],
652
+ "name": self.joysticks[event.joy].get_name(),
653
+ "power_level": self.joysticks[event.joy].get_power_level(),
654
+ }
655
+ if kdid in self._new_events:
656
+ del self._new_events[kdid]
657
+ else:
658
+ self._new_events[kdid] = {
659
+ "type": "joystick",
660
+ "id": event.instance_id,
661
+ "joy": event.joy,
662
+ "button": "down",
663
+ "hat": event.hat,
664
+ "value": event.value[1],
665
+ "name": self.joysticks[event.joy].get_name(),
666
+ "power_level": self.joysticks[event.joy].get_power_level(),
667
+ }
668
+ if kuid in self._new_events:
669
+ del self._new_events[kuid]
670
+
671
+ def trigger_all_events_collection(self, active: bool = True):
672
+ self._collect_all_events = active
673
+
674
+
675
+ def _button_to_player(button: K, player: Player):
676
+ return K(button.value + 12 * player.value)