mima-engine 0.2.3__py3-none-any.whl → 0.2.4__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 -1
- mima/backend/pygame_events.py +210 -194
- mima/backend/touch_control_scheme_a.py +126 -0
- mima/backend/touch_control_scheme_b.py +132 -0
- mima/core/collision.py +46 -23
- mima/core/engine.py +25 -13
- mima/core/mode_engine.py +7 -2
- mima/objects/creature.py +6 -0
- mima/objects/effects/debug_box.py +11 -2
- mima/objects/world/container.py +1 -1
- mima/objects/world/oneway.py +34 -8
- mima/objects/world/pickup.py +8 -2
- mima/objects/world/switch.py +20 -4
- mima/scripts/commands/oneway_move.py +4 -3
- mima/util/constants.py +3 -3
- mima/util/input_defaults.py +12 -0
- mima/view/mima_mode.py +60 -19
- mima/view/mima_scene.py +6 -0
- mima/view/mima_window.py +91 -0
- {mima_engine-0.2.3.dist-info → mima_engine-0.2.4.dist-info}/METADATA +2 -2
- {mima_engine-0.2.3.dist-info → mima_engine-0.2.4.dist-info}/RECORD +23 -21
- {mima_engine-0.2.3.dist-info → mima_engine-0.2.4.dist-info}/WHEEL +1 -1
- {mima_engine-0.2.3.dist-info → mima_engine-0.2.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
import pygame
|
|
4
|
+
|
|
5
|
+
from ..types.keys import Key as K
|
|
6
|
+
from ..util.constants import DOUBLE_TAP_SPEED
|
|
7
|
+
from ..util.input_defaults import ALT_TOUCHSCREEN_MAP, BUTTONS
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TouchControlSchemeB:
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
|
|
14
|
+
self.move_start_pos = pygame.Vector2()
|
|
15
|
+
self.move_pos = pygame.Vector2()
|
|
16
|
+
self.move_sy = 0.0
|
|
17
|
+
self.move_px = 0.0
|
|
18
|
+
self.move_py = 0.0
|
|
19
|
+
self._left_finger_tap_pos = 0.0
|
|
20
|
+
self._right_finger_tap_pos = 0.0
|
|
21
|
+
|
|
22
|
+
self._last_left_tap = 0.0
|
|
23
|
+
self._last_right_tap = 0.0
|
|
24
|
+
self._keys_active = {k: False for k in K}
|
|
25
|
+
self._state = {}
|
|
26
|
+
for key, conf in ALT_TOUCHSCREEN_MAP.items():
|
|
27
|
+
px, py = conf["pos"]
|
|
28
|
+
w, h = conf["size"]
|
|
29
|
+
self._state[key] = {
|
|
30
|
+
"rpx": px,
|
|
31
|
+
"rpy": py,
|
|
32
|
+
"rwidth": w,
|
|
33
|
+
"rheight": h,
|
|
34
|
+
"active": False,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
def handle_touch(self, event, width=1.0, height=1.0):
|
|
38
|
+
set_keys = []
|
|
39
|
+
unset_keys = []
|
|
40
|
+
|
|
41
|
+
tap_pos = pygame.Vector2(event.x * width, event.y * height)
|
|
42
|
+
keys_active = {k: False for k in K}
|
|
43
|
+
# print(f"{event.x:.2f}, {event.y:.2f}", end="")
|
|
44
|
+
for key, conf in ALT_TOUCHSCREEN_MAP.items():
|
|
45
|
+
px, py = conf["pos"]
|
|
46
|
+
w, h = conf["size"]
|
|
47
|
+
area = [[px, py], [px + w, py + h]]
|
|
48
|
+
|
|
49
|
+
if (
|
|
50
|
+
area[0][0] <= event.x < area[1][0]
|
|
51
|
+
and area[0][1] <= event.y < area[1][1]
|
|
52
|
+
):
|
|
53
|
+
if key == K.P1_UP:
|
|
54
|
+
if event.type == pygame.FINGERDOWN:
|
|
55
|
+
self.move_start_pos = pygame.Vector2(tap_pos)
|
|
56
|
+
self.move_pos = pygame.Vector2(tap_pos)
|
|
57
|
+
self._state[key]["rsx"] = event.x
|
|
58
|
+
self._state[key]["rsy"] = event.y
|
|
59
|
+
self._state[key]["rpx"] = event.x
|
|
60
|
+
self._state[key]["rpy"] = event.y
|
|
61
|
+
elif event.type == pygame.FINGERMOTION:
|
|
62
|
+
self.move_pos = tap_pos
|
|
63
|
+
self._state[key]["rpx"] = event.x
|
|
64
|
+
self._state[key]["rpy"] = event.y
|
|
65
|
+
|
|
66
|
+
vd = self.move_pos - self.move_start_pos
|
|
67
|
+
if abs(vd.x) > 2 * abs(vd.y):
|
|
68
|
+
# Horizontal
|
|
69
|
+
if vd.x > 5.0:
|
|
70
|
+
keys_active[K.P1_RIGHT] = True
|
|
71
|
+
# print("..>", end="")
|
|
72
|
+
elif vd.x < -5.0:
|
|
73
|
+
keys_active[K.P1_LEFT] = True
|
|
74
|
+
# print("..<", end="")
|
|
75
|
+
elif abs(vd.x) * 2 < abs(vd.y):
|
|
76
|
+
# Vertical
|
|
77
|
+
if vd.y > 5.0:
|
|
78
|
+
keys_active[K.P1_DOWN] = True
|
|
79
|
+
# print("..v", end="")
|
|
80
|
+
elif vd.y < -5.0:
|
|
81
|
+
keys_active[K.P1_UP] = True
|
|
82
|
+
# print("..^", end="")
|
|
83
|
+
elif abs(vd.x) * 1.05 > abs(vd.y) or abs(
|
|
84
|
+
vd.x
|
|
85
|
+
) < 1.05 * abs(vd.y):
|
|
86
|
+
# Diagonal
|
|
87
|
+
if vd.x < 0:
|
|
88
|
+
keys_active[K.P1_LEFT] = True
|
|
89
|
+
# print("..<", end="")
|
|
90
|
+
elif vd.x > 0:
|
|
91
|
+
keys_active[K.P1_RIGHT] = True
|
|
92
|
+
# print("..>", end="")
|
|
93
|
+
if vd.y < 0:
|
|
94
|
+
keys_active[K.P1_UP] = True
|
|
95
|
+
# print("..^", end="")
|
|
96
|
+
elif vd.y > 0:
|
|
97
|
+
keys_active[K.P1_DOWN] = True
|
|
98
|
+
# print("..v", end="")
|
|
99
|
+
# elif event.type == pygame.FINGERUP:
|
|
100
|
+
# unset_keys.append(K.P1_RIGHT)
|
|
101
|
+
# unset_keys.append(K.P1_LEFT)
|
|
102
|
+
# unset_keys.append(K.P1_UP)
|
|
103
|
+
# unset_keys.append(K.P1_DOWN)
|
|
104
|
+
else:
|
|
105
|
+
if event.type == pygame.FINGERDOWN:
|
|
106
|
+
keys_active[key] = True
|
|
107
|
+
# print(f"..{key.name}", end="")
|
|
108
|
+
if event.type == pygame.FINGERMOTION:
|
|
109
|
+
keys_active[key] = True
|
|
110
|
+
# print(f"..{key.name}", end="")
|
|
111
|
+
# print()
|
|
112
|
+
for k, val in keys_active.items():
|
|
113
|
+
if val:
|
|
114
|
+
set_keys.append(k)
|
|
115
|
+
# self._state.setdefault(k, {})["active"] = True
|
|
116
|
+
if k in self._state:
|
|
117
|
+
self._state[k]["active"] = True
|
|
118
|
+
if k in [K.P1_LEFT, K.P1_RIGHT, K.P1_DOWN]:
|
|
119
|
+
self._state[K.P1_UP]["active"] = True
|
|
120
|
+
else:
|
|
121
|
+
unset_keys.append(k)
|
|
122
|
+
if k in self._state:
|
|
123
|
+
self._state[k]["active"] = False
|
|
124
|
+
return set_keys, unset_keys
|
|
125
|
+
|
|
126
|
+
def get_touch_state(self):
|
|
127
|
+
state = {}
|
|
128
|
+
for key, conf in self._state.items():
|
|
129
|
+
nkey = K(key.value - 12)
|
|
130
|
+
state[nkey] = conf
|
|
131
|
+
|
|
132
|
+
return state
|
mima/core/collision.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import math
|
|
4
|
+
from itertools import product
|
|
4
5
|
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
|
|
5
6
|
|
|
6
7
|
from ..maps.tilemap import Tilemap
|
|
@@ -35,7 +36,9 @@ def check_object_to_map_collision(
|
|
|
35
36
|
|
|
36
37
|
collided_with_map = False
|
|
37
38
|
if obj.solid_vs_map:
|
|
38
|
-
if collision_with_map(
|
|
39
|
+
if collision_with_map(
|
|
40
|
+
tilemap, left, right, top, bottom, layer, collision
|
|
41
|
+
):
|
|
39
42
|
# On rare occasions, the object might be pushed towards
|
|
40
43
|
# the wall, i.e. old and new pos are equal
|
|
41
44
|
# Decide depending on the decimal part of the position
|
|
@@ -66,7 +69,9 @@ def check_object_to_map_collision(
|
|
|
66
69
|
top = new_py + obj.hitbox_py
|
|
67
70
|
bottom = top + obj.hitbox_height
|
|
68
71
|
|
|
69
|
-
if collision_with_map(
|
|
72
|
+
if collision_with_map(
|
|
73
|
+
tilemap, left, right, top, bottom, layer, collision
|
|
74
|
+
):
|
|
70
75
|
# See comment above
|
|
71
76
|
if new_py == obj.py:
|
|
72
77
|
decimal_dif = new_py - int(new_py)
|
|
@@ -244,34 +249,50 @@ def add_to_collision_chunk(
|
|
|
244
249
|
# collision_chunks[chidx].insert(0, obj)
|
|
245
250
|
# else:
|
|
246
251
|
# collision_chunks[chidx].append(obj)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
collision_chunks, obj, obj.px, obj.py + 1, chunk_size, chunks_per_row
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
chunk_ids.append(chid)
|
|
260
|
-
if chid != chid_right:
|
|
261
|
-
chunk_ids.append(chid_right)
|
|
262
|
-
if chid != chid_bottom:
|
|
263
|
-
chunk_ids.append(chid_bottom)
|
|
264
|
-
if chid != chid_right and chid != chid_bottom:
|
|
252
|
+
centerx = obj.px + (obj.hitbox_px + obj.hitbox_width) / 2
|
|
253
|
+
centery = obj.py + (obj.hitbox_py + obj.hitbox_height) / 2
|
|
254
|
+
# chid = _test_chunk_position(
|
|
255
|
+
# collision_chunks, obj, centerx, centery, chunk_size, chunks_per_row
|
|
256
|
+
# )
|
|
257
|
+
offsets = [[0, 0]] + [
|
|
258
|
+
list(p) for p in product([-1, 0, 1], repeat=2) if p != (0, 0)
|
|
259
|
+
]
|
|
260
|
+
for x, y in offsets:
|
|
265
261
|
chunk_ids.append(
|
|
266
262
|
_test_chunk_position(
|
|
267
263
|
collision_chunks,
|
|
268
264
|
obj,
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
centerx + x,
|
|
266
|
+
centery + y,
|
|
271
267
|
chunk_size,
|
|
272
268
|
chunks_per_row,
|
|
273
269
|
)
|
|
274
270
|
)
|
|
271
|
+
chunk_ids = list(dict.fromkeys(chunk_ids))
|
|
272
|
+
# chid_right = _test_chunk_position(
|
|
273
|
+
# collision_chunks, obj, obj.px + 1, obj.py, chunk_size, chunks_per_row
|
|
274
|
+
# )
|
|
275
|
+
|
|
276
|
+
# chid_bottom = _test_chunk_position(
|
|
277
|
+
# collision_chunks, obj, obj.px, obj.py + 1, chunk_size, chunks_per_row
|
|
278
|
+
# )
|
|
279
|
+
|
|
280
|
+
# chunk_ids.append(chid)
|
|
281
|
+
# if chid != chid_right:
|
|
282
|
+
# chunk_ids.append(chid_right)
|
|
283
|
+
# if chid != chid_bottom:
|
|
284
|
+
# chunk_ids.append(chid_bottom)
|
|
285
|
+
# if chid != chid_right and chid != chid_bottom:
|
|
286
|
+
# chunk_ids.append(
|
|
287
|
+
# _test_chunk_position(
|
|
288
|
+
# collision_chunks,
|
|
289
|
+
# obj,
|
|
290
|
+
# obj.px + 1,
|
|
291
|
+
# obj.py + 1,
|
|
292
|
+
# chunk_size,
|
|
293
|
+
# chunks_per_row,
|
|
294
|
+
# )
|
|
295
|
+
# )
|
|
275
296
|
|
|
276
297
|
for chid in obj.chunks:
|
|
277
298
|
if (
|
|
@@ -283,7 +304,9 @@ def add_to_collision_chunk(
|
|
|
283
304
|
return chunk_ids
|
|
284
305
|
|
|
285
306
|
|
|
286
|
-
def _test_chunk_position(
|
|
307
|
+
def _test_chunk_position(
|
|
308
|
+
collision_chunks, obj, px, py, chunk_size, chunks_per_row
|
|
309
|
+
):
|
|
287
310
|
chidx = _chunk_index(px, py, chunk_size, chunks_per_row)
|
|
288
311
|
collision_chunks.setdefault(chidx, [])
|
|
289
312
|
|
mima/core/engine.py
CHANGED
|
@@ -26,13 +26,9 @@ from ..usables.weapon import Weapon
|
|
|
26
26
|
from ..util import RuntimeConfig
|
|
27
27
|
from ..util.logging import install_trace_logger
|
|
28
28
|
from ..view.camera import Camera
|
|
29
|
-
|
|
30
|
-
# from .view.game_mode import GameMode
|
|
31
29
|
from ..view.mima_view import MimaView
|
|
32
30
|
from .database import Database
|
|
33
31
|
|
|
34
|
-
# from .view.scene import Scene
|
|
35
|
-
|
|
36
32
|
if TYPE_CHECKING:
|
|
37
33
|
from .states.game_state import GameState
|
|
38
34
|
|
|
@@ -51,7 +47,9 @@ class MimaEngine(ABC):
|
|
|
51
47
|
self.rtc = RuntimeConfig(config_path, default_config)
|
|
52
48
|
install_trace_logger()
|
|
53
49
|
|
|
54
|
-
self.backend: PygameBackend = PygameBackend(
|
|
50
|
+
self.backend: PygameBackend = PygameBackend(
|
|
51
|
+
self.rtc, init_file, platform
|
|
52
|
+
)
|
|
55
53
|
self.db: Database
|
|
56
54
|
self._caption: str = caption
|
|
57
55
|
self.seconds_total: float = 0.0
|
|
@@ -60,6 +58,9 @@ class MimaEngine(ABC):
|
|
|
60
58
|
self.elapsed_time: float = 0.00022
|
|
61
59
|
self._app_time: float = 0.0
|
|
62
60
|
|
|
61
|
+
self.enable_touch_controls: bool = False
|
|
62
|
+
self.show_touch_controls: bool = False
|
|
63
|
+
|
|
63
64
|
self.mode: Mode = Mode.LOADING
|
|
64
65
|
self.gate_color: GateColor = GateColor.RED
|
|
65
66
|
self.n_gate_colors = 2
|
|
@@ -67,9 +68,6 @@ class MimaEngine(ABC):
|
|
|
67
68
|
self.memory: Memory = Memory()
|
|
68
69
|
self.all_games: Dict[str, GameState] = {}
|
|
69
70
|
self.current_game: str = ""
|
|
70
|
-
# self.player: Creature
|
|
71
|
-
# self.quests: List[Quest] = []
|
|
72
|
-
# self._items: Dict[str, Item] = {}
|
|
73
71
|
self.cameras: List[str] = []
|
|
74
72
|
|
|
75
73
|
def construct(
|
|
@@ -110,6 +108,9 @@ class MimaEngine(ABC):
|
|
|
110
108
|
self.backend.construct(
|
|
111
109
|
width, height, pixel_size, fullscreen, target_fps, resizable
|
|
112
110
|
)
|
|
111
|
+
self.backend.user_input.enable_touch_controls = (
|
|
112
|
+
self.enable_touch_controls
|
|
113
|
+
)
|
|
113
114
|
|
|
114
115
|
return True
|
|
115
116
|
|
|
@@ -126,7 +127,8 @@ class MimaEngine(ABC):
|
|
|
126
127
|
if self.on_user_create():
|
|
127
128
|
while self.backend.keep_running():
|
|
128
129
|
self.backend.set_caption(
|
|
129
|
-
f"{self._caption} ({self.game_fps:.2f}/"
|
|
130
|
+
f"{self._caption} ({self.game_fps:.2f}/"
|
|
131
|
+
f"{self.app_fps:.2f} fps)"
|
|
130
132
|
)
|
|
131
133
|
self.backend.process_events()
|
|
132
134
|
|
|
@@ -160,7 +162,10 @@ class MimaEngine(ABC):
|
|
|
160
162
|
app_frames = 0
|
|
161
163
|
app_seconds -= 1.0
|
|
162
164
|
|
|
163
|
-
print(
|
|
165
|
+
print(
|
|
166
|
+
f"App/Game Frames total: {app_frames_total}/"
|
|
167
|
+
f"{game_frames_total}"
|
|
168
|
+
)
|
|
164
169
|
print(f"Seconds total: {self.seconds_total:.3f}")
|
|
165
170
|
print(
|
|
166
171
|
"Average App/Game FPS: "
|
|
@@ -276,7 +281,9 @@ class MimaEngine(ABC):
|
|
|
276
281
|
def set_player(self, creature: Creature, player: Player = Player.P1):
|
|
277
282
|
self.memory.player[player] = creature
|
|
278
283
|
|
|
279
|
-
def trigger_teleport(
|
|
284
|
+
def trigger_teleport(
|
|
285
|
+
self, active: bool = True, player: Player = Player.P1
|
|
286
|
+
):
|
|
280
287
|
self.memory.teleport_active[player] = active
|
|
281
288
|
|
|
282
289
|
def is_teleport_active(self, player: Player = Player.P1):
|
|
@@ -288,7 +295,9 @@ class MimaEngine(ABC):
|
|
|
288
295
|
def is_dialog_active(self, player: Player = Player.P1):
|
|
289
296
|
return self.memory.dialog_active[player]
|
|
290
297
|
|
|
291
|
-
def trigger_script(
|
|
298
|
+
def trigger_script(
|
|
299
|
+
self, active: bool = True, player: Player = Player.P1
|
|
300
|
+
) -> None:
|
|
292
301
|
self.memory.script_active[player] = active
|
|
293
302
|
|
|
294
303
|
def is_script_active(self, player: Player = Player.P1) -> bool:
|
|
@@ -337,7 +346,10 @@ class MimaEngine(ABC):
|
|
|
337
346
|
|
|
338
347
|
@dialog_active.setter
|
|
339
348
|
def dialog_active(self, val):
|
|
340
|
-
print(
|
|
349
|
+
print(
|
|
350
|
+
"dialog_active is deprecated; use "
|
|
351
|
+
"'trigger_dialog(active)' instead."
|
|
352
|
+
)
|
|
341
353
|
self.memory.dialog_active = val
|
|
342
354
|
|
|
343
355
|
@property
|
mima/core/mode_engine.py
CHANGED
|
@@ -22,7 +22,9 @@ class MimaModeEngine(MimaEngine):
|
|
|
22
22
|
platform="PC",
|
|
23
23
|
caption: str = "MimaEngine",
|
|
24
24
|
):
|
|
25
|
-
super().__init__(
|
|
25
|
+
super().__init__(
|
|
26
|
+
init_file, config_path, default_config, platform, caption
|
|
27
|
+
)
|
|
26
28
|
|
|
27
29
|
self.modes: Dict[Mode, MimaMode] = {}
|
|
28
30
|
self.mode: Optional[MimaMode] = None
|
|
@@ -31,6 +33,7 @@ class MimaModeEngine(MimaEngine):
|
|
|
31
33
|
|
|
32
34
|
self.draw_chunks: bool = False
|
|
33
35
|
self.draw_chunk_info: bool = False
|
|
36
|
+
self.draw_dyn_ids: bool = False
|
|
34
37
|
self.disable_filter: bool = False
|
|
35
38
|
self._timer = 1.0
|
|
36
39
|
|
|
@@ -67,7 +70,9 @@ class MimaModeEngine(MimaEngine):
|
|
|
67
70
|
self.mode.load()
|
|
68
71
|
|
|
69
72
|
def return_mode(self):
|
|
70
|
-
LOG.debug(
|
|
73
|
+
LOG.debug(
|
|
74
|
+
"Returning to previous mode. Stack: %s", str(self.mode_stack)
|
|
75
|
+
)
|
|
71
76
|
self.mode_stack.pop()
|
|
72
77
|
self.mode = self.modes[self.mode_stack[-1]]
|
|
73
78
|
self.mode.load()
|
mima/objects/creature.py
CHANGED
|
@@ -21,7 +21,12 @@ class DynamicDebugBox(Projectile):
|
|
|
21
21
|
ids=None,
|
|
22
22
|
) -> None:
|
|
23
23
|
super().__init__(
|
|
24
|
-
0,
|
|
24
|
+
0,
|
|
25
|
+
0,
|
|
26
|
+
"DynamicDebugBox",
|
|
27
|
+
duration=0.0,
|
|
28
|
+
alignment=Alignment.NEUTRAL,
|
|
29
|
+
tilemap=follow.tilemap,
|
|
25
30
|
)
|
|
26
31
|
self.layer = 2
|
|
27
32
|
self.sprite = None
|
|
@@ -76,7 +81,11 @@ class DynamicDebugBox(Projectile):
|
|
|
76
81
|
class StaticDebugBox(Projectile):
|
|
77
82
|
def __init__(self, px, py, width, height, color, n_frames=1, ids=None):
|
|
78
83
|
super().__init__(
|
|
79
|
-
px,
|
|
84
|
+
px,
|
|
85
|
+
py,
|
|
86
|
+
"StaticDebugBox",
|
|
87
|
+
duration=0.0,
|
|
88
|
+
alignment=Alignment.NEUTRAL,
|
|
80
89
|
)
|
|
81
90
|
self.layer = 2
|
|
82
91
|
self._color = color
|
mima/objects/world/container.py
CHANGED
|
@@ -138,7 +138,7 @@ class Container(Dynamic):
|
|
|
138
138
|
CommandParallel(
|
|
139
139
|
[
|
|
140
140
|
CommandShowDialog(
|
|
141
|
-
[f"You received {self.
|
|
141
|
+
[f"You received {self.item.name}"],
|
|
142
142
|
),
|
|
143
143
|
CommandPresentItem(self.item_name, target),
|
|
144
144
|
CommandGiveItem(self.item_name, target),
|
mima/objects/world/oneway.py
CHANGED
|
@@ -35,6 +35,7 @@ class Oneway(Dynamic):
|
|
|
35
35
|
dyn_id=dyn_id,
|
|
36
36
|
)
|
|
37
37
|
self.type = ObjectType.ONEWAY
|
|
38
|
+
self.layer = 0
|
|
38
39
|
self.sprite.width = int(width * self.engine.rtc.tile_width)
|
|
39
40
|
self.sprite.height = int(height * self.engine.rtc.tile_height)
|
|
40
41
|
|
|
@@ -46,24 +47,26 @@ class Oneway(Dynamic):
|
|
|
46
47
|
self.height: float = height
|
|
47
48
|
self.jump_vx: float = 0.0
|
|
48
49
|
self.jump_vy: float = 0.0
|
|
50
|
+
self.jump_direction = Direction.from_velocity(jump_vx, jump_vy)
|
|
49
51
|
self.activation_delay: float = ONEWAY_ACTIVATION_DELAY
|
|
50
52
|
self.triggered: bool = False
|
|
53
|
+
self.is_active: bool = False
|
|
51
54
|
self.cooldown: float = 0.0
|
|
52
55
|
self.target = None
|
|
53
56
|
|
|
54
57
|
if jump_vx < 0:
|
|
55
58
|
self.jump_vx = jump_vx - 1
|
|
56
|
-
self.hitbox_px += 0.1
|
|
59
|
+
# self.hitbox_px += 0.1
|
|
57
60
|
elif jump_vx > 0:
|
|
58
61
|
self.jump_vx = jump_vx + 1
|
|
59
|
-
self.hitbox_px -= 0.1
|
|
62
|
+
# self.hitbox_px -= 0.1
|
|
60
63
|
|
|
61
64
|
if jump_vy < 0:
|
|
62
65
|
self.jump_vy = jump_vy - 1
|
|
63
|
-
self.hitbox_py += 0.1
|
|
66
|
+
# self.hitbox_py += 0.1
|
|
64
67
|
elif jump_vy > 0:
|
|
65
68
|
self.jump_vy = jump_vy + 1
|
|
66
|
-
self.hitbox_py -= 0.1
|
|
69
|
+
# self.hitbox_py -= 0.1
|
|
67
70
|
|
|
68
71
|
def update(self, elapsed_time, target=None):
|
|
69
72
|
self.sprite.update(
|
|
@@ -90,9 +93,15 @@ class Oneway(Dynamic):
|
|
|
90
93
|
# Activation countdown reached 0 and the jump is initiated.
|
|
91
94
|
if self.timer <= 0.0 and self.target is not None:
|
|
92
95
|
self.engine.script.add_command(
|
|
93
|
-
CommandOnewayMove(
|
|
96
|
+
CommandOnewayMove(
|
|
97
|
+
self.target,
|
|
98
|
+
self.jump_vx,
|
|
99
|
+
self.jump_vy,
|
|
100
|
+
target.get_player(),
|
|
101
|
+
)
|
|
94
102
|
)
|
|
95
103
|
self.cooldown = 2.0
|
|
104
|
+
self.is_active
|
|
96
105
|
|
|
97
106
|
# Reset the triggered flag so it has to be activated again
|
|
98
107
|
# by interaction
|
|
@@ -100,11 +109,25 @@ class Oneway(Dynamic):
|
|
|
100
109
|
self.target = None
|
|
101
110
|
|
|
102
111
|
def on_interaction(self, target, nature=Nature.WALK):
|
|
103
|
-
if
|
|
112
|
+
if (
|
|
113
|
+
target.type == ObjectType.PLAYER
|
|
114
|
+
and nature == Nature.WALK
|
|
115
|
+
and self.cooldown <= 0.0
|
|
116
|
+
):
|
|
104
117
|
# No interaction when target is higher than the oneway
|
|
105
118
|
if target.pz > 0:
|
|
106
119
|
return False
|
|
107
120
|
|
|
121
|
+
if self.jump_direction != target.facing_direction:
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
tcenterx = target.px + (target.hitbox_px + target.hitbox_width) / 2
|
|
125
|
+
tbottomy = target.py + target.hitbox_py + target.hitbox_height
|
|
126
|
+
ttopy = target.py + target.hitbox_py
|
|
127
|
+
tleftx = target.px + target.hitbox_px
|
|
128
|
+
trightx = tleftx + target.hitbox_width
|
|
129
|
+
|
|
130
|
+
# print(tcenterx, tbottomy)
|
|
108
131
|
# We have to check that target is not placed "more" in the
|
|
109
132
|
# target direction than the oneway
|
|
110
133
|
if (
|
|
@@ -119,7 +142,7 @@ class Oneway(Dynamic):
|
|
|
119
142
|
and target.py <= self.py + self.height - target.hitbox_py
|
|
120
143
|
):
|
|
121
144
|
return False
|
|
122
|
-
if self.jump_vy > 0 and
|
|
145
|
+
if self.jump_vy > 0 and tbottomy >= self.py: # FIXME
|
|
123
146
|
return False
|
|
124
147
|
|
|
125
148
|
if self.jump_vx == 0:
|
|
@@ -133,12 +156,15 @@ class Oneway(Dynamic):
|
|
|
133
156
|
return False
|
|
134
157
|
if target.py + 1.0 <= self.py:
|
|
135
158
|
return False
|
|
136
|
-
|
|
137
159
|
self.triggered = True
|
|
138
160
|
self.target = target
|
|
139
161
|
if self.timer <= 0.0:
|
|
140
162
|
self.timer = self.activation_delay
|
|
163
|
+
# return False
|
|
141
164
|
|
|
165
|
+
# print(
|
|
166
|
+
# f"activated {self.timer:.3f}, {self.px, self.py}, {target.px, target.py}, {target.sprite.width, target.sprite.height}"
|
|
167
|
+
# )
|
|
142
168
|
return True
|
|
143
169
|
|
|
144
170
|
return False
|
mima/objects/world/pickup.py
CHANGED
|
@@ -39,6 +39,7 @@ class Pickup(Dynamic):
|
|
|
39
39
|
|
|
40
40
|
self.collected = False
|
|
41
41
|
self.solid_vs_dyn = False
|
|
42
|
+
self.moves_on_collision = True
|
|
42
43
|
# self.sprite = AnimatedSprite(
|
|
43
44
|
# self.item.tileset_name,
|
|
44
45
|
# self.item.image_name,
|
|
@@ -82,6 +83,8 @@ class Pickup(Dynamic):
|
|
|
82
83
|
return
|
|
83
84
|
|
|
84
85
|
if self.pz != 0:
|
|
86
|
+
|
|
87
|
+
# print("Draw item circle")
|
|
85
88
|
self.engine.backend.fill_circle(
|
|
86
89
|
(self.px - ox + 0.5) * self.sprite.width,
|
|
87
90
|
(self.py - oy + 0.7) * self.sprite.height,
|
|
@@ -90,7 +93,10 @@ class Pickup(Dynamic):
|
|
|
90
93
|
camera_name,
|
|
91
94
|
)
|
|
92
95
|
self.sprite.draw_self(
|
|
93
|
-
self.px - ox,
|
|
96
|
+
self.px - ox,
|
|
97
|
+
self.py - oy - self.pz,
|
|
98
|
+
camera_name,
|
|
99
|
+
draw_to_ui=draw_to_ui,
|
|
94
100
|
)
|
|
95
101
|
# self.engine.backend.draw_partial_sprite(
|
|
96
102
|
# (self.px - ox) * self.item.sprite_width,
|
|
@@ -129,7 +135,7 @@ class Pickup(Dynamic):
|
|
|
129
135
|
else:
|
|
130
136
|
eff = WalkingOnWater(self)
|
|
131
137
|
self.effects.append(eff)
|
|
132
|
-
self.engine.
|
|
138
|
+
self.engine.get_view().add_effect(eff, self.tilemap.name)
|
|
133
139
|
# else:
|
|
134
140
|
# self.attributes.speed_mod = 1.0
|
|
135
141
|
|
mima/objects/world/switch.py
CHANGED
|
@@ -46,10 +46,15 @@ class Switch(Dynamic):
|
|
|
46
46
|
self.listener_ids: List[int] = []
|
|
47
47
|
self.listeners: List[Dynamic] = []
|
|
48
48
|
self.send_initial_signal = initial_signal
|
|
49
|
+
self.cooldown = 0.0
|
|
50
|
+
self.cooldown_reset = 0.8
|
|
49
51
|
|
|
50
52
|
# self._gs_map = {False: GraphicState.OPEN, True: GraphicState.CLOSED}
|
|
51
53
|
|
|
52
54
|
def update(self, elapsed_time: float, target: Optional[Dynamic] = None):
|
|
55
|
+
if self.cooldown > 0.0:
|
|
56
|
+
self.cooldown -= elapsed_time
|
|
57
|
+
|
|
53
58
|
if self.send_initial_signal:
|
|
54
59
|
self.send_signal(self.signal)
|
|
55
60
|
self.send_initial_signal = False
|
|
@@ -71,25 +76,36 @@ class Switch(Dynamic):
|
|
|
71
76
|
def on_interaction(self, target: Dynamic, nature: Nature):
|
|
72
77
|
# if target.is_player().value > 0:
|
|
73
78
|
# print(f"{target.is_player()} talked to me({self.name})")
|
|
79
|
+
if self.cooldown > 0.0:
|
|
80
|
+
return False
|
|
81
|
+
|
|
74
82
|
if (
|
|
75
83
|
nature == Nature.TALK
|
|
76
84
|
and target.type == ObjectType.PLAYER
|
|
77
85
|
and self.visible
|
|
78
86
|
):
|
|
79
87
|
self.state_changed = True
|
|
80
|
-
self.engine.audio.play_sound("switch")
|
|
88
|
+
self.engine.audio.play_sound("switch", 0.2)
|
|
89
|
+
self.cooldown = self.cooldown_reset
|
|
90
|
+
print("Player talked")
|
|
81
91
|
|
|
82
92
|
elif nature == Nature.WALK and target.type == ObjectType.PROJECTILE:
|
|
83
93
|
if self.signal:
|
|
84
94
|
# Projectiles from the right will activate the switch
|
|
85
95
|
if target.px > self.px and target.vx < 0:
|
|
86
96
|
self.state_changed = True
|
|
97
|
+
if "body" not in target.name:
|
|
98
|
+
self.engine.audio.play_sound("switch", 0.2)
|
|
99
|
+
self.cooldown = self.cooldown_reset
|
|
87
100
|
else:
|
|
88
101
|
# Projectiles from the left will (de)activate the switch
|
|
89
|
-
if
|
|
102
|
+
if (
|
|
103
|
+
target.px <= self.px and target.vx > 0
|
|
104
|
+
): # Sword does not activate because vx=0
|
|
90
105
|
self.state_changed = True
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
if "body" not in target.name:
|
|
107
|
+
self.engine.audio.play_sound("switch", 0.2)
|
|
108
|
+
self.cooldown = self.cooldown_reset
|
|
93
109
|
|
|
94
110
|
elif nature == Nature.SIGNAL:
|
|
95
111
|
self.visible = False
|
|
@@ -8,11 +8,12 @@ from ...util.constants import ONEWAY_SPEED_BOOST
|
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
10
|
from ...objects.dynamic import Dynamic
|
|
11
|
+
from ...types.player import Player
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class CommandOnewayMove(Command):
|
|
14
|
-
def __init__(self, obj: Dynamic, vx: float, vy: float):
|
|
15
|
-
super().__init__()
|
|
15
|
+
def __init__(self, obj: Dynamic, vx: float, vy: float, player: Player):
|
|
16
|
+
super().__init__([player])
|
|
16
17
|
|
|
17
18
|
self.obj: Dynamic = obj
|
|
18
19
|
self.vx: float = vx
|
|
@@ -27,7 +28,7 @@ class CommandOnewayMove(Command):
|
|
|
27
28
|
self.obj.solid_vs_map = False
|
|
28
29
|
self.obj.solid_vs_dyn = False
|
|
29
30
|
self.obj.vx = self.obj.vy = 0.0
|
|
30
|
-
self.obj.vz =
|
|
31
|
+
self.obj.vz = 7.5
|
|
31
32
|
|
|
32
33
|
self.start_px = self.obj.px
|
|
33
34
|
self.start_py = self.obj.py
|
mima/util/constants.py
CHANGED
|
@@ -10,8 +10,8 @@ UI_HIGHT: int = 1 # TODO: remove
|
|
|
10
10
|
# Map transition
|
|
11
11
|
MOVE_MAP_DURATION: float = 1.0
|
|
12
12
|
MAP_TRANSITION_DURATION_FACTOR: float = 0.75
|
|
13
|
-
ONEWAY_ACTIVATION_DELAY: float = 0.
|
|
14
|
-
ONEWAY_SPEED_BOOST: float = 2.
|
|
13
|
+
ONEWAY_ACTIVATION_DELAY: float = 0.075
|
|
14
|
+
ONEWAY_SPEED_BOOST: float = 2.5
|
|
15
15
|
|
|
16
16
|
# Gamepad
|
|
17
17
|
AXIS_DEADZONE: float = 0.25
|
|
@@ -38,7 +38,7 @@ DEFAULT_GRAPHIC_TIMER_DAMAGED: float = 0.075
|
|
|
38
38
|
DEFAULT_GRAPHIC_TIMER_DEAD: float = 0.25
|
|
39
39
|
DEFAULT_GRAPHIC_TIMER: float = 0.5
|
|
40
40
|
ATTRIBUTE_TIMER: float = 0.25
|
|
41
|
-
DEFAULT_KNOCK_SPEED: float =
|
|
41
|
+
DEFAULT_KNOCK_SPEED: float = 6.0
|
|
42
42
|
|
|
43
43
|
# Gameplay
|
|
44
44
|
ABYSS_DAMAGE: int = 1
|