tilemap-parser 3.1.8__tar.gz → 3.1.10__tar.gz
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.
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/PKG-INFO +1 -1
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/pyproject.toml +1 -1
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/__init__.py +2 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/map_parse.py +23 -1
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/map_loader.py +13 -0
- tilemap_parser-3.1.10/src/tilemap_parser/runtime/renderer.py +192 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/PKG-INFO +1 -1
- tilemap_parser-3.1.8/src/tilemap_parser/runtime/renderer.py +0 -107
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/LICENSE +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/README.md +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/setup.cfg +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/__init__.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/animation.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/collision.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/collision_loader.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/node_parse.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/__init__.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/animation_player.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/area_node.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/collision_cache.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/object_collision.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/tile_collision.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/utils/__init__.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/utils/geometry.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/SOURCES.txt +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/dependency_links.txt +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/requires.txt +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/top_level.txt +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_collision.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_geometry.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_map_loader.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_object_collision.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_render_scale.py +0 -0
- {tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/tests/test_tile_collision.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-parser
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.10
|
|
4
4
|
Summary: Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime.
|
|
5
5
|
Author: tilemap parser contributors
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tilemap-parser"
|
|
7
|
-
version = "3.1.
|
|
7
|
+
version = "3.1.10"
|
|
8
8
|
description = "Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -40,6 +40,7 @@ from .map_parse import (
|
|
|
40
40
|
ParsedProjectState,
|
|
41
41
|
ParsedTile,
|
|
42
42
|
ParsedTileset,
|
|
43
|
+
TilesetAnimation,
|
|
43
44
|
parse_map_dict,
|
|
44
45
|
parse_map_file,
|
|
45
46
|
parse_map_json,
|
|
@@ -72,6 +73,7 @@ __all__ = [
|
|
|
72
73
|
"ParsedTile",
|
|
73
74
|
"ParsedTileset",
|
|
74
75
|
"RectangleShape",
|
|
76
|
+
"TilesetAnimation",
|
|
75
77
|
"TileCollisionData",
|
|
76
78
|
"TilesetCollision",
|
|
77
79
|
"parse_animation_dict",
|
|
@@ -125,12 +125,22 @@ class ParsedObject:
|
|
|
125
125
|
properties: Optional[JsonDict] = None
|
|
126
126
|
|
|
127
127
|
|
|
128
|
+
@dataclass
|
|
129
|
+
class TilesetAnimation:
|
|
130
|
+
frame_count: int
|
|
131
|
+
frame_duration_ms: float
|
|
132
|
+
frame_stride: int
|
|
133
|
+
loop: bool = True
|
|
134
|
+
animation_mode: str = "default"
|
|
135
|
+
|
|
136
|
+
|
|
128
137
|
@dataclass
|
|
129
138
|
class ParsedTileset:
|
|
130
139
|
path: str
|
|
131
140
|
type: str
|
|
132
141
|
properties: JsonDict = field(default_factory=dict)
|
|
133
142
|
tile_properties: Dict[str, JsonDict] = field(default_factory=dict)
|
|
143
|
+
animation: Optional[TilesetAnimation] = None
|
|
134
144
|
|
|
135
145
|
|
|
136
146
|
@dataclass
|
|
@@ -340,9 +350,21 @@ def _parse_tilesets_list(tilesets_raw: List[Any], ctx: str) -> List[ParsedTilese
|
|
|
340
350
|
tile_props[str(k)] = _require_dict(
|
|
341
351
|
v, f"{ctx}[{i}].tile_properties[{k!r}]"
|
|
342
352
|
)
|
|
353
|
+
animation = None
|
|
354
|
+
animation_raw = ts_obj.get("animation")
|
|
355
|
+
if animation_raw is not None:
|
|
356
|
+
anim_obj = _require_dict(animation_raw, f"{ctx}[{i}].animation")
|
|
357
|
+
animation = TilesetAnimation(
|
|
358
|
+
frame_count=_coerce_int(anim_obj.get("frame_count"), f"{ctx}[{i}].animation.frame_count"),
|
|
359
|
+
frame_duration_ms=_coerce_float(anim_obj.get("frame_duration_ms"), f"{ctx}[{i}].animation.frame_duration_ms"),
|
|
360
|
+
frame_stride=_coerce_int(anim_obj.get("frame_stride"), f"{ctx}[{i}].animation.frame_stride"),
|
|
361
|
+
loop=_coerce_bool(anim_obj.get("loop", True), f"{ctx}[{i}].animation.loop"),
|
|
362
|
+
animation_mode=_require_str(anim_obj.get("animation_mode", "default"), f"{ctx}[{i}].animation.animation_mode"),
|
|
363
|
+
)
|
|
343
364
|
out.append(
|
|
344
365
|
ParsedTileset(
|
|
345
|
-
path=path, type=ts_type, properties=props, tile_properties=tile_props
|
|
366
|
+
path=path, type=ts_type, properties=props, tile_properties=tile_props,
|
|
367
|
+
animation=animation,
|
|
346
368
|
)
|
|
347
369
|
)
|
|
348
370
|
return out
|
|
@@ -198,6 +198,19 @@ class TilemapData:
|
|
|
198
198
|
return None
|
|
199
199
|
return self.get_tile_surface(tile.ttype, tile.variant)
|
|
200
200
|
|
|
201
|
+
def get_tileset_animation(self, ttype: int) -> Optional[dict]:
|
|
202
|
+
if 0 <= ttype < len(self.parsed.tilesets):
|
|
203
|
+
anim = self.parsed.tilesets[ttype].animation
|
|
204
|
+
if anim is not None:
|
|
205
|
+
return {
|
|
206
|
+
"frame_count": anim.frame_count,
|
|
207
|
+
"frame_duration_ms": anim.frame_duration_ms,
|
|
208
|
+
"frame_stride": anim.frame_stride,
|
|
209
|
+
"loop": anim.loop,
|
|
210
|
+
"animation_mode": anim.animation_mode,
|
|
211
|
+
}
|
|
212
|
+
return None
|
|
213
|
+
|
|
201
214
|
|
|
202
215
|
def _variant_surface(
|
|
203
216
|
surf: Surface,
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
5
|
+
|
|
6
|
+
import pygame
|
|
7
|
+
from pygame import Rect, Surface, transform
|
|
8
|
+
|
|
9
|
+
from .map_loader import TilemapData
|
|
10
|
+
|
|
11
|
+
CHUNK_SIZE = 32
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class LayerRenderStats:
|
|
16
|
+
drawn_tiles: int
|
|
17
|
+
skipped_tiles: int
|
|
18
|
+
visible_layers: int
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TileLayerRenderer:
|
|
22
|
+
def __init__(
|
|
23
|
+
self, data: TilemapData, *, include_hidden_layers: bool = False
|
|
24
|
+
) -> None:
|
|
25
|
+
self.data = data
|
|
26
|
+
self.tile_layers = data.get_tile_layers_dict(
|
|
27
|
+
include_hidden=include_hidden_layers
|
|
28
|
+
)
|
|
29
|
+
self._sorted_layer_ids = sorted(
|
|
30
|
+
self.tile_layers.keys(),
|
|
31
|
+
key=lambda lid: (self.tile_layers[lid].z_index, lid),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
self._variant_cache: Dict[Tuple[int, int], Optional[Surface]] = {}
|
|
35
|
+
|
|
36
|
+
self._tile_w, self._tile_h = data.tile_size
|
|
37
|
+
self._rs = data.render_scale
|
|
38
|
+
if self._rs <= 0:
|
|
39
|
+
raise ValueError(f"render_scale must be positive, got {self._rs}")
|
|
40
|
+
self._eff_w = int(self._tile_w * self._rs)
|
|
41
|
+
self._eff_h = int(self._tile_h * self._rs)
|
|
42
|
+
if self._eff_w <= 0 or self._eff_h <= 0:
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f"effective tile size ({self._eff_w}, {self._eff_h}) must be positive; "
|
|
45
|
+
f"got tile_size=({self._tile_w}, {self._tile_h}) render_scale={self._rs}"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
self._tileset_animations: Dict[int, dict] = {}
|
|
49
|
+
for ts_idx, ts in enumerate(data.parsed.tilesets):
|
|
50
|
+
if ts.animation is not None:
|
|
51
|
+
self._tileset_animations[ts_idx] = {
|
|
52
|
+
"frame_count": ts.animation.frame_count,
|
|
53
|
+
"frame_duration_ms": ts.animation.frame_duration_ms,
|
|
54
|
+
"frame_stride": ts.animation.frame_stride,
|
|
55
|
+
"loop": ts.animation.loop,
|
|
56
|
+
"animation_mode": ts.animation.animation_mode,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
self._layer_chunks: Dict[int, Dict[Tuple[int, int], List[Tuple[int, int]]]] = {}
|
|
60
|
+
for layer_id, layer in self.tile_layers.items():
|
|
61
|
+
chunks: Dict[Tuple[int, int], List[Tuple[int, int]]] = {}
|
|
62
|
+
for (x, y), tile in layer.tiles.items():
|
|
63
|
+
if not isinstance(tile.ttype, int):
|
|
64
|
+
continue
|
|
65
|
+
cx, cy = x // CHUNK_SIZE, y // CHUNK_SIZE
|
|
66
|
+
chunk_key = (cx, cy)
|
|
67
|
+
if chunk_key not in chunks:
|
|
68
|
+
chunks[chunk_key] = []
|
|
69
|
+
chunks[chunk_key].append((x, y))
|
|
70
|
+
self._layer_chunks[layer_id] = chunks
|
|
71
|
+
|
|
72
|
+
def get_layer_dict(self) -> Dict[int, object]:
|
|
73
|
+
return dict(self.tile_layers)
|
|
74
|
+
|
|
75
|
+
def _get_cached_variant(self, ttype: int, variant: int) -> Optional[Surface]:
|
|
76
|
+
key = (ttype, variant)
|
|
77
|
+
if key not in self._variant_cache:
|
|
78
|
+
cell = self.data.get_tile_surface(ttype, variant, copy_surface=True)
|
|
79
|
+
if cell is not None and self._rs != 1.0:
|
|
80
|
+
cell = transform.scale(cell, (self._eff_w, self._eff_h))
|
|
81
|
+
self._variant_cache[key] = cell
|
|
82
|
+
return self._variant_cache[key]
|
|
83
|
+
|
|
84
|
+
def warm_cache(self) -> None:
|
|
85
|
+
for layer_id in self._sorted_layer_ids:
|
|
86
|
+
layer = self.tile_layers[layer_id]
|
|
87
|
+
for tile in layer.tiles.values():
|
|
88
|
+
if not isinstance(tile.ttype, int):
|
|
89
|
+
continue
|
|
90
|
+
anim = self._tileset_animations.get(tile.ttype)
|
|
91
|
+
if anim is not None:
|
|
92
|
+
frame_count = anim["frame_count"]
|
|
93
|
+
stride = anim["frame_stride"]
|
|
94
|
+
for f in range(frame_count):
|
|
95
|
+
self._get_cached_variant(tile.ttype, tile.variant + f * stride)
|
|
96
|
+
else:
|
|
97
|
+
self._get_cached_variant(tile.ttype, tile.variant)
|
|
98
|
+
self.data = None
|
|
99
|
+
|
|
100
|
+
def _compute_display_variant(
|
|
101
|
+
self,
|
|
102
|
+
variant: int,
|
|
103
|
+
ttype: int,
|
|
104
|
+
x: int,
|
|
105
|
+
y: int,
|
|
106
|
+
time_ms: int,
|
|
107
|
+
) -> int:
|
|
108
|
+
anim = self._tileset_animations.get(ttype)
|
|
109
|
+
if anim is None:
|
|
110
|
+
return variant
|
|
111
|
+
|
|
112
|
+
frame_count = anim["frame_count"]
|
|
113
|
+
frame_idx = (time_ms // anim["frame_duration_ms"]) % frame_count
|
|
114
|
+
|
|
115
|
+
if anim.get("animation_mode") == "random_start_times":
|
|
116
|
+
phase = ((x * 73856093) ^ (y * 19349663) ^ (ttype * 83492791)) % frame_count
|
|
117
|
+
frame_idx = (frame_idx + phase) % frame_count
|
|
118
|
+
|
|
119
|
+
return variant + frame_idx * anim["frame_stride"]
|
|
120
|
+
|
|
121
|
+
def render(
|
|
122
|
+
self,
|
|
123
|
+
target: Surface,
|
|
124
|
+
camera_xy: Union[Tuple[float, float], Tuple[int, int]] = (0, 0),
|
|
125
|
+
viewport_size: Optional[Tuple[int, int]] = None,
|
|
126
|
+
*,
|
|
127
|
+
current_time_ms: Optional[float] = None,
|
|
128
|
+
) -> LayerRenderStats:
|
|
129
|
+
"""Render visible tile layers.
|
|
130
|
+
|
|
131
|
+
Note: ``skipped_tiles`` is a debugging indicator, not a whole-map
|
|
132
|
+
accumulated count. It tracks null surfaces and invalid tiles within
|
|
133
|
+
the active chunk range — enough to spot rendering issues without
|
|
134
|
+
the cost of a full scan.
|
|
135
|
+
"""
|
|
136
|
+
cam_x, cam_y = float(camera_xy[0]), float(camera_xy[1])
|
|
137
|
+
if viewport_size is None:
|
|
138
|
+
viewport = target.get_rect()
|
|
139
|
+
else:
|
|
140
|
+
viewport = Rect(0, 0, viewport_size[0], viewport_size[1])
|
|
141
|
+
|
|
142
|
+
min_x = int(cam_x // self._eff_w) - 1
|
|
143
|
+
max_x = int((cam_x + viewport.width) // self._eff_w) + 1
|
|
144
|
+
min_y = int(cam_y // self._eff_h) - 1
|
|
145
|
+
max_y = int((cam_y + viewport.height) // self._eff_h) + 1
|
|
146
|
+
|
|
147
|
+
if current_time_ms is None:
|
|
148
|
+
current_time_ms = pygame.time.get_ticks()
|
|
149
|
+
time_ms = int(current_time_ms)
|
|
150
|
+
|
|
151
|
+
drawn = 0
|
|
152
|
+
skipped = 0
|
|
153
|
+
visible_layers = 0
|
|
154
|
+
|
|
155
|
+
min_cx = min_x // CHUNK_SIZE
|
|
156
|
+
max_cx = max_x // CHUNK_SIZE
|
|
157
|
+
min_cy = min_y // CHUNK_SIZE
|
|
158
|
+
max_cy = max_y // CHUNK_SIZE
|
|
159
|
+
|
|
160
|
+
for layer_id in self._sorted_layer_ids:
|
|
161
|
+
layer = self.tile_layers[layer_id]
|
|
162
|
+
if not layer.visible:
|
|
163
|
+
continue
|
|
164
|
+
visible_layers += 1
|
|
165
|
+
|
|
166
|
+
chunks = self._layer_chunks[layer_id]
|
|
167
|
+
|
|
168
|
+
for cx in range(min_cx, max_cx + 1):
|
|
169
|
+
for cy in range(min_cy, max_cy + 1):
|
|
170
|
+
chunk = chunks.get((cx, cy))
|
|
171
|
+
if not chunk:
|
|
172
|
+
continue
|
|
173
|
+
|
|
174
|
+
for x, y in chunk:
|
|
175
|
+
tile = layer.tiles[(x, y)]
|
|
176
|
+
display_variant = self._compute_display_variant(
|
|
177
|
+
tile.variant, tile.ttype, x, y, time_ms
|
|
178
|
+
)
|
|
179
|
+
cell = self._get_cached_variant(tile.ttype, display_variant)
|
|
180
|
+
if cell is None:
|
|
181
|
+
skipped += 1
|
|
182
|
+
continue
|
|
183
|
+
|
|
184
|
+
target.blit(
|
|
185
|
+
cell,
|
|
186
|
+
(x * self._eff_w - cam_x, y * self._eff_h - cam_y),
|
|
187
|
+
)
|
|
188
|
+
drawn += 1
|
|
189
|
+
|
|
190
|
+
return LayerRenderStats(
|
|
191
|
+
drawn_tiles=drawn, skipped_tiles=skipped, visible_layers=visible_layers
|
|
192
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-parser
|
|
3
|
-
Version: 3.1.
|
|
3
|
+
Version: 3.1.10
|
|
4
4
|
Summary: Standalone parser/loader for tilemap-editor JSON maps, sprite animations, and collision detection runtime.
|
|
5
5
|
Author: tilemap parser contributors
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from typing import Dict, Optional, Tuple, Union
|
|
5
|
-
|
|
6
|
-
from pygame import Rect, Surface, transform
|
|
7
|
-
|
|
8
|
-
from .map_loader import TilemapData
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@dataclass(frozen=True)
|
|
12
|
-
class LayerRenderStats:
|
|
13
|
-
drawn_tiles: int
|
|
14
|
-
skipped_tiles: int
|
|
15
|
-
visible_layers: int
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class TileLayerRenderer:
|
|
19
|
-
def __init__(
|
|
20
|
-
self, data: TilemapData, *, include_hidden_layers: bool = False
|
|
21
|
-
) -> None:
|
|
22
|
-
self.data = data
|
|
23
|
-
self.tile_layers = data.get_tile_layers_dict(
|
|
24
|
-
include_hidden=include_hidden_layers
|
|
25
|
-
)
|
|
26
|
-
self._sorted_layer_ids = sorted(
|
|
27
|
-
self.tile_layers.keys(),
|
|
28
|
-
key=lambda lid: (self.tile_layers[lid].z_index, lid),
|
|
29
|
-
)
|
|
30
|
-
self._variant_cache: Dict[Tuple[int, int], Optional[Surface]] = {}
|
|
31
|
-
self._tile_w, self._tile_h = data.tile_size
|
|
32
|
-
self._rs = data.render_scale
|
|
33
|
-
if self._rs <= 0:
|
|
34
|
-
raise ValueError(f"render_scale must be positive, got {self._rs}")
|
|
35
|
-
self._eff_w = int(self._tile_w * self._rs)
|
|
36
|
-
self._eff_h = int(self._tile_h * self._rs)
|
|
37
|
-
if self._eff_w <= 0 or self._eff_h <= 0:
|
|
38
|
-
raise ValueError(
|
|
39
|
-
f"effective tile size ({self._eff_w}, {self._eff_h}) must be positive; "
|
|
40
|
-
f"got tile_size=({self._tile_w}, {self._tile_h}) render_scale={self._rs}"
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
def get_layer_dict(self) -> Dict[int, object]:
|
|
44
|
-
return dict(self.tile_layers)
|
|
45
|
-
|
|
46
|
-
def _get_cached_variant(self, ttype: int, variant: int) -> Optional[Surface]:
|
|
47
|
-
key = (ttype, variant)
|
|
48
|
-
if key not in self._variant_cache:
|
|
49
|
-
cell = self.data.get_tile_surface(
|
|
50
|
-
ttype, variant, copy_surface=True
|
|
51
|
-
)
|
|
52
|
-
if cell is not None and self._rs != 1.0:
|
|
53
|
-
cell = transform.scale(cell, (self._eff_w, self._eff_h))
|
|
54
|
-
self._variant_cache[key] = cell
|
|
55
|
-
return self._variant_cache[key]
|
|
56
|
-
|
|
57
|
-
def warm_cache(self) -> None:
|
|
58
|
-
for layer_id in self._sorted_layer_ids:
|
|
59
|
-
layer = self.tile_layers[layer_id]
|
|
60
|
-
for tile in layer.tiles.values():
|
|
61
|
-
if isinstance(tile.ttype, int):
|
|
62
|
-
self._get_cached_variant(tile.ttype, tile.variant)
|
|
63
|
-
self.data = None
|
|
64
|
-
|
|
65
|
-
def render(
|
|
66
|
-
self,
|
|
67
|
-
target: Surface,
|
|
68
|
-
camera_xy: Union[Tuple[float, float], Tuple[int, int]] = (0, 0),
|
|
69
|
-
viewport_size: Optional[Tuple[int, int]] = None,
|
|
70
|
-
) -> LayerRenderStats:
|
|
71
|
-
cam_x, cam_y = float(camera_xy[0]), float(camera_xy[1])
|
|
72
|
-
if viewport_size is None:
|
|
73
|
-
viewport = target.get_rect()
|
|
74
|
-
else:
|
|
75
|
-
viewport = Rect(0, 0, viewport_size[0], viewport_size[1])
|
|
76
|
-
|
|
77
|
-
min_x = int(cam_x // self._eff_w) - 1
|
|
78
|
-
max_x = int((cam_x + viewport.width) // self._eff_w) + 1
|
|
79
|
-
min_y = int(cam_y // self._eff_h) - 1
|
|
80
|
-
max_y = int((cam_y + viewport.height) // self._eff_h) + 1
|
|
81
|
-
|
|
82
|
-
drawn = 0
|
|
83
|
-
skipped = 0
|
|
84
|
-
visible_layers = 0
|
|
85
|
-
|
|
86
|
-
for layer_id in self._sorted_layer_ids:
|
|
87
|
-
layer = self.tile_layers[layer_id]
|
|
88
|
-
if not layer.visible:
|
|
89
|
-
continue
|
|
90
|
-
visible_layers += 1
|
|
91
|
-
for (x, y), tile in layer.tiles.items():
|
|
92
|
-
if x < min_x or x > max_x or y < min_y or y > max_y:
|
|
93
|
-
skipped += 1
|
|
94
|
-
continue
|
|
95
|
-
if not isinstance(tile.ttype, int):
|
|
96
|
-
skipped += 1
|
|
97
|
-
continue
|
|
98
|
-
cell = self._get_cached_variant(tile.ttype, tile.variant)
|
|
99
|
-
if cell is None:
|
|
100
|
-
skipped += 1
|
|
101
|
-
continue
|
|
102
|
-
target.blit(cell, (x * self._eff_w - cam_x, y * self._eff_h - cam_y))
|
|
103
|
-
drawn += 1
|
|
104
|
-
|
|
105
|
-
return LayerRenderStats(
|
|
106
|
-
drawn_tiles=drawn, skipped_tiles=skipped, visible_layers=visible_layers
|
|
107
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/parser/collision_loader.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/animation_player.py
RENAMED
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/collision_cache.py
RENAMED
|
File without changes
|
{tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser/runtime/object_collision.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_parser-3.1.8 → tilemap_parser-3.1.10}/src/tilemap_parser.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|