mima-engine 0.1.5__py3-none-any.whl → 0.2.1__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 +369 -120
  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.1.dist-info}/METADATA +4 -2
  76. mima_engine-0.2.1.dist-info/RECORD +128 -0
  77. {mima_engine-0.1.5.dist-info → mima_engine-0.2.1.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.1.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,60 @@ 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
+
281
+ if (
282
+ area[0][0] <= event.x < area[1][0]
283
+ and area[0][1] <= event.y < area[1][1]
284
+ ):
285
+ if key == K.P1_UP:
286
+ self._left_finger_tap_pos = finger_pos
287
+ if tap - self._last_left_tap < DOUBLE_TAP_SPEED:
288
+ # print("Left Double Tap")
289
+ self.set_key(K.P1_SELECT)
290
+ self._last_left_tap = tap
291
+ elif key == K.P1_L:
292
+ self.set_key(K.P1_L)
293
+ else:
294
+ self.set_key(key)
295
+ self._right_finger_tap_pos = finger_pos
296
+ self._last_right_tap = tap
297
+
298
+ # if event.x < 0.0625 and event.y < 0.1111:
299
+ # self.set_key(K.L)
300
+ # elif event.x > 1.0 - 0.0625 and event.y < 0.1111:
301
+ # self.set_key(K.R)
302
+ # elif event.x < 0.5:
303
+ # # print(f"Left Finger Down: {finger_pos}")
304
+ # self._left_finger_tap_pos = finger_pos
305
+
306
+ # if tap - self._last_left_tap < DOUBLE_TAP_SPEED:
307
+ # # print("Left Double Tap")
308
+ # self.set_key(K.SELECT)
309
+ # self._last_left_tap = tap
310
+ # # self._left_finger_pos.x = event.x
311
+ # # self._left_finger_pos.y = event.y
312
+
313
+ # # if tap - self._last_left_tap < 0.2:
314
+ # # print("Left Double Tap")
315
+ # # # self._set_key(K.START)
316
+ # # # self._unset_key(K.RIGHT)
317
+ # # # self._unset_key(K.LEFT)
318
+ # # # self._unset_key(K.UP)
319
+ # # # self._unset_key(K.DOWN)
320
+ # else:
321
+ # self._right_finger_tap_pos = finger_pos
322
+
323
+ # # if tap - self._last_right_tap < DOUBLE_TAP_SPEED:
324
+ # # # print("Right Double Tap")
325
+ # # self.set_key(K.SELECT)
326
+ # self._last_right_tap = tap
327
+ # if event.y < 0.3:
328
+ # self.set_key(K.START)
329
+ # elif event.x < 0.75:
330
+ # self.set_key(K.B)
331
+ # else:
332
+ # self.set_key(K.A)
218
333
  # self._right_finger_pos.x = event.x
219
334
  # self._right_finger_pos.y = event.y
220
335
  # if tap - self._last_right_tap < 0.2:
@@ -234,23 +349,23 @@ class PygameUserInput:
234
349
  # print("Left Single Tap")
235
350
  # # self.set_key(K.START)
236
351
 
237
- self.unset_key(K.SELECT)
238
- self.unset_key(K.RIGHT)
239
- self.unset_key(K.LEFT)
240
- self.unset_key(K.UP)
241
- self.unset_key(K.DOWN)
242
- self.unset_key(K.R)
352
+ self.unset_key(K.P1_SELECT)
353
+ self.unset_key(K.P1_RIGHT)
354
+ self.unset_key(K.P1_LEFT)
355
+ self.unset_key(K.P1_UP)
356
+ self.unset_key(K.P1_DOWN)
357
+ self.unset_key(K.P1_L)
243
358
  # print(
244
359
  # f"Left Finger moved {finger_dist} "
245
360
  # f"({release - self._last_left_tap} s)"
246
361
  # )
247
362
  else:
248
- self.unset_key(K.START)
249
- self.unset_key(K.A)
250
- self.unset_key(K.B)
251
- self.unset_key(K.Y)
252
- self.unset_key(K.X)
253
- self.unset_key(K.R)
363
+ self.unset_key(K.P1_START)
364
+ self.unset_key(K.P1_A)
365
+ self.unset_key(K.P1_B)
366
+ self.unset_key(K.P1_Y)
367
+ self.unset_key(K.P1_X)
368
+ self.unset_key(K.P1_R)
254
369
  # print(f"Right Finger Up: {finger_pos}")
255
370
  # if (
256
371
  # SINGLE_TAP_MIN
@@ -284,45 +399,45 @@ class PygameUserInput:
284
399
  if event.type == pygame.FINGERMOTION:
285
400
  if event.x < 0.5:
286
401
  vd = finger_pos - self._left_finger_tap_pos
287
- self.unset_key(K.RIGHT)
288
- self.unset_key(K.LEFT)
289
- self.unset_key(K.UP)
290
- self.unset_key(K.DOWN)
402
+ self.unset_key(K.P1_RIGHT)
403
+ self.unset_key(K.P1_LEFT)
404
+ self.unset_key(K.P1_UP)
405
+ self.unset_key(K.P1_DOWN)
291
406
  if abs(vd.x) > 2 * abs(vd.y):
292
407
  # Horizontal
293
408
  if vd.x > 5.0:
294
- self.set_key(K.RIGHT)
295
- self.unset_key(K.LEFT)
296
- self.unset_key(K.UP)
297
- self.unset_key(K.DOWN)
409
+ self.set_key(K.P1_RIGHT)
410
+ self.unset_key(K.P1_LEFT)
411
+ self.unset_key(K.P1_UP)
412
+ self.unset_key(K.P1_DOWN)
298
413
  elif vd.x < -5.0:
299
- self.set_key(K.LEFT)
300
- self.unset_key(K.RIGHT)
301
- self.unset_key(K.UP)
302
- self.unset_key(K.DOWN)
414
+ self.set_key(K.P1_LEFT)
415
+ self.unset_key(K.P1_RIGHT)
416
+ self.unset_key(K.P1_UP)
417
+ self.unset_key(K.P1_DOWN)
303
418
  elif abs(vd.x) * 2 < abs(vd.y):
304
419
  # Vertical
305
420
  if vd.y > 5.0:
306
- self.unset_key(K.RIGHT)
307
- self.unset_key(K.LEFT)
308
- self.unset_key(K.UP)
309
- self.set_key(K.DOWN)
421
+ self.unset_key(K.P1_RIGHT)
422
+ self.unset_key(K.P1_LEFT)
423
+ self.unset_key(K.P1_UP)
424
+ self.set_key(K.P1_DOWN)
310
425
  elif vd.y < -5.0:
311
- self.unset_key(K.LEFT)
312
- self.unset_key(K.RIGHT)
313
- self.set_key(K.UP)
314
- self.unset_key(K.DOWN)
426
+ self.unset_key(K.P1_LEFT)
427
+ self.unset_key(K.P1_RIGHT)
428
+ self.set_key(K.P1_UP)
429
+ self.unset_key(K.P1_DOWN)
315
430
  elif abs(vd.x) * 1.05 > abs(vd.y) or abs(vd.x) < 1.05 * abs(
316
431
  vd.y
317
432
  ):
318
433
  if vd.x < 0:
319
- self.set_key(K.LEFT)
434
+ self.set_key(K.P1_LEFT)
320
435
  elif vd.x > 0:
321
- self.set_key(K.RIGHT)
436
+ self.set_key(K.P1_RIGHT)
322
437
  if vd.y < 0:
323
- self.set_key(K.UP)
438
+ self.set_key(K.P1_UP)
324
439
  elif vd.y > 0:
325
- self.set_key(K.DOWN)
440
+ self.set_key(K.P1_DOWN)
326
441
  # else:
327
442
  # vd = finger_pos - self._right_finger_tap_pos
328
443
  # self.unset_key(K.A)
@@ -408,11 +523,17 @@ class PygameUserInput:
408
523
  # self._unset_key(K.A)
409
524
  pass
410
525
 
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())
526
+ def _init_joysticks(self):
527
+ for jid in range(pygame.joystick.get_count()):
528
+ js = pygame.joystick.Joystick(jid)
529
+ js.init()
530
+ # p = Player(jid + 1)
531
+ self.joysticks[js.get_id()] = js
532
+ LOG.info(
533
+ "Initialized Joystick #%d: %s",
534
+ jid,
535
+ self.joysticks[js.get_id()].get_name(),
536
+ )
416
537
 
