mima-engine 0.1.4__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.
- mima/__init__.py +1 -1
- mima/backend/pygame_assets.py +15 -9
- mima/backend/pygame_audio.py +5 -2
- mima/backend/pygame_backend.py +255 -57
- mima/backend/pygame_camera.py +63 -0
- mima/backend/pygame_events.py +331 -85
- mima/collision.py +182 -111
- mima/engine.py +155 -15
- mima/maps/tiled/tiled_map.py +3 -3
- mima/maps/tiled/tiled_tileset.py +1 -0
- mima/maps/tilemap.py +78 -15
- mima/maps/tileset.py +8 -2
- mima/maps/transition_map.py +6 -8
- mima/mode_engine.py +80 -0
- mima/objects/animated_sprite.py +23 -15
- mima/objects/attributes.py +3 -0
- mima/objects/creature.py +64 -25
- mima/objects/dynamic.py +30 -8
- mima/objects/effects/colorize_screen.py +22 -6
- mima/objects/effects/debug_box.py +124 -0
- mima/objects/effects/light.py +21 -30
- mima/objects/effects/show_sprite.py +39 -0
- mima/objects/effects/walking_on_grass.py +25 -7
- mima/objects/effects/walking_on_water.py +17 -6
- mima/objects/loader.py +24 -13
- mima/objects/projectile.py +21 -6
- mima/objects/sprite.py +7 -8
- mima/objects/world/color_gate.py +5 -2
- mima/objects/world/color_switch.py +12 -6
- mima/objects/world/container.py +17 -8
- mima/objects/world/floor_switch.py +8 -4
- mima/objects/world/gate.py +8 -5
- mima/objects/world/light_source.py +11 -9
- mima/objects/world/logic_gate.py +8 -7
- mima/objects/world/movable.py +72 -28
- mima/objects/world/oneway.py +14 -9
- mima/objects/world/pickup.py +10 -5
- mima/objects/world/switch.py +28 -25
- mima/objects/world/teleport.py +76 -55
- mima/scene_engine.py +19 -20
- mima/scripts/command.py +16 -2
- mima/scripts/commands/change_map.py +23 -4
- mima/scripts/commands/equip_weapon.py +23 -0
- mima/scripts/commands/give_item.py +5 -3
- mima/scripts/commands/move_map.py +9 -9
- mima/scripts/commands/parallel.py +16 -3
- mima/scripts/commands/present_item.py +7 -5
- mima/scripts/commands/screen_fade.py +30 -12
- mima/scripts/commands/serial.py +30 -7
- mima/scripts/commands/set_spawn_map.py +6 -3
- mima/scripts/commands/show_choices.py +16 -7
- mima/scripts/commands/show_dialog.py +110 -3
- mima/scripts/script_processor.py +41 -20
- mima/states/game_state.py +2 -0
- mima/states/memory.py +28 -0
- mima/states/quest.py +2 -3
- mima/types/keys.py +48 -0
- mima/types/mode.py +4 -10
- mima/types/player.py +9 -0
- mima/types/position.py +13 -0
- mima/types/tile_collision.py +11 -0
- mima/types/window.py +44 -0
- mima/usables/item.py +1 -0
- mima/util/colors.py +5 -0
- mima/util/constants.py +6 -0
- mima/util/functions.py +27 -0
- mima/util/input_defaults.py +109 -0
- mima/util/runtime_config.py +234 -30
- mima/util/trading_item.py +20 -0
- mima/view/camera.py +160 -19
- mima/view/mima_mode.py +612 -0
- mima/view/mima_scene.py +225 -0
- mima/view/mima_view.py +12 -0
- mima/view/mima_window.py +153 -0
- {mima_engine-0.1.4.dist-info → mima_engine-0.2.0.dist-info}/METADATA +4 -2
- mima_engine-0.2.0.dist-info/RECORD +128 -0
- {mima_engine-0.1.4.dist-info → mima_engine-0.2.0.dist-info}/WHEEL +1 -1
- mima/view/scene.py +0 -322
- mima_engine-0.1.4.dist-info/RECORD +0 -114
- {mima_engine-0.1.4.dist-info → mima_engine-0.2.0.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
1
3
|
from ...types.alignment import Alignment
|
|
2
|
-
from ...
|
|
4
|
+
from ...types.player import Player
|
|
5
|
+
from ...util.colors import BLACK, Color
|
|
3
6
|
from ...util.constants import HEIGHT, WIDTH
|
|
4
7
|
from ..dynamic import Dynamic
|
|
5
8
|
from ..projectile import Projectile
|
|
@@ -12,14 +15,18 @@ class ColorizeScreen(Projectile):
|
|
|
12
15
|
alpha=BLACK.alpha,
|
|
13
16
|
duration: float = -1.0,
|
|
14
17
|
to_filter: bool = False,
|
|
18
|
+
cameras: Optional[List[str]] = None,
|
|
15
19
|
):
|
|
16
|
-
super().__init__(0, 0, 0, 0, duration, Alignment.GOOD)
|
|
20
|
+
super().__init__(0, 0, 0, 0, duration, Alignment.GOOD, None)
|
|
17
21
|
self.layer = 1
|
|
18
22
|
self.solid_vs_map = False
|
|
19
23
|
self.color = color
|
|
20
24
|
self.alpha = alpha
|
|
21
25
|
self.vanishs_after_time: bool = duration > 0
|
|
22
26
|
self.to_filter = to_filter
|
|
27
|
+
self._cameras = (
|
|
28
|
+
cameras if (cameras is not None and cameras) else ["C_DISPLAY"]
|
|
29
|
+
)
|
|
23
30
|
|
|
24
31
|
def update(self, elapsed_time: float, target: Dynamic = None):
|
|
25
32
|
if self.vanishs_after_time:
|
|
@@ -29,8 +36,17 @@ class ColorizeScreen(Projectile):
|
|
|
29
36
|
|
|
30
37
|
# self.sprite.update(elapsed_time, self.facing_direction, self.graphic_state)
|
|
31
38
|
|
|
32
|
-
def draw_self(self, ox: float, oy: float):
|
|
33
|
-
color = Color(
|
|
34
|
-
|
|
35
|
-
self.px, self.py, self.engine.backend.render_width, self.engine.backend.render_height, color, draw_to_filter=self.to_filter
|
|
39
|
+
def draw_self(self, ox: float, oy: float, camera_name=None):
|
|
40
|
+
color = Color(
|
|
41
|
+
self.color.red, self.color.green, self.color.blue, self.alpha
|
|
36
42
|
)
|
|
43
|
+
if camera_name in self._cameras:
|
|
44
|
+
self.engine.backend.fill_rect(
|
|
45
|
+
self.px,
|
|
46
|
+
self.py,
|
|
47
|
+
self.engine.backend.render_width,
|
|
48
|
+
self.engine.backend.render_height,
|
|
49
|
+
color,
|
|
50
|
+
camera_name,
|
|
51
|
+
draw_to_filter=self.to_filter,
|
|
52
|
+
)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, List
|
|
4
|
+
|
|
5
|
+
from ...types.alignment import Alignment
|
|
6
|
+
from ...util.colors import DARK_RED, TRANS_LIGHT_RED
|
|
7
|
+
from ...util.constants import SMALL_FONT_HEIGHT, SMALL_FONT_WIDTH
|
|
8
|
+
from ..projectile import Projectile
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ...util.colors import Color
|
|
12
|
+
from ..dynamic import Dynamic
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class DynamicDebugBox(Projectile):
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
follow: Dynamic,
|
|
19
|
+
color: Color = TRANS_LIGHT_RED,
|
|
20
|
+
n_frames=1,
|
|
21
|
+
ids=None,
|
|
22
|
+
) -> None:
|
|
23
|
+
super().__init__(
|
|
24
|
+
0, 0, 0, 0, 0, Alignment.NEUTRAL, follow.tilemap, "DynamicDebugBox"
|
|
25
|
+
)
|
|
26
|
+
self.layer = 2
|
|
27
|
+
self.sprite = None
|
|
28
|
+
|
|
29
|
+
self._follow: Dynamic = follow
|
|
30
|
+
self._color: Color = color
|
|
31
|
+
self._n_frames: int = n_frames
|
|
32
|
+
self._ids: List[int] = ids if ids is not None else follow.chunks
|
|
33
|
+
|
|
34
|
+
def update(self, elapsed_time: float, target: Dynamic = None):
|
|
35
|
+
if self._n_frames >= 0:
|
|
36
|
+
if self._n_frames == 0:
|
|
37
|
+
self.kill()
|
|
38
|
+
|
|
39
|
+
self._n_frames -= 1
|
|
40
|
+
|
|
41
|
+
def draw_self(self, ox, oy, camera_name):
|
|
42
|
+
ppx = (
|
|
43
|
+
self._follow.px - ox + self._follow.hitbox_px
|
|
44
|
+
) * self.engine.rtc.tile_width
|
|
45
|
+
ppy = (
|
|
46
|
+
self._follow.py - oy + self._follow.hitbox_py
|
|
47
|
+
) * self.engine.rtc.tile_height
|
|
48
|
+
pwidth = self._follow.hitbox_width * self.engine.rtc.tile_width
|
|
49
|
+
pheight = self._follow.hitbox_height * self.engine.rtc.tile_height
|
|
50
|
+
self.engine.backend.fill_rect(
|
|
51
|
+
ppx, ppy, pwidth, pheight, self._color, camera_name
|
|
52
|
+
)
|
|
53
|
+
txt = ""
|
|
54
|
+
for i in self._ids:
|
|
55
|
+
txt += f"{i} "
|
|
56
|
+
|
|
57
|
+
if txt:
|
|
58
|
+
txt = txt.strip()
|
|
59
|
+
text_pw = len(txt) * SMALL_FONT_WIDTH + 1
|
|
60
|
+
text_ph = SMALL_FONT_HEIGHT + 1
|
|
61
|
+
text_ppx = ppx + pwidth / 2 - text_pw / 2
|
|
62
|
+
text_ppy = ppy + pheight / 2 - text_ph / 2
|
|
63
|
+
self.engine.backend.fill_rect(
|
|
64
|
+
text_ppx - 1,
|
|
65
|
+
text_ppy - 1,
|
|
66
|
+
text_pw + 1,
|
|
67
|
+
text_ph + 1,
|
|
68
|
+
DARK_RED,
|
|
69
|
+
camera_name,
|
|
70
|
+
)
|
|
71
|
+
self.engine.backend.draw_small_text(
|
|
72
|
+
txt, text_ppx, text_ppy, camera_name=camera_name
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class StaticDebugBox(Projectile):
|
|
77
|
+
def __init__(self, px, py, width, height, color, n_frames=1, ids=None):
|
|
78
|
+
super().__init__(
|
|
79
|
+
px, py, 0, 0, 0, Alignment.NEUTRAL, None, "StaticDebugBox"
|
|
80
|
+
)
|
|
81
|
+
self.layer = 2
|
|
82
|
+
self._color = color
|
|
83
|
+
self._n_frames = n_frames
|
|
84
|
+
self._px = px
|
|
85
|
+
self._py = py
|
|
86
|
+
self._width = width
|
|
87
|
+
self._height = height
|
|
88
|
+
self._ids: List[int] = ids if ids is not None else []
|
|
89
|
+
|
|
90
|
+
def update(self, elapsed_time: float, target: Dynamic = None):
|
|
91
|
+
if self._n_frames <= 0:
|
|
92
|
+
self.kill()
|
|
93
|
+
|
|
94
|
+
self._n_frames -= 1
|
|
95
|
+
|
|
96
|
+
def draw_self(self, ox, oy, camera_name):
|
|
97
|
+
ppx = (self._px - ox) * self.engine.rtc.tile_width
|
|
98
|
+
ppy = (self._py - oy) * self.engine.rtc.tile_height
|
|
99
|
+
pwidth = self._width * self.engine.rtc.tile_width
|
|
100
|
+
pheight = self._height * self.engine.rtc.tile_height
|
|
101
|
+
self.engine.backend.fill_rect(
|
|
102
|
+
ppx, ppy, pwidth, pheight, self._color, camera_name
|
|
103
|
+
)
|
|
104
|
+
txt = ""
|
|
105
|
+
for i in self._ids:
|
|
106
|
+
txt += f"{i} "
|
|
107
|
+
|
|
108
|
+
if txt:
|
|
109
|
+
txt = txt.strip()
|
|
110
|
+
text_pw = len(txt) * self.engine.rtc.small_font_width + 1
|
|
111
|
+
text_ph = self.engine.rtc.small_font_height + 1
|
|
112
|
+
text_ppx = ppx + pwidth / 2 - text_pw / 2
|
|
113
|
+
text_ppy = ppy + pheight / 2 - text_ph / 2
|
|
114
|
+
self.engine.backend.fill_rect(
|
|
115
|
+
text_ppx - 1,
|
|
116
|
+
text_ppy - 1,
|
|
117
|
+
text_pw + 1,
|
|
118
|
+
text_ph + 1,
|
|
119
|
+
self.engine.rtc.color_dark_red,
|
|
120
|
+
camera_name,
|
|
121
|
+
)
|
|
122
|
+
self.engine.backend.draw_small_text(
|
|
123
|
+
txt, text_ppx, text_ppy, camera_name=camera_name
|
|
124
|
+
)
|
mima/objects/effects/light.py
CHANGED
|
@@ -2,8 +2,6 @@ from typing import List
|
|
|
2
2
|
|
|
3
3
|
from ...types.alignment import Alignment
|
|
4
4
|
from ...types.blend import Blend
|
|
5
|
-
from ...util.colors import BLACK, DARK_GREY, VERY_LIGHT_GREY, WHITE
|
|
6
|
-
from ...util.constants import TILE_HEIGHT, TILE_WIDTH
|
|
7
5
|
from ..dynamic import Dynamic
|
|
8
6
|
from ..projectile import Projectile
|
|
9
7
|
|
|
@@ -16,12 +14,15 @@ class Light(Projectile):
|
|
|
16
14
|
fixed_size: bool = False,
|
|
17
15
|
update_from_target: bool = False,
|
|
18
16
|
):
|
|
19
|
-
super().__init__(
|
|
17
|
+
super().__init__(
|
|
18
|
+
0, 0, 0, 0, 0, Alignment.GOOD, follow.tilemap, "Light"
|
|
19
|
+
)
|
|
20
20
|
self.layer = 1
|
|
21
21
|
self.sprite.name = "light_small"
|
|
22
22
|
self.sprite.width = 48
|
|
23
23
|
self.sprite.height = 48
|
|
24
24
|
self.solid_vs_map = False
|
|
25
|
+
# self.moves_on_collision = False
|
|
25
26
|
self._follow: Dynamic = follow
|
|
26
27
|
self._fixed_size: bool = fixed_size
|
|
27
28
|
self._update_from_target: bool = update_from_target
|
|
@@ -35,14 +36,14 @@ class Light(Projectile):
|
|
|
35
36
|
|
|
36
37
|
self._prepare_light(max_size)
|
|
37
38
|
|
|
38
|
-
# print(f"Light({id(self)}, {self.layer}, {self.sprite.name}, {self.sprite.width, self.sprite.height}, {self._follow}, {self._max_size}, {self._fixed_size}, {self._sizes}, {self._size_idx})")
|
|
39
|
-
|
|
40
39
|
def update(self, elapsed_time: float, target: Dynamic = None):
|
|
41
40
|
self.px = (
|
|
42
|
-
self._follow.px
|
|
41
|
+
self._follow.px
|
|
42
|
+
+ self._follow.sprite.width / self.engine.rtc.tile_width * 0.5
|
|
43
43
|
)
|
|
44
44
|
self.py = (
|
|
45
|
-
self._follow.py
|
|
45
|
+
self._follow.py
|
|
46
|
+
+ self._follow.sprite.height / self.engine.rtc.tile_height * 0.5
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
rad = self._follow.light_radius()
|
|
@@ -60,41 +61,31 @@ class Light(Projectile):
|
|
|
60
61
|
self._timer += self._timer_reset
|
|
61
62
|
self._size_idx = (self._size_idx + 1) % len(self._sizes)
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def draw_self(self, ox: float, oy: float):
|
|
66
|
-
# color = Color(self.color.red, self.color.green, self.color.blue, self.alpha)
|
|
67
|
-
# self.engine.backend.fill_rect(self.px, self.py, WIDTH, HEIGHT, color)
|
|
68
|
-
# self.engine.backend.draw_partial_sprite(
|
|
69
|
-
# (self.px - ox) * TILE_WIDTH,
|
|
70
|
-
# (self.py - oy) * TILE_WIDTH,
|
|
71
|
-
# self.sprite.name,
|
|
72
|
-
# 0,
|
|
73
|
-
# 0,
|
|
74
|
-
# self.sprite.width,
|
|
75
|
-
# self.sprite.height,
|
|
76
|
-
# draw_to_filter=True,
|
|
77
|
-
# )
|
|
78
|
-
# print(f"Drawing light {self} of {self._follow} at {(self.px - ox + self._follow.extra_ox) * TILE_WIDTH,(self.py - oy + self._follow.extra_oy) * TILE_HEIGHT}")
|
|
64
|
+
def draw_self(self, ox: float, oy: float, camera_name: str):
|
|
79
65
|
self.engine.backend.fill_circle(
|
|
80
|
-
(self.px - ox + self._follow.extra_ox)
|
|
81
|
-
|
|
66
|
+
(self.px - ox + self._follow.extra_ox)
|
|
67
|
+
* self.engine.rtc.tile_width,
|
|
68
|
+
(self.py - oy + self._follow.extra_oy)
|
|
69
|
+
* self.engine.rtc.tile_height,
|
|
82
70
|
self._sizes[self._size_idx] * 0.65, # 0.3125 *
|
|
83
|
-
|
|
71
|
+
self.engine.rtc.color_dark_grey,
|
|
72
|
+
camera_name,
|
|
84
73
|
blend_mode=Blend.SUB,
|
|
85
74
|
draw_to_filter=True,
|
|
86
75
|
)
|
|
87
76
|
self.engine.backend.fill_circle(
|
|
88
|
-
(self.px - ox + self._follow.extra_ox)
|
|
89
|
-
|
|
77
|
+
(self.px - ox + self._follow.extra_ox)
|
|
78
|
+
* self.engine.rtc.tile_width,
|
|
79
|
+
(self.py - oy + self._follow.extra_oy)
|
|
80
|
+
* self.engine.rtc.tile_height,
|
|
90
81
|
self._sizes[self._size_idx] * 0.5, # 0.3125 *
|
|
91
|
-
|
|
82
|
+
self.engine.rtc.color_very_light_grey,
|
|
83
|
+
camera_name,
|
|
92
84
|
blend_mode=Blend.SUB,
|
|
93
85
|
draw_to_filter=True,
|
|
94
86
|
)
|
|
95
87
|
|
|
96
88
|
def _prepare_light(self, max_size):
|
|
97
|
-
|
|
98
89
|
self._max_size = max_size
|
|
99
90
|
self._sizes = [max_size]
|
|
100
91
|
if not self._fixed_size:
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ...types.alignment import Alignment
|
|
6
|
+
from ..projectile import Projectile
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ...maps.tilemap import Tilemap
|
|
10
|
+
from ..sprite import Sprite
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ShowSprite(Projectile):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
px: float,
|
|
17
|
+
py: float,
|
|
18
|
+
sprite: Sprite,
|
|
19
|
+
tilemap: Tilemap,
|
|
20
|
+
layer: int = 0,
|
|
21
|
+
dyn_id: int = 0,
|
|
22
|
+
):
|
|
23
|
+
super().__init__(
|
|
24
|
+
px, py, 0.0, 0.0, 0.0, Alignment.NEUTRAL, tilemap, "SpriteEffect"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
self.layer = layer
|
|
28
|
+
self.sprite: Sprite = sprite
|
|
29
|
+
|
|
30
|
+
def update(self, elapsed_time: float):
|
|
31
|
+
self.sprite.update(
|
|
32
|
+
elapsed_time, self.facing_direction, self.graphic_state
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def draw_self(self, ox: float, oy: float, camera_name: str):
|
|
36
|
+
if self.sprite is None:
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
self.sprite.draw_self(self.px - ox, self.py - oy, camera_name)
|
|
@@ -6,7 +6,9 @@ from ..projectile import Projectile
|
|
|
6
6
|
|
|
7
7
|
class WalkingOnGrass(Projectile):
|
|
8
8
|
def __init__(self, follow: Dynamic):
|
|
9
|
-
super().__init__(
|
|
9
|
+
super().__init__(
|
|
10
|
+
follow.px, follow.py, 0, 0, 1.0, follow.alignment, follow.tilemap
|
|
11
|
+
)
|
|
10
12
|
self.layer = 0
|
|
11
13
|
self.sprite.name = "simple_sheet"
|
|
12
14
|
self.sprite.ox = 32
|
|
@@ -17,22 +19,38 @@ class WalkingOnGrass(Projectile):
|
|
|
17
19
|
self._follow = follow
|
|
18
20
|
self.renew: bool = True
|
|
19
21
|
self.solid_vs_map = False
|
|
22
|
+
# self.moves_on_collision = False
|
|
20
23
|
|
|
21
24
|
def update(self, elapsed_time: float, target: Dynamic = None):
|
|
22
25
|
if not self.renew:
|
|
23
26
|
self.kill()
|
|
24
27
|
|
|
25
|
-
self.px =
|
|
26
|
-
|
|
28
|
+
self.px = (
|
|
29
|
+
self._follow.px
|
|
30
|
+
+ (self._follow.sprite.width - self.sprite.width)
|
|
31
|
+
/ 2
|
|
32
|
+
/ self.engine.rtc.tile_width
|
|
33
|
+
)
|
|
34
|
+
self.py = (
|
|
35
|
+
self._follow.py
|
|
36
|
+
+ (self._follow.sprite.height - self.sprite.height)
|
|
37
|
+
/ self.engine.rtc.tile_height
|
|
38
|
+
)
|
|
27
39
|
|
|
28
40
|
if self._follow.graphic_state == GraphicState.STANDING:
|
|
29
41
|
elapsed_time = 0
|
|
30
|
-
self.sprite.update(
|
|
42
|
+
self.sprite.update(
|
|
43
|
+
elapsed_time, Direction.SOUTH, GraphicState.STANDING
|
|
44
|
+
)
|
|
31
45
|
|
|
32
46
|
self.renew = False
|
|
33
47
|
|
|
34
|
-
def draw_self(self, ox: float, oy: float):
|
|
35
|
-
if
|
|
48
|
+
def draw_self(self, ox: float, oy: float, camera_name):
|
|
49
|
+
if (
|
|
50
|
+
self.sprite.name is None
|
|
51
|
+
or self.sprite.name == ""
|
|
52
|
+
or self.redundant
|
|
53
|
+
):
|
|
36
54
|
return
|
|
37
55
|
|
|
38
|
-
self.sprite.draw_self(self.px - ox, self.py - oy)
|
|
56
|
+
self.sprite.draw_self(self.px - ox, self.py - oy, camera_name)
|
|
@@ -22,20 +22,31 @@ class WalkingOnWater(WalkingOnGrass):
|
|
|
22
22
|
self.kill()
|
|
23
23
|
|
|
24
24
|
self.px = (
|
|
25
|
-
self._follow.px
|
|
25
|
+
self._follow.px
|
|
26
|
+
+ (self._follow.sprite.width - self.sprite.width)
|
|
27
|
+
/ 2
|
|
28
|
+
/ self.engine.rtc.tile_width
|
|
26
29
|
)
|
|
27
30
|
self.py = (
|
|
28
|
-
self._follow.py
|
|
31
|
+
self._follow.py
|
|
32
|
+
+ (self._follow.sprite.height - self.sprite.height)
|
|
33
|
+
/ self.engine.rtc.tile_height
|
|
29
34
|
)
|
|
30
35
|
|
|
31
36
|
if self._follow.graphic_state == GraphicState.STANDING:
|
|
32
37
|
elapsed_time = 0
|
|
33
|
-
self.sprite.update(
|
|
38
|
+
self.sprite.update(
|
|
39
|
+
elapsed_time, Direction.SOUTH, GraphicState.STANDING
|
|
40
|
+
)
|
|
34
41
|
|
|
35
42
|
self.renew = False
|
|
36
43
|
|
|
37
|
-
def draw_self(self, ox: float, oy: float):
|
|
38
|
-
if
|
|
44
|
+
def draw_self(self, ox: float, oy: float, camera_name: str):
|
|
45
|
+
if (
|
|
46
|
+
self.sprite.name is None
|
|
47
|
+
or self.sprite.name == ""
|
|
48
|
+
or self.redundant
|
|
49
|
+
):
|
|
39
50
|
return
|
|
40
51
|
|
|
41
|
-
self.sprite.draw_self(self.px - ox, self.py - oy)
|
|
52
|
+
self.sprite.draw_self(self.px - ox, self.py - oy, camera_name)
|
mima/objects/loader.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
2
5
|
|
|
3
6
|
from ..types.object import ObjectType
|
|
4
|
-
from
|
|
7
|
+
from .world.color_gate import ColorGate
|
|
8
|
+
from .world.color_switch import ColorSwitch
|
|
5
9
|
from .world.container import Container
|
|
6
10
|
from .world.floor_switch import FloorSwitch
|
|
7
11
|
from .world.gate import Gate
|
|
@@ -9,17 +13,20 @@ from .world.light_source import LightSource
|
|
|
9
13
|
from .world.logic_gate import LogicGate
|
|
10
14
|
from .world.movable import Movable
|
|
11
15
|
from .world.oneway import Oneway
|
|
12
|
-
from .world.color_switch import ColorSwitch
|
|
13
|
-
from .world.color_gate import ColorGate
|
|
14
16
|
|
|
15
17
|
# from .world.pickup import Pickup
|
|
16
18
|
from .world.switch import Switch
|
|
17
19
|
from .world.teleport import Teleport
|
|
18
20
|
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from ..engine import MimaEngine
|
|
23
|
+
|
|
19
24
|
LOG = logging.getLogger(__name__)
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
class ObjectLoader:
|
|
28
|
+
engine: MimaEngine
|
|
29
|
+
|
|
23
30
|
def __init__(self, object_dispatcher, creature_dispatcher):
|
|
24
31
|
self._base_dispatcher = {
|
|
25
32
|
"color_switch": ColorSwitch.load_from_tiled_object,
|
|
@@ -42,10 +49,10 @@ class ObjectLoader:
|
|
|
42
49
|
def populate_dynamics(self, tilemap, dynamics):
|
|
43
50
|
# self._current_map = tilemap
|
|
44
51
|
for obj in tilemap.objects:
|
|
45
|
-
px = obj.px /
|
|
46
|
-
py = obj.py /
|
|
47
|
-
width = max(obj.width /
|
|
48
|
-
height = max(obj.height /
|
|
52
|
+
px = obj.px / self.engine.rtc.tile_width
|
|
53
|
+
py = obj.py / self.engine.rtc.tile_height
|
|
54
|
+
width = max(obj.width / self.engine.rtc.tile_width, 1.0)
|
|
55
|
+
height = max(obj.height / self.engine.rtc.tile_height, 1.0)
|
|
49
56
|
|
|
50
57
|
LOG.debug(
|
|
51
58
|
f"Loading object {obj.name} ({obj.object_id}): {obj.type}) "
|
|
@@ -58,13 +65,14 @@ class ObjectLoader:
|
|
|
58
65
|
|
|
59
66
|
try:
|
|
60
67
|
dynamics.extend(
|
|
61
|
-
dispatcher[obj.type](obj, px, py, width, height)
|
|
68
|
+
dispatcher[obj.type](obj, px, py, width, height, tilemap)
|
|
62
69
|
)
|
|
63
70
|
except (KeyError, ValueError):
|
|
64
71
|
LOG.exception(
|
|
65
|
-
f"Failed to load '{obj.name}' ({obj.object_id}:
|
|
72
|
+
f"Failed to load '{obj.name}' ({obj.object_id}: "
|
|
73
|
+
f"{obj.type})"
|
|
66
74
|
)
|
|
67
|
-
raise
|
|
75
|
+
# raise
|
|
68
76
|
|
|
69
77
|
# Connect listener IDs to actual listeners
|
|
70
78
|
for dyn in dynamics:
|
|
@@ -90,14 +98,17 @@ class ObjectLoader:
|
|
|
90
98
|
f"Logic Gate {listener.dyn_id}"
|
|
91
99
|
)
|
|
92
100
|
|
|
93
|
-
def load_creature_from_tiled_object(
|
|
101
|
+
def load_creature_from_tiled_object(
|
|
102
|
+
self, obj, px, py, width, height, tilemap
|
|
103
|
+
):
|
|
94
104
|
creature_type = obj.get_string("creature_type")
|
|
95
105
|
try:
|
|
96
106
|
return self._cstm_creature_dispatcher[creature_type](
|
|
97
|
-
obj, px, py, width, height
|
|
107
|
+
obj, px, py, width, height, tilemap
|
|
98
108
|
)
|
|
99
109
|
except (KeyError, ValueError):
|
|
100
110
|
LOG.exception(
|
|
101
111
|
f"Failed to load '{obj.name}' ({obj.object_id}: {obj.type})"
|
|
102
112
|
)
|
|
103
|
-
raise
|
|
113
|
+
# raise
|
|
114
|
+
return []
|
mima/objects/projectile.py
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
1
5
|
from ..types.alignment import Alignment
|
|
2
6
|
from ..types.damage import Damage
|
|
3
7
|
from ..types.object import ObjectType
|
|
4
8
|
from .dynamic import Dynamic
|
|
5
9
|
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from ..maps.tilemap import Tilemap
|
|
12
|
+
|
|
6
13
|
|
|
7
14
|
class Projectile(Dynamic):
|
|
8
15
|
def __init__(
|
|
@@ -13,9 +20,10 @@ class Projectile(Dynamic):
|
|
|
13
20
|
vy: float,
|
|
14
21
|
duration: float,
|
|
15
22
|
alignment: Alignment,
|
|
23
|
+
tilemap: Tilemap = None,
|
|
16
24
|
name: str = "Projectile",
|
|
17
25
|
):
|
|
18
|
-
super().__init__(
|
|
26
|
+
super().__init__(px, py, name, tilemap)
|
|
19
27
|
|
|
20
28
|
self.type = ObjectType.PROJECTILE
|
|
21
29
|
self.vx = vx
|
|
@@ -31,6 +39,7 @@ class Projectile(Dynamic):
|
|
|
31
39
|
self.one_hit = False
|
|
32
40
|
self.inherit_pos = False
|
|
33
41
|
self.gravity = False
|
|
42
|
+
self.moves_on_collision = True
|
|
34
43
|
self.change_solid_vs_map_timer = 0
|
|
35
44
|
self.dtype = Damage.BODY
|
|
36
45
|
self.damage = 0
|
|
@@ -47,12 +56,13 @@ class Projectile(Dynamic):
|
|
|
47
56
|
self.change_solid_vs_map_timer = 0
|
|
48
57
|
|
|
49
58
|
self.speed = self.attributes.speed
|
|
50
|
-
|
|
59
|
+
# if "body" not in self.name:
|
|
60
|
+
# print(self.name, self.pz)
|
|
51
61
|
self.sprite.update(
|
|
52
62
|
elapsed_time, self.facing_direction, self.graphic_state
|
|
53
63
|
)
|
|
54
64
|
|
|
55
|
-
def draw_self(self, ox: float, oy: float):
|
|
65
|
+
def draw_self(self, ox: float, oy: float, camera_name: str = "display"):
|
|
56
66
|
if (
|
|
57
67
|
self.sprite.name is None
|
|
58
68
|
or self.sprite.name == ""
|
|
@@ -60,7 +70,7 @@ class Projectile(Dynamic):
|
|
|
60
70
|
):
|
|
61
71
|
return
|
|
62
72
|
|
|
63
|
-
self.sprite.draw_self(self.px - ox, self.py - oy)
|
|
73
|
+
self.sprite.draw_self(self.px - ox, self.py - oy, camera_name)
|
|
64
74
|
|
|
65
75
|
def on_death(self) -> bool:
|
|
66
76
|
if self.spawn_on_death:
|
|
@@ -69,9 +79,11 @@ class Projectile(Dynamic):
|
|
|
69
79
|
if self.inherit_pos:
|
|
70
80
|
do.px = self.px
|
|
71
81
|
do.py = self.py
|
|
72
|
-
self.engine.
|
|
82
|
+
self.engine.get_view().add_projectile(
|
|
83
|
+
do, self.tilemap.name
|
|
84
|
+
)
|
|
73
85
|
else:
|
|
74
|
-
self.engine.
|
|
86
|
+
self.engine.get_view().add_dynamic(do, self.tilemap.name)
|
|
75
87
|
|
|
76
88
|
return False
|
|
77
89
|
|
|
@@ -84,3 +96,6 @@ class Projectile(Dynamic):
|
|
|
84
96
|
do.kill()
|
|
85
97
|
self.kill()
|
|
86
98
|
return True
|
|
99
|
+
|
|
100
|
+
def __str__(self):
|
|
101
|
+
return f"P({self.name}, {self.dyn_id})"
|
mima/objects/sprite.py
CHANGED
|
@@ -8,20 +8,18 @@ from ..util.constants import (
|
|
|
8
8
|
DEFAULT_GRAPHIC_TIMER_WALKING,
|
|
9
9
|
DEFAULT_SPRITE_HEIGHT,
|
|
10
10
|
DEFAULT_SPRITE_WIDTH,
|
|
11
|
-
TILE_HEIGHT,
|
|
12
|
-
TILE_WIDTH,
|
|
13
11
|
)
|
|
14
12
|
|
|
15
13
|
|
|
16
14
|
class Sprite:
|
|
17
15
|
engine = None
|
|
18
16
|
|
|
19
|
-
def __init__(self, name: str = ""):
|
|
17
|
+
def __init__(self, name: str = "", *, ox=0, oy=0, width=0, height=0):
|
|
20
18
|
self.name = name
|
|
21
19
|
self.ox: int = 0
|
|
22
20
|
self.oy: int = 0
|
|
23
|
-
self.width: int = DEFAULT_SPRITE_WIDTH
|
|
24
|
-
self.height: int = DEFAULT_SPRITE_HEIGHT
|
|
21
|
+
self.width: int = DEFAULT_SPRITE_WIDTH if width == 0 else width
|
|
22
|
+
self.height: int = DEFAULT_SPRITE_HEIGHT if height == 0 else height
|
|
25
23
|
self.num_frames: int = 1
|
|
26
24
|
self.frame_index: int = 0
|
|
27
25
|
|
|
@@ -74,7 +72,7 @@ class Sprite:
|
|
|
74
72
|
self.last_direction = direction
|
|
75
73
|
self.last_graphic_state = graphic_state
|
|
76
74
|
|
|
77
|
-
def draw_self(self, px: float, py: float):
|
|
75
|
+
def draw_self(self, px: float, py: float, camera_name: str = "display"):
|
|
78
76
|
if self.name == "":
|
|
79
77
|
return
|
|
80
78
|
|
|
@@ -96,13 +94,14 @@ class Sprite:
|
|
|
96
94
|
sheet_oy = (self.oy + state_value) * self.height
|
|
97
95
|
|
|
98
96
|
self.engine.backend.draw_partial_sprite(
|
|
99
|
-
px *
|
|
100
|
-
py *
|
|
97
|
+
px * self.engine.rtc.tile_width,
|
|
98
|
+
py * self.engine.rtc.tile_height,
|
|
101
99
|
self.name,
|
|
102
100
|
sheet_ox,
|
|
103
101
|
sheet_oy,
|
|
104
102
|
self.width,
|
|
105
103
|
self.height,
|
|
104
|
+
camera_name,
|
|
106
105
|
)
|
|
107
106
|
|
|
108
107
|
def reset(self):
|
mima/objects/world/color_gate.py
CHANGED
|
@@ -21,20 +21,22 @@ class ColorGate(Gate):
|
|
|
21
21
|
graphic_state: GraphicState,
|
|
22
22
|
facing_direction: Direction,
|
|
23
23
|
color: GateColor,
|
|
24
|
+
tilemap=None,
|
|
24
25
|
dyn_id: int = -1,
|
|
25
26
|
name: str = "ColorGate",
|
|
26
27
|
):
|
|
27
28
|
super().__init__(
|
|
28
29
|
px,
|
|
29
30
|
py,
|
|
31
|
+
name,
|
|
30
32
|
tileset_name,
|
|
31
33
|
image_name,
|
|
32
34
|
sprite_name,
|
|
33
35
|
graphic_state,
|
|
34
36
|
facing_direction,
|
|
35
37
|
False,
|
|
38
|
+
tilemap,
|
|
36
39
|
dyn_id,
|
|
37
|
-
name,
|
|
38
40
|
)
|
|
39
41
|
self.color = color
|
|
40
42
|
self.type = ObjectType.COLOR_GATE
|
|
@@ -47,7 +49,7 @@ class ColorGate(Gate):
|
|
|
47
49
|
return False
|
|
48
50
|
|
|
49
51
|
@staticmethod
|
|
50
|
-
def load_from_tiled_object(obj, px, py, width, height):
|
|
52
|
+
def load_from_tiled_object(obj, px, py, width, height, tilemap):
|
|
51
53
|
gate = ColorGate(
|
|
52
54
|
px=px,
|
|
53
55
|
py=py,
|
|
@@ -61,6 +63,7 @@ class ColorGate(Gate):
|
|
|
61
63
|
obj.get_string("facing_direction", "south").upper()
|
|
62
64
|
],
|
|
63
65
|
color=GateColor[obj.get_string("color", "red").upper()],
|
|
66
|
+
tilemap=tilemap,
|
|
64
67
|
dyn_id=obj.object_id,
|
|
65
68
|
name=obj.name,
|
|
66
69
|
)
|