zombie-escape 1.12.0__py3-none-any.whl → 1.13.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zombie_escape/__about__.py +1 -1
- zombie_escape/__main__.py +7 -0
- zombie_escape/colors.py +22 -14
- zombie_escape/entities.py +756 -147
- zombie_escape/entities_constants.py +35 -14
- zombie_escape/export_images.py +296 -0
- zombie_escape/gameplay/__init__.py +2 -1
- zombie_escape/gameplay/constants.py +6 -0
- zombie_escape/gameplay/footprints.py +4 -0
- zombie_escape/gameplay/interactions.py +19 -7
- zombie_escape/gameplay/layout.py +103 -34
- zombie_escape/gameplay/movement.py +85 -5
- zombie_escape/gameplay/spawn.py +139 -90
- zombie_escape/gameplay/state.py +18 -9
- zombie_escape/gameplay/survivors.py +13 -2
- zombie_escape/gameplay/utils.py +40 -21
- zombie_escape/level_blueprints.py +256 -19
- zombie_escape/locales/ui.en.json +12 -2
- zombie_escape/locales/ui.ja.json +12 -2
- zombie_escape/models.py +14 -7
- zombie_escape/render.py +149 -37
- zombie_escape/render_assets.py +419 -124
- zombie_escape/render_constants.py +27 -0
- zombie_escape/screens/game_over.py +14 -3
- zombie_escape/screens/gameplay.py +72 -14
- zombie_escape/screens/title.py +18 -7
- zombie_escape/stage_constants.py +51 -15
- zombie_escape/zombie_escape.py +24 -1
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.13.1.dist-info}/METADATA +41 -15
- zombie_escape-1.13.1.dist-info/RECORD +49 -0
- zombie_escape-1.12.0.dist-info/RECORD +0 -47
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.13.1.dist-info}/WHEEL +0 -0
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.13.1.dist-info}/entry_points.txt +0 -0
- {zombie_escape-1.12.0.dist-info → zombie_escape-1.13.1.dist-info}/licenses/LICENSE.txt +0 -0
zombie_escape/models.py
CHANGED
|
@@ -26,19 +26,20 @@ if TYPE_CHECKING: # pragma: no cover - typing-only imports
|
|
|
26
26
|
class LevelLayout:
|
|
27
27
|
"""Container for level layout rectangles and cell sets."""
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
walkable_cells: list[pygame.Rect]
|
|
29
|
+
field_rect: pygame.Rect
|
|
30
|
+
outside_cells: set[tuple[int, int]]
|
|
31
|
+
walkable_cells: list[tuple[int, int]]
|
|
33
32
|
outer_wall_cells: set[tuple[int, int]]
|
|
34
33
|
wall_cells: set[tuple[int, int]]
|
|
34
|
+
pitfall_cells: set[tuple[int, int]]
|
|
35
|
+
car_walkable_cells: set[tuple[int, int]]
|
|
35
36
|
fall_spawn_cells: set[tuple[int, int]]
|
|
36
37
|
bevel_corners: dict[tuple[int, int], tuple[bool, bool, bool, bool]]
|
|
37
38
|
|
|
38
39
|
|
|
39
40
|
@dataclass
|
|
40
41
|
class FallingZombie:
|
|
41
|
-
"""Represents a zombie falling toward a target position."""
|
|
42
|
+
"""Represents a zombie falling toward a target position or into a pit."""
|
|
42
43
|
|
|
43
44
|
start_pos: tuple[int, int]
|
|
44
45
|
target_pos: tuple[int, int]
|
|
@@ -47,8 +48,9 @@ class FallingZombie:
|
|
|
47
48
|
fall_duration_ms: int
|
|
48
49
|
dust_duration_ms: int
|
|
49
50
|
tracker: bool
|
|
50
|
-
|
|
51
|
+
wall_hugging: bool
|
|
51
52
|
dust_started: bool = False
|
|
53
|
+
mode: str = "spawn" # "spawn" (falling in) or "pitfall" (falling out)
|
|
52
54
|
|
|
53
55
|
|
|
54
56
|
@dataclass
|
|
@@ -103,9 +105,12 @@ class ProgressState:
|
|
|
103
105
|
last_zombie_spawn_time: int
|
|
104
106
|
dawn_carbonized: bool
|
|
105
107
|
debug_mode: bool
|
|
108
|
+
show_fps: bool
|
|
106
109
|
falling_zombies: list[FallingZombie]
|
|
107
110
|
falling_spawn_carry: int
|
|
108
111
|
dust_rings: list[DustRing]
|
|
112
|
+
player_wall_target_cell: tuple[int, int] | None
|
|
113
|
+
player_wall_target_ttl: int
|
|
109
114
|
|
|
110
115
|
|
|
111
116
|
@dataclass
|
|
@@ -165,12 +170,14 @@ class Stage:
|
|
|
165
170
|
interior_fall_spawn_weight: float = 0.0
|
|
166
171
|
fall_spawn_zones: list[tuple[int, int, int, int]] = field(default_factory=list)
|
|
167
172
|
fall_spawn_floor_ratio: float = 0.0
|
|
173
|
+
pitfall_density: float = 0.0
|
|
168
174
|
zombie_tracker_ratio: float = 0.0
|
|
169
|
-
|
|
175
|
+
zombie_wall_hugging_ratio: float = 0.0
|
|
170
176
|
zombie_normal_ratio: float = 1.0
|
|
171
177
|
zombie_aging_duration_frames: int = ZOMBIE_AGING_DURATION_FRAMES
|
|
172
178
|
waiting_car_target_count: int = 1
|
|
173
179
|
wall_algorithm: str = "default"
|
|
180
|
+
wall_rubble_ratio: float = 0.0
|
|
174
181
|
|
|
175
182
|
@property
|
|
176
183
|
def name(self) -> str:
|
zombie_escape/render.py
CHANGED
|
@@ -34,6 +34,8 @@ from .entities_constants import (
|
|
|
34
34
|
FLASHLIGHT_WIDTH,
|
|
35
35
|
FUEL_CAN_HEIGHT,
|
|
36
36
|
FUEL_CAN_WIDTH,
|
|
37
|
+
INTERNAL_WALL_BEVEL_DEPTH,
|
|
38
|
+
JUMP_SHADOW_OFFSET,
|
|
37
39
|
SHOES_HEIGHT,
|
|
38
40
|
SHOES_WIDTH,
|
|
39
41
|
ZOMBIE_RADIUS,
|
|
@@ -63,6 +65,11 @@ from .render_constants import (
|
|
|
63
65
|
FALLING_ZOMBIE_COLOR,
|
|
64
66
|
FLASHLIGHT_FOG_SCALE_ONE,
|
|
65
67
|
FLASHLIGHT_FOG_SCALE_TWO,
|
|
68
|
+
PITFALL_ABYSS_COLOR,
|
|
69
|
+
PITFALL_EDGE_DEPTH_OFFSET,
|
|
70
|
+
PITFALL_EDGE_METAL_COLOR,
|
|
71
|
+
PITFALL_EDGE_STRIPE_COLOR,
|
|
72
|
+
PITFALL_EDGE_STRIPE_SPACING,
|
|
66
73
|
PLAYER_SHADOW_ALPHA_MULT,
|
|
67
74
|
PLAYER_SHADOW_RADIUS_MULT,
|
|
68
75
|
SHADOW_MIN_RATIO,
|
|
@@ -314,9 +321,7 @@ def draw_level_overview(
|
|
|
314
321
|
if flashlights:
|
|
315
322
|
for flashlight in flashlights:
|
|
316
323
|
if flashlight.alive():
|
|
317
|
-
pygame.draw.rect(
|
|
318
|
-
surface, YELLOW, flashlight.rect, border_radius=2
|
|
319
|
-
)
|
|
324
|
+
pygame.draw.rect(surface, YELLOW, flashlight.rect, border_radius=2)
|
|
320
325
|
pygame.draw.rect(
|
|
321
326
|
surface, BLACK, flashlight.rect, width=2, border_radius=2
|
|
322
327
|
)
|
|
@@ -587,6 +592,8 @@ def _draw_fall_whirlwind(
|
|
|
587
592
|
camera: Camera,
|
|
588
593
|
center: tuple[int, int],
|
|
589
594
|
progress: float,
|
|
595
|
+
*,
|
|
596
|
+
scale: float = 1.0,
|
|
590
597
|
) -> None:
|
|
591
598
|
base_alpha = FALLING_WHIRLWIND_COLOR[3]
|
|
592
599
|
alpha = int(max(0, min(255, base_alpha * (1.0 - progress))))
|
|
@@ -598,8 +605,9 @@ def _draw_fall_whirlwind(
|
|
|
598
605
|
FALLING_WHIRLWIND_COLOR[2],
|
|
599
606
|
alpha,
|
|
600
607
|
)
|
|
601
|
-
|
|
602
|
-
|
|
608
|
+
safe_scale = max(0.4, scale)
|
|
609
|
+
swirl_radius = max(2, int(ZOMBIE_RADIUS * 1.1 * safe_scale))
|
|
610
|
+
offset = max(1, int(ZOMBIE_RADIUS * 0.6 * safe_scale))
|
|
603
611
|
size = swirl_radius * 4
|
|
604
612
|
swirl = pygame.Surface((size, size), pygame.SRCALPHA)
|
|
605
613
|
cx = cy = size // 2
|
|
@@ -632,22 +640,42 @@ def _draw_falling_fx(
|
|
|
632
640
|
if now < fall_start:
|
|
633
641
|
if flashlight_count > 0 and pre_fx_ms > 0:
|
|
634
642
|
fx_progress = max(0.0, min(1.0, (now - fall.started_at_ms) / pre_fx_ms))
|
|
635
|
-
|
|
643
|
+
# Make the premonition grow with the impending drop scale.
|
|
644
|
+
pre_scale = 1.0 + (0.9 * fx_progress)
|
|
645
|
+
_draw_fall_whirlwind(
|
|
646
|
+
screen,
|
|
647
|
+
camera,
|
|
648
|
+
fall.start_pos,
|
|
649
|
+
fx_progress,
|
|
650
|
+
scale=pre_scale,
|
|
651
|
+
)
|
|
636
652
|
continue
|
|
637
653
|
if now >= impact_at:
|
|
638
654
|
continue
|
|
639
655
|
fall_progress = max(0.0, min(1.0, (now - fall_start) / fall_duration_ms))
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
656
|
+
|
|
657
|
+
if getattr(fall, "mode", "spawn") == "pitfall":
|
|
658
|
+
scale = 1.0 - fall_progress
|
|
659
|
+
scale = scale * scale
|
|
660
|
+
y_offset = 0.0
|
|
661
|
+
else:
|
|
662
|
+
eased = 1.0 - (1.0 - fall_progress) * (1.0 - fall_progress)
|
|
663
|
+
scale = 2.0 - (1.0 * eased)
|
|
664
|
+
# Add an extra vertical drop from above (1.5x wall depth)
|
|
665
|
+
y_offset = -INTERNAL_WALL_BEVEL_DEPTH * 1.5 * (1.0 - eased)
|
|
666
|
+
|
|
667
|
+
radius = ZOMBIE_RADIUS * scale
|
|
668
|
+
cx = fall.target_pos[0]
|
|
669
|
+
cy = fall.target_pos[1] + ZOMBIE_RADIUS - radius + y_offset
|
|
670
|
+
|
|
671
|
+
world_rect = pygame.Rect(0, 0, radius * 2, radius * 2)
|
|
672
|
+
world_rect.center = (int(cx), int(cy))
|
|
645
673
|
screen_rect = camera.apply_rect(world_rect)
|
|
646
674
|
pygame.draw.circle(
|
|
647
675
|
screen,
|
|
648
676
|
FALLING_ZOMBIE_COLOR,
|
|
649
677
|
screen_rect.center,
|
|
650
|
-
|
|
678
|
+
max(1, int(screen_rect.width / 2)),
|
|
651
679
|
)
|
|
652
680
|
|
|
653
681
|
for ring in list(dust_rings):
|
|
@@ -725,6 +753,7 @@ def _draw_status_bar(
|
|
|
725
753
|
debug_mode: bool = False,
|
|
726
754
|
zombie_group: sprite.Group | None = None,
|
|
727
755
|
falling_spawn_carry: int | None = None,
|
|
756
|
+
show_fps: bool = False,
|
|
728
757
|
fps: float | None = None,
|
|
729
758
|
) -> None:
|
|
730
759
|
"""Render a compact status bar with current config flags and stage info."""
|
|
@@ -766,14 +795,12 @@ def _draw_status_bar(
|
|
|
766
795
|
zombies = [z for z in zombie_group if z.alive()]
|
|
767
796
|
total = len(zombies)
|
|
768
797
|
tracker = sum(1 for z in zombies if z.tracker)
|
|
769
|
-
wall = sum(1 for z in zombies if z.
|
|
798
|
+
wall = sum(1 for z in zombies if z.wall_hugging)
|
|
770
799
|
normal = max(0, total - tracker - wall)
|
|
771
|
-
|
|
800
|
+
debug_counts = f"Z:{total} N:{normal} T:{tracker} W:{wall}"
|
|
772
801
|
if falling_spawn_carry is not None:
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
parts.append(f"FPS:{fps:.1f}")
|
|
776
|
-
|
|
802
|
+
debug_counts = f"{debug_counts} C:{max(0, falling_spawn_carry)}"
|
|
803
|
+
parts.append(debug_counts)
|
|
777
804
|
status_text = " | ".join(parts)
|
|
778
805
|
color = LIGHT_GRAY
|
|
779
806
|
|
|
@@ -790,7 +817,7 @@ def _draw_status_bar(
|
|
|
790
817
|
right=bar_rect.right - 12, centery=bar_rect.centery
|
|
791
818
|
)
|
|
792
819
|
screen.blit(seed_surface, seed_rect)
|
|
793
|
-
if
|
|
820
|
+
if show_fps and fps is not None:
|
|
794
821
|
fps_text = f"FPS:{fps:.1f}"
|
|
795
822
|
fps_surface = font.render(fps_text, False, LIGHT_GRAY)
|
|
796
823
|
fps_rect = fps_surface.get_rect(
|
|
@@ -807,11 +834,17 @@ def _draw_play_area(
|
|
|
807
834
|
camera: Camera,
|
|
808
835
|
assets: RenderAssets,
|
|
809
836
|
palette: Any,
|
|
810
|
-
|
|
811
|
-
|
|
837
|
+
field_rect: pygame.Rect,
|
|
838
|
+
outside_cells: set[tuple[int, int]],
|
|
812
839
|
fall_spawn_cells: set[tuple[int, int]],
|
|
840
|
+
pitfall_cells: set[tuple[int, int]],
|
|
813
841
|
) -> tuple[int, int, int, int, set[tuple[int, int]]]:
|
|
814
|
-
xs, ys, xe, ye =
|
|
842
|
+
xs, ys, xe, ye = (
|
|
843
|
+
field_rect.left,
|
|
844
|
+
field_rect.top,
|
|
845
|
+
field_rect.right,
|
|
846
|
+
field_rect.bottom,
|
|
847
|
+
)
|
|
815
848
|
xs //= assets.internal_wall_grid_snap
|
|
816
849
|
ys //= assets.internal_wall_grid_snap
|
|
817
850
|
xe //= assets.internal_wall_grid_snap
|
|
@@ -826,15 +859,6 @@ def _draw_play_area(
|
|
|
826
859
|
play_area_screen_rect = camera.apply_rect(play_area_rect)
|
|
827
860
|
pygame.draw.rect(screen, palette.floor_primary, play_area_screen_rect)
|
|
828
861
|
|
|
829
|
-
outside_cells = {
|
|
830
|
-
(r.x // assets.internal_wall_grid_snap, r.y // assets.internal_wall_grid_snap)
|
|
831
|
-
for r in outside_rects
|
|
832
|
-
}
|
|
833
|
-
for rect_obj in outside_rects:
|
|
834
|
-
sr = camera.apply_rect(rect_obj)
|
|
835
|
-
if sr.colliderect(screen.get_rect()):
|
|
836
|
-
pygame.draw.rect(screen, palette.outside, sr)
|
|
837
|
-
|
|
838
862
|
view_world = pygame.Rect(
|
|
839
863
|
-camera.camera.x,
|
|
840
864
|
-camera.camera.y,
|
|
@@ -855,7 +879,57 @@ def _draw_play_area(
|
|
|
855
879
|
for y in range(start_y, end_y):
|
|
856
880
|
for x in range(start_x, end_x):
|
|
857
881
|
if (x, y) in outside_cells:
|
|
882
|
+
lx, ly = (
|
|
883
|
+
x * assets.internal_wall_grid_snap,
|
|
884
|
+
y * assets.internal_wall_grid_snap,
|
|
885
|
+
)
|
|
886
|
+
r = pygame.Rect(
|
|
887
|
+
lx,
|
|
888
|
+
ly,
|
|
889
|
+
assets.internal_wall_grid_snap,
|
|
890
|
+
assets.internal_wall_grid_snap,
|
|
891
|
+
)
|
|
892
|
+
sr = camera.apply_rect(r)
|
|
893
|
+
if sr.colliderect(screen.get_rect()):
|
|
894
|
+
pygame.draw.rect(screen, palette.outside, sr)
|
|
895
|
+
continue
|
|
896
|
+
|
|
897
|
+
if (x, y) in pitfall_cells:
|
|
898
|
+
lx, ly = (
|
|
899
|
+
x * assets.internal_wall_grid_snap,
|
|
900
|
+
y * assets.internal_wall_grid_snap,
|
|
901
|
+
)
|
|
902
|
+
r = pygame.Rect(
|
|
903
|
+
lx,
|
|
904
|
+
ly,
|
|
905
|
+
assets.internal_wall_grid_snap,
|
|
906
|
+
assets.internal_wall_grid_snap,
|
|
907
|
+
)
|
|
908
|
+
sr = camera.apply_rect(r)
|
|
909
|
+
if not sr.colliderect(screen.get_rect()):
|
|
910
|
+
continue
|
|
911
|
+
pygame.draw.rect(screen, PITFALL_ABYSS_COLOR, sr)
|
|
912
|
+
|
|
913
|
+
if (x, y - 1) not in pitfall_cells:
|
|
914
|
+
edge_h = max(
|
|
915
|
+
1, INTERNAL_WALL_BEVEL_DEPTH - PITFALL_EDGE_DEPTH_OFFSET
|
|
916
|
+
)
|
|
917
|
+
pygame.draw.rect(
|
|
918
|
+
screen, PITFALL_EDGE_METAL_COLOR, (sr.x, sr.y, sr.w, edge_h)
|
|
919
|
+
)
|
|
920
|
+
for sx in range(
|
|
921
|
+
sr.x - edge_h, sr.right, PITFALL_EDGE_STRIPE_SPACING
|
|
922
|
+
):
|
|
923
|
+
pygame.draw.line(
|
|
924
|
+
screen,
|
|
925
|
+
PITFALL_EDGE_STRIPE_COLOR,
|
|
926
|
+
(max(sr.x, sx), sr.y),
|
|
927
|
+
(min(sr.right - 1, sx + edge_h), sr.y + edge_h - 1),
|
|
928
|
+
width=2,
|
|
929
|
+
)
|
|
930
|
+
|
|
858
931
|
continue
|
|
932
|
+
|
|
859
933
|
use_secondary = ((x // 2) + (y // 2)) % 2 == 0
|
|
860
934
|
if (x, y) in fall_spawn_cells:
|
|
861
935
|
color = (
|
|
@@ -966,11 +1040,15 @@ def _draw_entity_shadows(
|
|
|
966
1040
|
*,
|
|
967
1041
|
light_source_pos: tuple[int, int] | None,
|
|
968
1042
|
exclude_car: Car | None,
|
|
1043
|
+
outside_cells: set[tuple[int, int]] | None,
|
|
1044
|
+
cell_size: int,
|
|
969
1045
|
shadow_radius: int = int(ZOMBIE_RADIUS * ENTITY_SHADOW_RADIUS_MULT),
|
|
970
1046
|
alpha: int = ENTITY_SHADOW_ALPHA,
|
|
971
1047
|
) -> bool:
|
|
972
1048
|
if light_source_pos is None or shadow_radius <= 0:
|
|
973
1049
|
return False
|
|
1050
|
+
if cell_size <= 0:
|
|
1051
|
+
outside_cells = None
|
|
974
1052
|
shadow_surface = _get_shadow_circle_surface(
|
|
975
1053
|
shadow_radius,
|
|
976
1054
|
alpha,
|
|
@@ -990,6 +1068,13 @@ def _draw_entity_shadows(
|
|
|
990
1068
|
continue
|
|
991
1069
|
if not isinstance(entity, (Zombie, Survivor, Car)):
|
|
992
1070
|
continue
|
|
1071
|
+
if outside_cells:
|
|
1072
|
+
cell = (
|
|
1073
|
+
int(entity.rect.centerx // cell_size),
|
|
1074
|
+
int(entity.rect.centery // cell_size),
|
|
1075
|
+
)
|
|
1076
|
+
if cell in outside_cells:
|
|
1077
|
+
continue
|
|
993
1078
|
cx, cy = entity.rect.center
|
|
994
1079
|
dx = cx - px
|
|
995
1080
|
dy = cy - py
|
|
@@ -1001,8 +1086,13 @@ def _draw_entity_shadows(
|
|
|
1001
1086
|
else:
|
|
1002
1087
|
offset_x = 0.0
|
|
1003
1088
|
offset_y = 0.0
|
|
1089
|
+
|
|
1090
|
+
jump_dy = 0.0
|
|
1091
|
+
if getattr(entity, "is_jumping", False):
|
|
1092
|
+
jump_dy = JUMP_SHADOW_OFFSET
|
|
1093
|
+
|
|
1004
1094
|
shadow_rect = shadow_surface.get_rect(
|
|
1005
|
-
center=(int(cx + offset_x), int(cy + offset_y))
|
|
1095
|
+
center=(int(cx + offset_x), int(cy + offset_y + jump_dy))
|
|
1006
1096
|
)
|
|
1007
1097
|
shadow_screen_rect = camera.apply_rect(shadow_rect)
|
|
1008
1098
|
if not shadow_screen_rect.colliderect(screen_rect):
|
|
@@ -1022,6 +1112,8 @@ def _draw_single_entity_shadow(
|
|
|
1022
1112
|
*,
|
|
1023
1113
|
entity: pygame.sprite.Sprite | None,
|
|
1024
1114
|
light_source_pos: tuple[int, int] | None,
|
|
1115
|
+
outside_cells: set[tuple[int, int]] | None,
|
|
1116
|
+
cell_size: int,
|
|
1025
1117
|
shadow_radius: int,
|
|
1026
1118
|
alpha: int,
|
|
1027
1119
|
edge_softness: float = ENTITY_SHADOW_EDGE_SOFTNESS,
|
|
@@ -1033,6 +1125,13 @@ def _draw_single_entity_shadow(
|
|
|
1033
1125
|
or shadow_radius <= 0
|
|
1034
1126
|
):
|
|
1035
1127
|
return False
|
|
1128
|
+
if outside_cells and cell_size > 0:
|
|
1129
|
+
cell = (
|
|
1130
|
+
int(entity.rect.centerx // cell_size),
|
|
1131
|
+
int(entity.rect.centery // cell_size),
|
|
1132
|
+
)
|
|
1133
|
+
if cell in outside_cells:
|
|
1134
|
+
return False
|
|
1036
1135
|
shadow_surface = _get_shadow_circle_surface(
|
|
1037
1136
|
shadow_radius,
|
|
1038
1137
|
alpha,
|
|
@@ -1052,8 +1151,13 @@ def _draw_single_entity_shadow(
|
|
|
1052
1151
|
else:
|
|
1053
1152
|
offset_x = 0.0
|
|
1054
1153
|
offset_y = 0.0
|
|
1154
|
+
|
|
1155
|
+
jump_dy = 0.0
|
|
1156
|
+
if getattr(entity, "is_jumping", False):
|
|
1157
|
+
jump_dy = JUMP_SHADOW_OFFSET
|
|
1158
|
+
|
|
1055
1159
|
shadow_rect = shadow_surface.get_rect(
|
|
1056
|
-
center=(int(cx + offset_x), int(cy + offset_y))
|
|
1160
|
+
center=(int(cx + offset_x), int(cy + offset_y + jump_dy))
|
|
1057
1161
|
)
|
|
1058
1162
|
shadow_screen_rect = camera.apply_rect(shadow_rect)
|
|
1059
1163
|
if not shadow_screen_rect.colliderect(screen_rect):
|
|
@@ -1464,8 +1568,8 @@ def draw(
|
|
|
1464
1568
|
|
|
1465
1569
|
camera = game_data.camera
|
|
1466
1570
|
stage = game_data.stage
|
|
1467
|
-
|
|
1468
|
-
|
|
1571
|
+
field_rect = game_data.layout.field_rect
|
|
1572
|
+
outside_cells = game_data.layout.outside_cells
|
|
1469
1573
|
all_sprites = game_data.groups.all_sprites
|
|
1470
1574
|
fog_surfaces = game_data.fog
|
|
1471
1575
|
footprints = state.footprints
|
|
@@ -1493,9 +1597,10 @@ def draw(
|
|
|
1493
1597
|
camera,
|
|
1494
1598
|
assets,
|
|
1495
1599
|
palette,
|
|
1496
|
-
|
|
1497
|
-
|
|
1600
|
+
field_rect,
|
|
1601
|
+
outside_cells,
|
|
1498
1602
|
game_data.layout.fall_spawn_cells,
|
|
1603
|
+
game_data.layout.pitfall_cells,
|
|
1499
1604
|
)
|
|
1500
1605
|
shadow_layer = _get_shadow_layer(screen.get_size())
|
|
1501
1606
|
shadow_layer.fill((0, 0, 0, 0))
|
|
@@ -1520,6 +1625,8 @@ def draw(
|
|
|
1520
1625
|
all_sprites,
|
|
1521
1626
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1522
1627
|
exclude_car=active_car if player.in_car else None,
|
|
1628
|
+
outside_cells=outside_cells,
|
|
1629
|
+
cell_size=game_data.cell_size,
|
|
1523
1630
|
)
|
|
1524
1631
|
player_shadow_alpha = max(1, int(ENTITY_SHADOW_ALPHA * PLAYER_SHADOW_ALPHA_MULT))
|
|
1525
1632
|
player_shadow_radius = int(ZOMBIE_RADIUS * PLAYER_SHADOW_RADIUS_MULT)
|
|
@@ -1529,6 +1636,8 @@ def draw(
|
|
|
1529
1636
|
camera,
|
|
1530
1637
|
entity=active_car,
|
|
1531
1638
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1639
|
+
outside_cells=outside_cells,
|
|
1640
|
+
cell_size=game_data.cell_size,
|
|
1532
1641
|
shadow_radius=player_shadow_radius,
|
|
1533
1642
|
alpha=player_shadow_alpha,
|
|
1534
1643
|
)
|
|
@@ -1538,6 +1647,8 @@ def draw(
|
|
|
1538
1647
|
camera,
|
|
1539
1648
|
entity=player,
|
|
1540
1649
|
light_source_pos=fov_target.rect.center if fov_target else None,
|
|
1650
|
+
outside_cells=outside_cells,
|
|
1651
|
+
cell_size=game_data.cell_size,
|
|
1541
1652
|
shadow_radius=player_shadow_radius,
|
|
1542
1653
|
alpha=player_shadow_alpha,
|
|
1543
1654
|
)
|
|
@@ -1625,6 +1736,7 @@ def draw(
|
|
|
1625
1736
|
debug_mode=state.debug_mode,
|
|
1626
1737
|
zombie_group=zombie_group,
|
|
1627
1738
|
falling_spawn_carry=state.falling_spawn_carry,
|
|
1739
|
+
show_fps=state.show_fps,
|
|
1628
1740
|
fps=fps,
|
|
1629
1741
|
)
|
|
1630
1742
|
if do_flip:
|