417
538
  def set_key(self, button: K):
418
539
  self._new_keys[button] = True
@@ -420,11 +541,139 @@ class PygameUserInput:
420
541
  def unset_key(self, button: K):
421
542
  self._new_keys[button] = False
422
543
 
423
- def new_key_press(self, button: K):
544
+ def new_key_press(self, button: K, player: Player = Player.P1):
545
+ button = _button_to_player(button, player)
424
546
  return self._new_keys[button] and not self._last_keys[button]
425
547
 
426
- def key_held(self, button: K):
548
+ def key_held(self, button: K, player: Player = Player.P1):
549
+ button = _button_to_player(button, player)
427
550
  return self._new_keys[button]
428
551
 
429
- def new_key_release(self, button: K):
552
+ def new_key_release(self, button: K, player: Player = Player.P1):
553
+ button = _button_to_player(button, player)
430
554
  return self._last_keys[button] and not self._new_keys[button]
555
+
556
+ def get_all_events(self):
557
+ return self._new_events
558
+
559
+ def _collect_keyboard_events(self, event):
560
+ kid = f"kb_{event.key}"
561
+ if event.type == pygame.KEYDOWN:
562
+ self._new_events[kid] = {
563
+ "type": "keyboard",
564
+ "id": event.type,
565
+ "button": event.key,
566
+ "name": pygame.key.name(event.key),
567
+ }
568
+ if event.type == pygame.KEYUP and kid in self._new_events:
569
+ del self._new_events[kid]
570
+
571
+ def _collect_joystick_events(self, event):
572
+ if event.type == pygame.JOYDEVICEREMOVED:
573
+ jid = f"js_{event.instance_id}_removed"
574
+ self._new_events[jid] = {
575
+ "type": "joystick",
576
+ "id": event.instance_id,
577
+ "button": "removed",
578
+ "name": "removed",
579
+ }
580
+ if event.type == pygame.JOYDEVICEADDED:
581
+ jid = f"js_{event.device_index}_added"
582
+ self._new_events[jid] = {
583
+ "type": "joystick",
584
+ "id": event.device_index,
585
+ "button": "added",
586
+ "guid": event.guid,
587
+ }
588
+
589
+ if event.type == pygame.JOYBUTTONDOWN:
590
+ kid = f"js_{event.joy}_{event.button}"
591
+
592
+ self._new_events[kid] = {
593
+ "type": "joystick",
594
+ "id": event.instance_id,
595
+ "joy": event.joy,
596
+ "button": event.button,
597
+ "name": self.joysticks[event.joy].get_name(),
598
+ "power_level": self.joysticks[event.joy].get_power_level(),
599
+ }
600
+ if event.type == pygame.JOYBUTTONUP:
601
+ kid = f"js_{event.joy}_{event.button}"
602
+ if kid in self._new_events:
603
+ del self._new_events[kid]
604
+ if event.type == pygame.JOYHATMOTION:
605
+ kid = f"js_{event.joy}_{event.hat}"
606
+ klid = f"{kid}_left"
607
+ krid = f"{kid}_right"
608
+ kuid = f"{kid}_up"
609
+ kdid = f"{kid}_down"
610
+ if event.value[0] == 0:
611
+ if klid in self._new_events:
612
+ del self._new_events[klid]
613
+ if krid in self._new_events:
614
+ del self._new_events[krid]
615
+ elif event.value[0] == -1:
616
+ self._new_events[klid] = {
617
+ "type": "joystick",
618
+ "id": event.instance_id,
619
+ "joy": event.joy,
620
+ "button": "left",
621
+ "hat": event.hat,
622
+ "value": event.value[0],
623
+ "name": self.joysticks[event.joy].get_name(),
624
+ "power_level": self.joysticks[event.joy].get_power_level(),
625
+ }
626
+ if krid in self._new_events:
627
+ del self._new_events[krid]
628
+ else:
629
+ self._new_events[krid] = {
630
+ "type": "joystick",
631
+ "id": event.instance_id,
632
+ "joy": event.joy,
633
+ "button": "right",
634
+ "hat": event.hat,
635
+ "value": event.value[0],
636
+ "name": self.joysticks[event.joy].get_name(),
637
+ "power_level": self.joysticks[event.joy].get_power_level(),
638
+ }
639
+ if klid in self._new_events:
640
+ del self._new_events[klid]
641
+
642
+ if event.value[1] == 0:
643
+ if kuid in self._new_events:
644
+ del self._new_events[kuid]
645
+ if kdid in self._new_events:
646
+ del self._new_events[kdid]
647
+ elif event.value[1] == 1:
648
+ self._new_events[kuid] = {
649
+ "type": "joystick",
650
+ "id": event.instance_id,
651
+ "joy": event.joy,
652
+ "button": "up",
653
+ "hat": event.hat,
654
+ "value": event.value[1],
655
+ "name": self.joysticks[event.joy].get_name(),
656
+ "power_level": self.joysticks[event.joy].get_power_level(),
657
+ }
658
+ if kdid in self._new_events:
659
+ del self._new_events[kdid]
660
+ else:
661
+ self._new_events[kdid] = {
662
+ "type": "joystick",
663
+ "id": event.instance_id,
664
+ "joy": event.joy,
665
+ "button": "down",
666
+ "hat": event.hat,
667
+ "value": event.value[1],
668
+ "name": self.joysticks[event.joy].get_name(),
669
+ "power_level": self.joysticks[event.joy].get_power_level(),
670
+ }
671
+ if kuid in self._new_events:
672
+ del self._new_events[kuid]
673
+
674
+ def trigger_all_events_collection(self, active: bool = True):
675
+ self._collect_all_events = active
676
+
677
+
678
+ def _button_to_player(button: K, player: Player):
679
+ return K(button.value + 12 * player.value)