mima-engine 0.1.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.
- mima/__init__.py +1 -0
- mima/backend/__init__.py +1 -0
- mima/backend/pygame_assets.py +345 -0
- mima/backend/pygame_audio.py +75 -0
- mima/backend/pygame_backend.py +399 -0
- mima/backend/pygame_events.py +430 -0
- mima/collision.py +237 -0
- mima/engine.py +197 -0
- mima/maps/__init__.py +0 -0
- mima/maps/template.py +41 -0
- mima/maps/tile.py +20 -0
- mima/maps/tile_animation.py +7 -0
- mima/maps/tile_info.py +10 -0
- mima/maps/tile_layer.py +52 -0
- mima/maps/tiled/__init__.py +0 -0
- mima/maps/tiled/tiled_layer.py +48 -0
- mima/maps/tiled/tiled_map.py +95 -0
- mima/maps/tiled/tiled_object.py +79 -0
- mima/maps/tiled/tiled_objectgroup.py +25 -0
- mima/maps/tiled/tiled_template.py +49 -0
- mima/maps/tiled/tiled_tile.py +90 -0
- mima/maps/tiled/tiled_tileset.py +45 -0
- mima/maps/tilemap.py +159 -0
- mima/maps/tileset.py +32 -0
- mima/maps/tileset_info.py +9 -0
- mima/maps/transition_map.py +148 -0
- mima/objects/__init__.py +0 -0
- mima/objects/animated_sprite.py +198 -0
- mima/objects/attribute_effect.py +26 -0
- mima/objects/attributes.py +123 -0
- mima/objects/creature.py +332 -0
- mima/objects/dynamic.py +182 -0
- mima/objects/effects/__init__.py +0 -0
- mima/objects/effects/colorize_screen.py +36 -0
- mima/objects/effects/light.py +107 -0
- mima/objects/effects/walking_on_grass.py +38 -0
- mima/objects/effects/walking_on_water.py +41 -0
- mima/objects/loader.py +103 -0
- mima/objects/projectile.py +86 -0
- mima/objects/sprite.py +110 -0
- mima/objects/world/__init__.py +0 -0
- mima/objects/world/color_gate.py +68 -0
- mima/objects/world/color_switch.py +105 -0
- mima/objects/world/container.py +171 -0
- mima/objects/world/floor_switch.py +111 -0
- mima/objects/world/gate.py +174 -0
- mima/objects/world/light_source.py +124 -0
- mima/objects/world/logic_gate.py +163 -0
- mima/objects/world/movable.py +338 -0
- mima/objects/world/oneway.py +168 -0
- mima/objects/world/pickup.py +88 -0
- mima/objects/world/switch.py +165 -0
- mima/objects/world/teleport.py +288 -0
- mima/scene_engine.py +79 -0
- mima/scripts/__init__.py +2 -0
- mima/scripts/command.py +24 -0
- mima/scripts/commands/__init__.py +0 -0
- mima/scripts/commands/add_quest.py +19 -0
- mima/scripts/commands/change_map.py +15 -0
- mima/scripts/commands/close_dialog.py +8 -0
- mima/scripts/commands/give_item.py +24 -0
- mima/scripts/commands/give_resource.py +51 -0
- mima/scripts/commands/move_map.py +152 -0
- mima/scripts/commands/move_to.py +49 -0
- mima/scripts/commands/oneway_move.py +57 -0
- mima/scripts/commands/parallel.py +53 -0
- mima/scripts/commands/play_sound.py +13 -0
- mima/scripts/commands/present_item.py +51 -0
- mima/scripts/commands/progress_quest.py +12 -0
- mima/scripts/commands/quit_game.py +8 -0
- mima/scripts/commands/save_game.py +13 -0
- mima/scripts/commands/screen_fade.py +65 -0
- mima/scripts/commands/serial.py +46 -0
- mima/scripts/commands/set_facing_direction.py +21 -0
- mima/scripts/commands/set_spawn_map.py +14 -0
- mima/scripts/commands/show_choices.py +43 -0
- mima/scripts/commands/show_dialog.py +11 -0
- mima/scripts/commands/take_coins.py +23 -0
- mima/scripts/script_processor.py +40 -0
- mima/states/__init__.py +0 -0
- mima/states/game_state.py +162 -0
- mima/states/quest.py +72 -0
- mima/types/__init__.py +0 -0
- mima/types/alignment.py +7 -0
- mima/types/blend.py +8 -0
- mima/types/damage.py +42 -0
- mima/types/direction.py +44 -0
- mima/types/gate_color.py +7 -0
- mima/types/graphic_state.py +22 -0
- mima/types/keys.py +16 -0
- mima/types/mode.py +15 -0
- mima/types/nature.py +12 -0
- mima/types/object.py +22 -0
- mima/types/start.py +7 -0
- mima/types/terrain.py +9 -0
- mima/types/weapon_slot.py +6 -0
- mima/usables/__init__.py +0 -0
- mima/usables/item.py +31 -0
- mima/usables/weapon.py +48 -0
- mima/util/__init__.py +1 -0
- mima/util/colors.py +45 -0
- mima/util/constants.py +47 -0
- mima/util/functions.py +13 -0
- mima/util/input_defaults.py +49 -0
- mima/util/logging.py +51 -0
- mima/util/property.py +8 -0
- mima/util/runtime_config.py +133 -0
- mima/view/__init__.py +0 -0
- mima/view/camera.py +51 -0
- mima/view/scene.py +350 -0
- mima_engine-0.1.0.dist-info/METADATA +14 -0
- mima_engine-0.1.0.dist-info/RECORD +114 -0
- mima_engine-0.1.0.dist-info/WHEEL +5 -0
- mima_engine-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from typing import Dict, List, Union
|
|
4
|
+
|
|
5
|
+
import pygame
|
|
6
|
+
|
|
7
|
+
from ..types.keys import Key as K
|
|
8
|
+
from ..util.constants import AXIS_ACTIVATION, AXIS_DEADZONE, DOUBLE_TAP_SPEED
|
|
9
|
+
from ..util.input_defaults import (
|
|
10
|
+
BUTTONS,
|
|
11
|
+
DEFAULT_JOYSTICK_MAP,
|
|
12
|
+
DEFAULT_KEYBOARD_MAP,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
LOG = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
KEYBOARD_EVENTS = [pygame.KEYUP, pygame.KEYDOWN]
|
|
18
|
+
JOYSTICK_EVENTS = [
|
|
19
|
+
pygame.JOYDEVICEADDED,
|
|
20
|
+
pygame.JOYDEVICEREMOVED,
|
|
21
|
+
pygame.JOYBUTTONUP,
|
|
22
|
+
pygame.JOYBUTTONDOWN,
|
|
23
|
+
pygame.JOYAXISMOTION,
|
|
24
|
+
pygame.JOYHATMOTION,
|
|
25
|
+
]
|
|
26
|
+
TOUCH_EVENTS = [pygame.FINGERUP, pygame.FINGERDOWN, pygame.FINGERMOTION]
|
|
27
|
+
SDL2_BACKGROUND_EVENTS = [259, 260, 261, 262]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class PygameUserInput:
|
|
31
|
+
"""A class that manages keys and key events."""
|
|
32
|
+
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
key_map: Dict[K, List[str]] = DEFAULT_KEYBOARD_MAP,
|
|
36
|
+
joystick_map: Dict[K, List[Union[str, int]]] = DEFAULT_JOYSTICK_MAP,
|
|
37
|
+
platform: str = "PC",
|
|
38
|
+
):
|
|
39
|
+
self._last_keys: Dict[K, bool] = {}
|
|
40
|
+
self._new_keys: Dict[K, bool] = {but: False for but in BUTTONS}
|
|
41
|
+
self._left_finger_tap_pos: pygame.Vector2 = pygame.Vector2(0, 0)
|
|
42
|
+
self._right_finger_tap_pos: pygame.Vector2 = pygame.Vector2(0, 0)
|
|
43
|
+
self._left_finger_pos: pygame.Vector2 = pygame.Vector2(0, 0)
|
|
44
|
+
self._right_finger_pos: pygame.Vector2 = pygame.Vector2(0, 0)
|
|
45
|
+
self._last_left_tap: float = 0.0
|
|
46
|
+
self._last_right_tap: float = 0.0
|
|
47
|
+
self._last_left_motion: float = 0.0
|
|
48
|
+
self._last_right_motion: float = 0.0
|
|
49
|
+
self._key_map: Dict[K, int] = {}
|
|
50
|
+
self.vd = pygame.Vector2(0, 0)
|
|
51
|
+
self.joystick_input_enabled: bool = True
|
|
52
|
+
if platform == "android":
|
|
53
|
+
# Disable motion control
|
|
54
|
+
# FIXME allow external controllers
|
|
55
|
+
self.joystick_input_enabled = False
|
|
56
|
+
# self._fingers: List[pygame.Vector2] = []
|
|
57
|
+
|
|
58
|
+
# if key_map is None:
|
|
59
|
+
# self._key_map = dict()
|
|
60
|
+
# for key, vals in RuntimeConfig().keymap.items():
|
|
61
|
+
# self._key_map[key] = list()
|
|
62
|
+
# for val in vals:
|
|
63
|
+
# self._key_map[key].append(getattr(pygame, f"K_{val}"))
|
|
64
|
+
# else:
|
|
65
|
+
for key, vals in key_map.items():
|
|
66
|
+
self._key_map[key] = []
|
|
67
|
+
for val in vals:
|
|
68
|
+
self._key_map[key].append(getattr(pygame, f"K_{val}"))
|
|
69
|
+
|
|
70
|
+
# self._key_map = key_map
|
|
71
|
+
# if joystick_map is None:
|
|
72
|
+
# self._joystick_map = DEFAULT_JOYSTICK_MAP
|
|
73
|
+
# else:
|
|
74
|
+
self._joystick_map = joystick_map
|
|
75
|
+
|
|
76
|
+
self.joystick = None
|
|
77
|
+
self._init_joystick()
|
|
78
|
+
self.width = 0
|
|
79
|
+
self.height = 0
|
|
80
|
+
|
|
81
|
+
def reset(self):
|
|
82
|
+
self._last_keys = self._new_keys.copy()
|
|
83
|
+
|
|
84
|
+
def process(self, event):
|
|
85
|
+
if event.type in KEYBOARD_EVENTS:
|
|
86
|
+
self._handle_keyboard(event)
|
|
87
|
+
|
|
88
|
+
if event.type in JOYSTICK_EVENTS and self.joystick_input_enabled:
|
|
89
|
+
self._handle_joystick(event)
|
|
90
|
+
|
|
91
|
+
if event.type in TOUCH_EVENTS:
|
|
92
|
+
self._handle_touch(event)
|
|
93
|
+
|
|
94
|
+
def _handle_keyboard(self, event):
|
|
95
|
+
if event.type == pygame.KEYDOWN:
|
|
96
|
+
for but, keys in self._key_map.items():
|
|
97
|
+
if event.key in keys:
|
|
98
|
+
self.set_key(but)
|
|
99
|
+
|
|
100
|
+
if event.type == pygame.KEYUP:
|
|
101
|
+
for but, keys in self._key_map.items():
|
|
102
|
+
if event.key in keys:
|
|
103
|
+
self.unset_key(but)
|
|
104
|
+
|
|
105
|
+
def _handle_joystick(self, event):
|
|
106
|
+
if event.type == pygame.JOYDEVICEREMOVED:
|
|
107
|
+
self.joystick = None
|
|
108
|
+
LOG.info("Gamepad unplugged.")
|
|
109
|
+
|
|
110
|
+
if event.type == pygame.JOYDEVICEADDED:
|
|
111
|
+
self._init_joystick()
|
|
112
|
+
LOG.info(
|
|
113
|
+
"Detected new gamepad device %s.", self.joystick.get_name()
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if event.type == pygame.JOYBUTTONDOWN:
|
|
117
|
+
if event.joy != 0:
|
|
118
|
+
return
|
|
119
|
+
for but, keys in self._joystick_map.items():
|
|
120
|
+
if event.button in keys:
|
|
121
|
+
self.set_key(but)
|
|
122
|
+
|
|
123
|
+
if event.type == pygame.JOYBUTTONUP:
|
|
124
|
+
if event.joy != 0:
|
|
125
|
+
return
|
|
126
|
+
for but, keys in self._joystick_map.items():
|
|
127
|
+
if event.button in keys:
|
|
128
|
+
self.unset_key(but)
|
|
129
|
+
if event.type == pygame.JOYHATMOTION:
|
|
130
|
+
if event.joy != 0 or event.hat != 0:
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
if event.value[0] == 0:
|
|
134
|
+
self.unset_key(K.LEFT)
|
|
135
|
+
self.unset_key(K.RIGHT)
|
|
136
|
+
elif event.value[0] == -1:
|
|
137
|
+
self.set_key(K.LEFT)
|
|
138
|
+
self.unset_key(K.RIGHT)
|
|
139
|
+
else:
|
|
140
|
+
self.unset_key(K.LEFT)
|
|
141
|
+
self.set_key(K.RIGHT)
|
|
142
|
+
|
|
143
|
+
if event.value[1] == 0:
|
|
144
|
+
self.unset_key(K.UP)
|
|
145
|
+
self.unset_key(K.DOWN)
|
|
146
|
+
elif event.value[1] == 1:
|
|
147
|
+
self.set_key(K.UP)
|
|
148
|
+
self.unset_key(K.DOWN)
|
|
149
|
+
else:
|
|
150
|
+
self.unset_key(K.UP)
|
|
151
|
+
self.set_key(K.DOWN)
|
|
152
|
+
if event.type == pygame.JOYAXISMOTION:
|
|
153
|
+
if event.joy != 0:
|
|
154
|
+
return
|
|
155
|
+
if event.axis == 0:
|
|
156
|
+
if event.value < -AXIS_ACTIVATION:
|
|
157
|
+
self.set_key(K.LEFT)
|
|
158
|
+
self.unset_key(K.RIGHT)
|
|
159
|
+
elif event.value > AXIS_ACTIVATION:
|
|
160
|
+
self.unset_key(K.LEFT)
|
|
161
|
+
self.set_key(K.RIGHT)
|
|
162
|
+
elif abs(event.value) < AXIS_DEADZONE:
|
|
163
|
+
self.unset_key(K.LEFT)
|
|
164
|
+
self.unset_key(K.RIGHT)
|
|
165
|
+
else:
|
|
166
|
+
pass
|
|
167
|
+
if event.axis == 1:
|
|
168
|
+
if event.value < -AXIS_ACTIVATION:
|
|
169
|
+
self.set_key(K.UP)
|
|
170
|
+
self.unset_key(K.DOWN)
|
|
171
|
+
elif event.value > AXIS_ACTIVATION:
|
|
172
|
+
self.unset_key(K.UP)
|
|
173
|
+
self.set_key(K.DOWN)
|
|
174
|
+
elif abs(event.value) < AXIS_DEADZONE:
|
|
175
|
+
self.unset_key(K.UP)
|
|
176
|
+
self.unset_key(K.DOWN)
|
|
177
|
+
|
|
178
|
+
def _handle_touch(self, event):
|
|
179
|
+
finger_pos = pygame.Vector2(
|
|
180
|
+
event.x * self.width, event.y * self.height
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if event.type == pygame.FINGERDOWN:
|
|
184
|
+
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)
|
|
218
|
+
# self._right_finger_pos.x = event.x
|
|
219
|
+
# self._right_finger_pos.y = event.y
|
|
220
|
+
# if tap - self._last_right_tap < 0.2:
|
|
221
|
+
# print("Right Double Tap")
|
|
222
|
+
|
|
223
|
+
if event.type == pygame.FINGERUP:
|
|
224
|
+
# release = time.time()
|
|
225
|
+
# finger_dist = (finger_pos - self._left_finger_tap_pos).length()
|
|
226
|
+
|
|
227
|
+
if event.x < 0.5:
|
|
228
|
+
# print(f"Left Finger Up: {finger_pos}")
|
|
229
|
+
# if (
|
|
230
|
+
# SINGLE_TAP_MIN
|
|
231
|
+
# < release - self._last_left_tap
|
|
232
|
+
# < SINGLE_TAP_MAX
|
|
233
|
+
# ) and finger_dist < 2.5:
|
|
234
|
+
# print("Left Single Tap")
|
|
235
|
+
# # self.set_key(K.START)
|
|
236
|
+
|
|
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)
|
|
243
|
+
# print(
|
|
244
|
+
# f"Left Finger moved {finger_dist} "
|
|
245
|
+
# f"({release - self._last_left_tap} s)"
|
|
246
|
+
# )
|
|
247
|
+
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)
|
|
254
|
+
# print(f"Right Finger Up: {finger_pos}")
|
|
255
|
+
# if (
|
|
256
|
+
# SINGLE_TAP_MIN
|
|
257
|
+
# < release - self._last_right_tap
|
|
258
|
+
# < SINGLE_TAP_MAX
|
|
259
|
+
# ) and finger_dist < 2.5:
|
|
260
|
+
# print("Right Single Tap")
|
|
261
|
+
|
|
262
|
+
# print(
|
|
263
|
+
# f"Left Finger moved {finger_dist} "
|
|
264
|
+
# f"({release - self._last_left_tap} s)"
|
|
265
|
+
# )
|
|
266
|
+
#
|
|
267
|
+
# if event.x < 0.5:
|
|
268
|
+
# if 0.1 < release - self._last_left_tap < 0.25:
|
|
269
|
+
# print("Left Single Tap")
|
|
270
|
+
|
|
271
|
+
# self._left_finger_pos.x = 0
|
|
272
|
+
# self._left_finger_pos.y = 0
|
|
273
|
+
# self._unset_key(K.DOWN)
|
|
274
|
+
# self._unset_key(K.LEFT)
|
|
275
|
+
# self._unset_key(K.UP)
|
|
276
|
+
# self._unset_key(K.RIGHT)
|
|
277
|
+
# self._unset_key(K.START)
|
|
278
|
+
# else:
|
|
279
|
+
# if 0.1 < release - self._last_right_tap < 0.25:
|
|
280
|
+
# print("Right Single Tap")
|
|
281
|
+
|
|
282
|
+
# self._unset_key(K.A)
|
|
283
|
+
# self._unset_key(K.B)
|
|
284
|
+
if event.type == pygame.FINGERMOTION:
|
|
285
|
+
if event.x < 0.5:
|
|
286
|
+
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)
|
|
291
|
+
if abs(vd.x) > 2 * abs(vd.y):
|
|
292
|
+
# Horizontal
|
|
293
|
+
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)
|
|
298
|
+
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)
|
|
303
|
+
elif abs(vd.x) * 2 < abs(vd.y):
|
|
304
|
+
# Vertical
|
|
305
|
+
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)
|
|
310
|
+
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)
|
|
315
|
+
elif abs(vd.x) * 1.05 > abs(vd.y) or abs(vd.x) < 1.05 * abs(
|
|
316
|
+
vd.y
|
|
317
|
+
):
|
|
318
|
+
if vd.x < 0:
|
|
319
|
+
self.set_key(K.LEFT)
|
|
320
|
+
elif vd.x > 0:
|
|
321
|
+
self.set_key(K.RIGHT)
|
|
322
|
+
if vd.y < 0:
|
|
323
|
+
self.set_key(K.UP)
|
|
324
|
+
elif vd.y > 0:
|
|
325
|
+
self.set_key(K.DOWN)
|
|
326
|
+
# else:
|
|
327
|
+
# vd = finger_pos - self._right_finger_tap_pos
|
|
328
|
+
# self.unset_key(K.A)
|
|
329
|
+
# self.unset_key(K.B)
|
|
330
|
+
# self.unset_key(K.Y)
|
|
331
|
+
# self.unset_key(K.X)
|
|
332
|
+
# if abs(vd.x) > 2 * abs(vd.y):
|
|
333
|
+
# # Horizontal
|
|
334
|
+
# if vd.x > 5.0:
|
|
335
|
+
# self.set_key(K.Y)
|
|
336
|
+
# elif vd.x < -5.0:
|
|
337
|
+
# self.set_key(K.B)
|
|
338
|
+
# elif abs(vd.x) * 2 < abs(vd.y):
|
|
339
|
+
# # Vertical
|
|
340
|
+
# if vd.y > 5.0:
|
|
341
|
+
# self.set_key(K.A)
|
|
342
|
+
# elif vd.y < -5.0:
|
|
343
|
+
# self.set_key(K.X)
|
|
344
|
+
|
|
345
|
+
self.vd = vd
|
|
346
|
+
|
|
347
|
+
def _handle_mouse(self, event):
|
|
348
|
+
# if event.type == pygame.MOUSEBUTTONDOWN:
|
|
349
|
+
# if 0 <= event.pos[0] < 16 and 80 <= event.pos[1] < 96:
|
|
350
|
+
# self._unset_key(K.RIGHT)
|
|
351
|
+
# self._set_key(K.LEFT)
|
|
352
|
+
# self._unset_key(K.UP)
|
|
353
|
+
# self._unset_key(K.DOWN)
|
|
354
|
+
# elif 0 <= event.pos[0] < 16 and 64 <= event.pos[1] < 80:
|
|
355
|
+
# self._unset_key(K.RIGHT)
|
|
356
|
+
# self._set_key(K.LEFT)
|
|
357
|
+
# self._set_key(K.UP)
|
|
358
|
+
# self._unset_key(K.DOWN)
|
|
359
|
+
# elif 16 <= event.pos[0] < 32 and 64 <= event.pos[1] < 80:
|
|
360
|
+
# self._unset_key(K.RIGHT)
|
|
361
|
+
# self._unset_key(K.LEFT)
|
|
362
|
+
# self._set_key(K.UP)
|
|
363
|
+
# self._unset_key(K.DOWN)
|
|
364
|
+
# elif 32 <= event.pos[0] < 48 and 64 <= event.pos[1] < 80:
|
|
365
|
+
# self._set_key(K.RIGHT)
|
|
366
|
+
# self._unset_key(K.LEFT)
|
|
367
|
+
# self._set_key(K.UP)
|
|
368
|
+
# self._unset_key(K.DOWN)
|
|
369
|
+
# elif 32 <= event.pos[0] < 48 and 80 <= event.pos[1] < 96:
|
|
370
|
+
# self._set_key(K.RIGHT)
|
|
371
|
+
# self._unset_key(K.LEFT)
|
|
372
|
+
# self._unset_key(K.UP)
|
|
373
|
+
# self._unset_key(K.DOWN)
|
|
374
|
+
# elif 32 <= event.pos[0] < 48 and 96 <= event.pos[1] < 112:
|
|
375
|
+
# self._set_key(K.RIGHT)
|
|
376
|
+
# self._unset_key(K.LEFT)
|
|
377
|
+
# self._unset_key(K.UP)
|
|
378
|
+
# self._set_key(K.DOWN)
|
|
379
|
+
# elif 16 <= event.pos[0] < 32 and 96 <= event.pos[1] < 112:
|
|
380
|
+
# self._unset_key(K.RIGHT)
|
|
381
|
+
# self._unset_key(K.LEFT)
|
|
382
|
+
# self._unset_key(K.UP)
|
|
383
|
+
# self._set_key(K.DOWN)
|
|
384
|
+
# elif 0 <= event.pos[0] < 16 and 96 <= event.pos[1] < 112:
|
|
385
|
+
# self._unset_key(K.RIGHT)
|
|
386
|
+
# self._set_key(K.LEFT)
|
|
387
|
+
# self._unset_key(K.UP)
|
|
388
|
+
# self._set_key(K.DOWN)
|
|
389
|
+
# if 112 <= event.pos[0] < 144 and 0 <= event.pos[1] < 32:
|
|
390
|
+
# self._set_key(K.START)
|
|
391
|
+
# self._unset_key(K.RIGHT)
|
|
392
|
+
# self._unset_key(K.LEFT)
|
|
393
|
+
# self._unset_key(K.UP)
|
|
394
|
+
# self._unset_key(K.DOWN)
|
|
395
|
+
# if 240 <= event.pos[0] < 256 and 80 <= event.pos[1] < 112:
|
|
396
|
+
# self._set_key(K.A)
|
|
397
|
+
# self._unset_key(K.RIGHT)
|
|
398
|
+
# self._unset_key(K.LEFT)
|
|
399
|
+
# self._unset_key(K.UP)
|
|
400
|
+
# self._unset_key(K.DOWN)
|
|
401
|
+
|
|
402
|
+
# if event.type == pygame.MOUSEBUTTONUP:
|
|
403
|
+
# self._unset_key(K.DOWN)
|
|
404
|
+
# self._unset_key(K.LEFT)
|
|
405
|
+
# self._unset_key(K.UP)
|
|
406
|
+
# self._unset_key(K.RIGHT)
|
|
407
|
+
# self._unset_key(K.START)
|
|
408
|
+
# self._unset_key(K.A)
|
|
409
|
+
pass
|
|
410
|
+
|
|
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())
|
|
416
|
+
|
|
417
|
+
def set_key(self, button: K):
|
|
418
|
+
self._new_keys[button] = True
|
|
419
|
+
|
|
420
|
+
def unset_key(self, button: K):
|
|
421
|
+
self._new_keys[button] = False
|
|
422
|
+
|
|
423
|
+
def new_key_press(self, button: K):
|
|
424
|
+
return self._new_keys[button] and not self._last_keys[button]
|
|
425
|
+
|
|
426
|
+
def key_held(self, button: K):
|
|
427
|
+
return self._new_keys[button]
|
|
428
|
+
|
|
429
|
+
def new_key_release(self, button: K):
|
|
430
|
+
return self._last_keys[button] and not self._new_keys[button]
|
mima/collision.py
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Tuple
|
|
4
|
+
|
|
5
|
+
from .maps.tilemap import Tilemap
|
|
6
|
+
from .objects.dynamic import Dynamic
|
|
7
|
+
from .types.direction import Direction
|
|
8
|
+
from .types.graphic_state import GraphicState, Until
|
|
9
|
+
from .types.nature import Nature
|
|
10
|
+
from .types.object import ObjectType
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from .engine import MimaEngine
|
|
14
|
+
from .view.scene import Scene
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def check_object_to_map_collision(
|
|
18
|
+
elapsed_time: float,
|
|
19
|
+
obj: Dynamic,
|
|
20
|
+
tilemap: Tilemap,
|
|
21
|
+
new_px: float,
|
|
22
|
+
new_py: float,
|
|
23
|
+
) -> Tuple[float, float]:
|
|
24
|
+
|
|
25
|
+
left = new_px + obj.hitbox_px
|
|
26
|
+
right = left + obj.hitbox_width
|
|
27
|
+
top = obj.py + obj.hitbox_py
|
|
28
|
+
bottom = top + obj.hitbox_height
|
|
29
|
+
|
|
30
|
+
collided_with_map = False
|
|
31
|
+
if obj.solid_vs_map:
|
|
32
|
+
if collision_with_map(tilemap, left, right, top, bottom):
|
|
33
|
+
# On rare occasions, the object might be pushed towards
|
|
34
|
+
# the wall, i.e. old and new pos are equal
|
|
35
|
+
# Decide depending on the decimal part of the position
|
|
36
|
+
# where to push the object
|
|
37
|
+
if new_px == obj.px:
|
|
38
|
+
decimal_dif = new_px - int(new_px)
|
|
39
|
+
if abs(decimal_dif) > 0.5:
|
|
40
|
+
new_px += 0.0001
|
|
41
|
+
else:
|
|
42
|
+
new_px -= 0.0001
|
|
43
|
+
|
|
44
|
+
# Did the object move from right to left?
|
|
45
|
+
if new_px < obj.px:
|
|
46
|
+
new_px += int(left) + 1.0 - left
|
|
47
|
+
else:
|
|
48
|
+
new_px -= right - int(right) + 0.001
|
|
49
|
+
|
|
50
|
+
obj.vx = 0
|
|
51
|
+
collided_with_map = True
|
|
52
|
+
if (
|
|
53
|
+
obj.facing_direction
|
|
54
|
+
in [
|
|
55
|
+
Direction.WEST,
|
|
56
|
+
Direction.EAST,
|
|
57
|
+
]
|
|
58
|
+
and obj.can_push
|
|
59
|
+
):
|
|
60
|
+
obj.lock_graphic_state(GraphicState.PUSHING, Until.NEXT_UPDATE)
|
|
61
|
+
|
|
62
|
+
left = new_px + obj.hitbox_px
|
|
63
|
+
right = left + obj.hitbox_width
|
|
64
|
+
top = new_py + obj.hitbox_py
|
|
65
|
+
bottom = top + obj.hitbox_height
|
|
66
|
+
|
|
67
|
+
if collision_with_map(tilemap, left, right, top, bottom):
|
|
68
|
+
# See comment above
|
|
69
|
+
if new_py == obj.py:
|
|
70
|
+
decimal_dif = new_py - int(new_py)
|
|
71
|
+
if abs(decimal_dif) > 0.5:
|
|
72
|
+
new_py += 0.0001
|
|
73
|
+
else:
|
|
74
|
+
new_py -= 0.0001
|
|
75
|
+
|
|
76
|
+
if new_py < obj.py:
|
|
77
|
+
new_py += int(top) + 1.0 - top
|
|
78
|
+
else:
|
|
79
|
+
new_py -= bottom - int(bottom) + 0.001
|
|
80
|
+
|
|
81
|
+
obj.vy = 0
|
|
82
|
+
collided_with_map = True
|
|
83
|
+
if (
|
|
84
|
+
obj.facing_direction
|
|
85
|
+
in [
|
|
86
|
+
Direction.NORTH,
|
|
87
|
+
Direction.SOUTH,
|
|
88
|
+
]
|
|
89
|
+
and obj.can_push
|
|
90
|
+
):
|
|
91
|
+
obj.lock_graphic_state(GraphicState.PUSHING, Until.NEXT_UPDATE)
|
|
92
|
+
|
|
93
|
+
if obj.type == ObjectType.PROJECTILE and collided_with_map:
|
|
94
|
+
obj.kill()
|
|
95
|
+
|
|
96
|
+
return new_px, new_py
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def collision_with_map(
|
|
100
|
+
tilemap: Tilemap,
|
|
101
|
+
left: float,
|
|
102
|
+
right: float,
|
|
103
|
+
top: float,
|
|
104
|
+
bottom: float,
|
|
105
|
+
layer: int = 0,
|
|
106
|
+
) -> bool:
|
|
107
|
+
if tilemap.is_solid(left, top, layer):
|
|
108
|
+
return True
|
|
109
|
+
if tilemap.is_solid(left, bottom, layer):
|
|
110
|
+
return True
|
|
111
|
+
if tilemap.is_solid(right, top, layer):
|
|
112
|
+
return True
|
|
113
|
+
if tilemap.is_solid(right, bottom, layer):
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def check_object_to_object_collision(
|
|
120
|
+
engine: MimaEngine,
|
|
121
|
+
scene: Scene,
|
|
122
|
+
obj: Dynamic,
|
|
123
|
+
new_px: float,
|
|
124
|
+
new_py: float,
|
|
125
|
+
other: Dynamic,
|
|
126
|
+
) -> Tuple[float, float]:
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
obj_left = new_px + obj.hitbox_px
|
|
130
|
+
obj_right = obj_left + obj.hitbox_width
|
|
131
|
+
obj_top = obj.py + obj.hitbox_py
|
|
132
|
+
obj_bottom = obj_top + obj.hitbox_height
|
|
133
|
+
|
|
134
|
+
other_left = other.px + other.hitbox_px
|
|
135
|
+
other_right = other_left + other.hitbox_width
|
|
136
|
+
other_top = other.py + other.hitbox_py
|
|
137
|
+
other_bottom = other_top + other.hitbox_height
|
|
138
|
+
|
|
139
|
+
if obj.solid_vs_dyn and other.solid_vs_dyn:
|
|
140
|
+
collided_with_dyn = False
|
|
141
|
+
if collision_with_dyn(
|
|
142
|
+
obj_left,
|
|
143
|
+
obj_right,
|
|
144
|
+
obj_top,
|
|
145
|
+
obj_bottom,
|
|
146
|
+
other_left,
|
|
147
|
+
other_right,
|
|
148
|
+
other_top,
|
|
149
|
+
other_bottom,
|
|
150
|
+
):
|
|
151
|
+
collided_with_dyn = True
|
|
152
|
+
if obj_left < other_left:
|
|
153
|
+
new_px -= obj_right - other_left + 0.001
|
|
154
|
+
else:
|
|
155
|
+
new_px += other_right - obj_left + 0.001
|
|
156
|
+
|
|
157
|
+
obj_left = new_px + obj.hitbox_px
|
|
158
|
+
obj_right = obj_left + obj.hitbox_width
|
|
159
|
+
obj_top = new_py + obj.hitbox_py
|
|
160
|
+
obj_bottom = obj_top + obj.hitbox_height
|
|
161
|
+
|
|
162
|
+
if collision_with_dyn(
|
|
163
|
+
obj_left,
|
|
164
|
+
obj_right,
|
|
165
|
+
obj_top,
|
|
166
|
+
obj_bottom,
|
|
167
|
+
other_left,
|
|
168
|
+
other_right,
|
|
169
|
+
other_top,
|
|
170
|
+
other_bottom,
|
|
171
|
+
):
|
|
172
|
+
collided_with_dyn = True
|
|
173
|
+
if obj_top < other_top:
|
|
174
|
+
new_py -= obj_bottom - other_top + 0.001
|
|
175
|
+
else:
|
|
176
|
+
new_py += other_bottom - obj_top + 0.001
|
|
177
|
+
|
|
178
|
+
if collided_with_dyn:
|
|
179
|
+
other.on_interaction(obj, Nature.WALK)
|
|
180
|
+
|
|
181
|
+
else:
|
|
182
|
+
if obj.type == ObjectType.PLAYER:
|
|
183
|
+
if collision_with_dyn(
|
|
184
|
+
obj_left,
|
|
185
|
+
obj_right,
|
|
186
|
+
obj_top,
|
|
187
|
+
obj_bottom,
|
|
188
|
+
other_left,
|
|
189
|
+
other_right,
|
|
190
|
+
other_top,
|
|
191
|
+
other_bottom,
|
|
192
|
+
):
|
|
193
|
+
for quest in engine.quests:
|
|
194
|
+
if quest.on_interaction(
|
|
195
|
+
scene.dynamics, other, Nature.WALK
|
|
196
|
+
):
|
|
197
|
+
break
|
|
198
|
+
scene.tilemap.on_interaction(other, Nature.WALK)
|
|
199
|
+
other.on_interaction(obj, Nature.WALK)
|
|
200
|
+
else:
|
|
201
|
+
if collision_with_dyn(
|
|
202
|
+
obj_left,
|
|
203
|
+
obj_right,
|
|
204
|
+
obj_top,
|
|
205
|
+
obj_bottom,
|
|
206
|
+
other_left,
|
|
207
|
+
other_right,
|
|
208
|
+
other_top,
|
|
209
|
+
other_bottom,
|
|
210
|
+
):
|
|
211
|
+
if obj.type == ObjectType.PROJECTILE:
|
|
212
|
+
if other.alignment != obj.alignment:
|
|
213
|
+
# We know object is a projectile
|
|
214
|
+
if other.attackable and not other.invincible:
|
|
215
|
+
scene.deal_damage(obj, other)
|
|
216
|
+
else:
|
|
217
|
+
other.on_interaction(obj, Nature.WALK)
|
|
218
|
+
else:
|
|
219
|
+
other.on_interaction(obj, Nature.WALK)
|
|
220
|
+
|
|
221
|
+
return new_px, new_py
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def collision_with_dyn(
|
|
225
|
+
left1: float,
|
|
226
|
+
right1: float,
|
|
227
|
+
top1: float,
|
|
228
|
+
bottom1: float,
|
|
229
|
+
left2: float,
|
|
230
|
+
right2: float,
|
|
231
|
+
top2: float,
|
|
232
|
+
bottom2: float,
|
|
233
|
+
) -> bool:
|
|
234
|
+
if left1 < right2 and right1 > left2 and top1 < bottom2 and bottom1 > top2:
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
return False
|