zombie-escape 1.1.2__tar.gz → 1.1.4__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.
Files changed (32) hide show
  1. zombie_escape-1.1.4/.gitignore +8 -0
  2. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/PKG-INFO +1 -1
  3. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/pyproject.toml +3 -0
  4. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/__about__.py +1 -1
  5. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/__init__.py +3 -1
  6. zombie_escape-1.1.4/src/zombie_escape/colors.py +26 -0
  7. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/config.py +10 -11
  8. zombie_escape-1.1.4/src/zombie_escape/constants.py +215 -0
  9. zombie_escape-1.1.4/src/zombie_escape/entities.py +771 -0
  10. zombie_escape-1.1.4/src/zombie_escape/gameplay/__init__.py +7 -0
  11. zombie_escape-1.1.4/src/zombie_escape/gameplay/logic.py +1248 -0
  12. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/level_blueprints.py +20 -14
  13. zombie_escape-1.1.2/src/zombie_escape/i18n.py → zombie_escape-1.1.4/src/zombie_escape/localization.py +10 -7
  14. zombie_escape-1.1.4/src/zombie_escape/models.py +140 -0
  15. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/render.py +161 -124
  16. zombie_escape-1.1.4/src/zombie_escape/render_assets.py +33 -0
  17. zombie_escape-1.1.4/src/zombie_escape/screens/__init__.py +106 -0
  18. zombie_escape-1.1.4/src/zombie_escape/screens/game_over.py +130 -0
  19. zombie_escape-1.1.4/src/zombie_escape/screens/gameplay.py +264 -0
  20. zombie_escape-1.1.4/src/zombie_escape/screens/settings.py +363 -0
  21. zombie_escape-1.1.4/src/zombie_escape/screens/title.py +129 -0
  22. zombie_escape-1.1.4/src/zombie_escape/zombie_escape.py +144 -0
  23. zombie_escape-1.1.2/.gitignore +0 -2
  24. zombie_escape-1.1.2/src/zombie_escape/colors.py +0 -28
  25. zombie_escape-1.1.2/src/zombie_escape/zombie_escape.py +0 -3000
  26. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/LICENSE.txt +0 -0
  27. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/README.md +0 -0
  28. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/assets/fonts/Silkscreen-Regular.ttf +0 -0
  29. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/assets/fonts/misaki_gothic.ttf +0 -0
  30. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/font_utils.py +0 -0
  31. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/locales/ui.en.json +0 -0
  32. {zombie_escape-1.1.2 → zombie_escape-1.1.4}/src/zombie_escape/locales/ui.ja.json +0 -0
@@ -0,0 +1,8 @@
1
+ .codex/
2
+ node_modules/
3
+ **/__pycache__/**
4
+ dist/
5
+
6
+ package-lock.json
7
+ package.json
8
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zombie-escape
3
- Version: 1.1.2
3
+ Version: 1.1.4
4
4
  Summary: Top-down zombie survival game built with pygame.
5
5
  Project-URL: Homepage, https://github.com/tos-kamiya/zombie-escape
6
6
  Author-email: Toshihiro Kamiya <kamiya@mbj.nifty.com>
@@ -46,3 +46,6 @@ include = ["src/zombie_escape/**"]
46
46
 
47
47
  [project.gui-scripts]
48
48
  zombie-escape = "zombie_escape:main"
49
+
50
+ [tool.ty.rules]
51
+ unresolved-import = "ignore"
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Toshihiro Kamiya <kamiya@mbj.nifty.com>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "1.1.2"
4
+ __version__ = "1.1.4"
@@ -2,4 +2,6 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
- from .zombie_escape import main
5
+ from .zombie_escape import main as main
6
+
7
+ __all__ = ["main"]
@@ -0,0 +1,26 @@
1
+ from __future__ import annotations
2
+
3
+ # Basic palette
4
+ WHITE: tuple[int, int, int] = (255, 255, 255)
5
+ BLACK: tuple[int, int, int] = (0, 0, 0)
6
+ RED: tuple[int, int, int] = (255, 0, 0)
7
+ GREEN: tuple[int, int, int] = (0, 255, 0)
8
+ BLUE: tuple[int, int, int] = (0, 0, 255)
9
+ GRAY: tuple[int, int, int] = (100, 100, 100)
10
+ LIGHT_GRAY: tuple[int, int, int] = (200, 200, 200)
11
+ YELLOW: tuple[int, int, int] = (255, 255, 0)
12
+ ORANGE: tuple[int, int, int] = (255, 165, 0)
13
+ DARK_RED: tuple[int, int, int] = (139, 0, 0)
14
+
15
+ # World colors
16
+ FOG_COLOR: tuple[int, int, int, int] = (0, 0, 0, 255)
17
+ INTERNAL_WALL_COLOR: tuple[int, int, int] = (99, 88, 70)
18
+ INTERNAL_WALL_BORDER_COLOR: tuple[int, int, int] = (105, 93, 74)
19
+ OUTER_WALL_COLOR: tuple[int, int, int] = (122, 114, 102)
20
+ OUTER_WALL_BORDER_COLOR: tuple[int, int, int] = (120, 112, 100)
21
+ FLOOR_COLOR_PRIMARY: tuple[int, int, int] = (41, 46, 51)
22
+ FLOOR_COLOR_SECONDARY: tuple[int, int, int] = (48, 54, 61)
23
+ FLOOR_COLOR_OUTSIDE: tuple[int, int, int] = (30, 45, 30)
24
+ FOOTPRINT_COLOR: tuple[int, int, int] = (110, 200, 255)
25
+ STEEL_BEAM_COLOR: tuple[int, int, int] = (110, 50, 50)
26
+ STEEL_BEAM_LINE_COLOR: tuple[int, int, int] = (180, 90, 90)
@@ -1,14 +1,14 @@
1
1
  import json
2
2
  from copy import deepcopy
3
3
  from pathlib import Path
4
- from typing import Any, Dict, Tuple
4
+ from typing import Any
5
5
 
6
6
  from platformdirs import user_config_dir
7
7
 
8
8
  APP_NAME = "ZombieEscape"
9
9
 
10
10
  # Defaults for all configurable options
11
- DEFAULT_CONFIG: Dict[str, Any] = {
11
+ DEFAULT_CONFIG: dict[str, Any] = {
12
12
  "language": "en",
13
13
  "footprints": {"enabled": True},
14
14
  "fast_zombies": {"enabled": False, "ratio": 0.1},
@@ -24,9 +24,9 @@ def user_config_path() -> Path:
24
24
  return Path(user_config_dir(APP_NAME, APP_NAME)) / "config.json"
25
25
 
26
26
 
27
- def _deep_merge(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any]:
27
+ def _deep_merge(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]:
28
28
  """Deep-merge dictionaries, with override winning on conflicts."""
29
- merged: Dict[str, Any] = deepcopy(base)
29
+ merged: dict[str, Any] = deepcopy(base)
30
30
  for key, val in override.items():
31
31
  if isinstance(val, dict) and isinstance(merged.get(key), dict):
32
32
  merged[key] = _deep_merge(merged[key], val)
@@ -35,10 +35,10 @@ def _deep_merge(base: Dict[str, Any], override: Dict[str, Any]) -> Dict[str, Any
35
35
  return merged
36
36
 
37
37
 
38
- def load_config(path: Path | None = None) -> Tuple[Dict[str, Any], Path]:
38
+ def load_config(*, path: Path | None = None) -> tuple[dict[str, Any], Path]:
39
39
  """Load config from disk, falling back to defaults on errors."""
40
40
  config_path = path or user_config_path()
41
- config: Dict[str, Any] = deepcopy(DEFAULT_CONFIG)
41
+ config: dict[str, Any] = deepcopy(DEFAULT_CONFIG)
42
42
 
43
43
  try:
44
44
  if config_path.exists():
@@ -51,11 +51,10 @@ def load_config(path: Path | None = None) -> Tuple[Dict[str, Any], Path]:
51
51
  return config, config_path
52
52
 
53
53
 
54
- def save_config(config: Dict[str, Any], path: Path | None = None) -> None:
54
+ def save_config(config: dict[str, Any], path: Path) -> None:
55
55
  """Persist config to disk, creating parent dirs as needed."""
56
- config_path = path or user_config_path()
57
56
  try:
58
- config_path.parent.mkdir(parents=True, exist_ok=True)
59
- config_path.write_text(json.dumps(config, indent=2), encoding="utf-8")
57
+ path.parent.mkdir(parents=True, exist_ok=True)
58
+ path.write_text(json.dumps(config, indent=2), encoding="utf-8")
60
59
  except Exception as exc: # noqa: BLE001
61
- print(f"Failed to save config ({config_path}): {exc}")
60
+ print(f"Failed to save config ({path}): {exc}")
@@ -0,0 +1,215 @@
1
+ """Centralized constant values and render assets for zombie_escape."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .config import DEFAULT_CONFIG
6
+ from .level_blueprints import GRID_COLS, GRID_ROWS, TILE_SIZE
7
+ from .render_assets import FogRing, RenderAssets
8
+
9
+ # --- Screen and window configuration ---
10
+ LOGICAL_SCREEN_WIDTH = 400
11
+ LOGICAL_SCREEN_HEIGHT = 300
12
+ RENDER_SCREEN_WIDTH = 400
13
+ RENDER_SCREEN_HEIGHT = 300
14
+ DEFAULT_WINDOW_SCALE = 2.0 # Keep ~800x600 OS window while rendering at 400x300
15
+ WINDOW_SCALE_MIN = 1.0
16
+ WINDOW_SCALE_MAX = DEFAULT_WINDOW_SCALE * 2 # Allow up to 1600x1200 windows
17
+ SCREEN_WIDTH = LOGICAL_SCREEN_WIDTH # Logical render width
18
+ SCREEN_HEIGHT = LOGICAL_SCREEN_HEIGHT # Logical render height
19
+ FPS = 60
20
+ STATUS_BAR_HEIGHT = 18
21
+
22
+ # --- Level dimensions derived from blueprint grid ---
23
+ LEVEL_GRID_COLS = GRID_COLS
24
+ LEVEL_GRID_ROWS = GRID_ROWS
25
+ CELL_SIZE = TILE_SIZE
26
+ LEVEL_WIDTH = LEVEL_GRID_COLS * CELL_SIZE
27
+ LEVEL_HEIGHT = LEVEL_GRID_ROWS * CELL_SIZE
28
+
29
+ # --- Player and companion settings ---
30
+ PLAYER_RADIUS = 6
31
+ PLAYER_SPEED = 1.4
32
+ FOV_RADIUS = 80
33
+ FOG_RADIUS_SCALE = 1.2
34
+ FOG_MAX_RADIUS_FACTOR = 1.55
35
+ FOG_HATCH_PIXEL_SCALE = 2
36
+ COMPANION_RADIUS = PLAYER_RADIUS
37
+ COMPANION_FOLLOW_SPEED = PLAYER_SPEED * 0.7
38
+ COMPANION_COLOR = (0, 200, 70)
39
+
40
+ # --- Survivor settings (Stage 4) ---
41
+ SURVIVOR_RADIUS = PLAYER_RADIUS - 1
42
+ SURVIVOR_COLOR = (220, 220, 255)
43
+ SURVIVOR_APPROACH_RADIUS = 48
44
+ SURVIVOR_APPROACH_SPEED = PLAYER_SPEED * 0.35
45
+ SURVIVOR_SPAWN_RATE = 0.07
46
+ SURVIVOR_MAX_SAFE_PASSENGERS = 5
47
+ SURVIVOR_SPEED_PENALTY_PER_PASSENGER = 0.104
48
+ SURVIVOR_MIN_SPEED_FACTOR = 0.35
49
+ SURVIVOR_OVERLOAD_DAMAGE_RATIO = 0.2
50
+ SURVIVOR_MESSAGE_DURATION_MS = 2000
51
+ SURVIVOR_CONVERSION_LINE_KEYS = [
52
+ "stages.stage4.conversion_lines.line1",
53
+ "stages.stage4.conversion_lines.line2",
54
+ "stages.stage4.conversion_lines.line3",
55
+ ]
56
+
57
+ # --- Flashlight settings ---
58
+ DEFAULT_FLASHLIGHT_BONUS_SCALE = float(
59
+ DEFAULT_CONFIG.get("flashlight", {}).get("bonus_scale", 1.35)
60
+ )
61
+ FLASHLIGHT_WIDTH = 10
62
+ FLASHLIGHT_HEIGHT = 8
63
+ FLASHLIGHT_PICKUP_RADIUS = 13
64
+ DEFAULT_FLASHLIGHT_SPAWN_COUNT = 2
65
+
66
+ # --- Footprint settings ---
67
+ FOOTPRINT_RADIUS = 2
68
+ FOOTPRINT_OVERVIEW_RADIUS = 3
69
+ FOOTPRINT_COLOR = (110, 200, 255)
70
+ FOOTPRINT_STEP_DISTANCE = 40
71
+ FOOTPRINT_LIFETIME_MS = 135000
72
+ FOOTPRINT_MAX = 320
73
+ FOOTPRINT_MIN_FADE = 0.3
74
+
75
+ # --- Zombie settings ---
76
+ ZOMBIE_RADIUS = 6
77
+ ZOMBIE_SPEED = 0.6
78
+ NORMAL_ZOMBIE_SPEED_JITTER = 0.15
79
+ ZOMBIE_SPAWN_DELAY_MS = 5000
80
+ MAX_ZOMBIES = 400
81
+ INITIAL_ZOMBIES_INSIDE = 15
82
+ ZOMBIE_INTERIOR_SPAWN_RATE = 0.015
83
+ ZOMBIE_SPAWN_PLAYER_BUFFER = 140
84
+ ZOMBIE_MODE_CHANGE_INTERVAL_MS = 5000
85
+ ZOMBIE_SIGHT_RANGE = FOV_RADIUS * 2.0
86
+ FAST_ZOMBIE_BASE_SPEED = PLAYER_SPEED * 0.81
87
+ FAST_ZOMBIE_SPEED_JITTER = 0.075
88
+ ZOMBIE_SEPARATION_DISTANCE = ZOMBIE_RADIUS * 2.2
89
+
90
+ # --- Car and fuel settings ---
91
+ CAR_WIDTH = 15
92
+ CAR_HEIGHT = 25
93
+ CAR_SPEED = 2
94
+ CAR_HEALTH = 20
95
+ CAR_WALL_DAMAGE = 1
96
+ CAR_ZOMBIE_DAMAGE = 1
97
+ CAR_HINT_DELAY_MS_DEFAULT = 300000
98
+ FUEL_CAN_WIDTH = 11
99
+ FUEL_CAN_HEIGHT = 15
100
+ FUEL_PICKUP_RADIUS = 12
101
+ FUEL_HINT_DURATION_MS = 1600
102
+
103
+ # --- Wall and beam settings ---
104
+ INTERNAL_WALL_GRID_SNAP = CELL_SIZE
105
+ INTERNAL_WALL_HEALTH = 40
106
+ OUTER_WALL_HEALTH = 9999
107
+ STEEL_BEAM_HEALTH = INTERNAL_WALL_HEALTH * 2
108
+
109
+ # --- Rendering assets shared with draw routines ---
110
+ FOG_RINGS = [
111
+ FogRing(radius_factor=0.82, thickness=2),
112
+ FogRing(radius_factor=0.99, thickness=4),
113
+ FogRing(radius_factor=1.16, thickness=6),
114
+ FogRing(radius_factor=1.33, thickness=8),
115
+ FogRing(radius_factor=1.5, thickness=12),
116
+ ]
117
+
118
+ RENDER_ASSETS = RenderAssets(
119
+ screen_width=SCREEN_WIDTH,
120
+ screen_height=SCREEN_HEIGHT,
121
+ status_bar_height=STATUS_BAR_HEIGHT,
122
+ player_radius=PLAYER_RADIUS,
123
+ fov_radius=FOV_RADIUS,
124
+ fog_radius_scale=FOG_RADIUS_SCALE,
125
+ fog_max_radius_factor=FOG_MAX_RADIUS_FACTOR,
126
+ fog_hatch_pixel_scale=FOG_HATCH_PIXEL_SCALE,
127
+ fog_rings=FOG_RINGS,
128
+ footprint_radius=FOOTPRINT_RADIUS,
129
+ footprint_overview_radius=FOOTPRINT_OVERVIEW_RADIUS,
130
+ footprint_lifetime_ms=FOOTPRINT_LIFETIME_MS,
131
+ footprint_min_fade=FOOTPRINT_MIN_FADE,
132
+ internal_wall_grid_snap=INTERNAL_WALL_GRID_SNAP,
133
+ default_flashlight_bonus_scale=DEFAULT_FLASHLIGHT_BONUS_SCALE,
134
+ )
135
+
136
+ __all__ = [
137
+ "LOGICAL_SCREEN_WIDTH",
138
+ "LOGICAL_SCREEN_HEIGHT",
139
+ "RENDER_SCREEN_WIDTH",
140
+ "RENDER_SCREEN_HEIGHT",
141
+ "DEFAULT_WINDOW_SCALE",
142
+ "WINDOW_SCALE_MIN",
143
+ "WINDOW_SCALE_MAX",
144
+ "SCREEN_WIDTH",
145
+ "SCREEN_HEIGHT",
146
+ "FPS",
147
+ "STATUS_BAR_HEIGHT",
148
+ "LEVEL_GRID_COLS",
149
+ "LEVEL_GRID_ROWS",
150
+ "CELL_SIZE",
151
+ "LEVEL_WIDTH",
152
+ "LEVEL_HEIGHT",
153
+ "PLAYER_RADIUS",
154
+ "PLAYER_SPEED",
155
+ "FOV_RADIUS",
156
+ "FOG_RADIUS_SCALE",
157
+ "FOG_MAX_RADIUS_FACTOR",
158
+ "FOG_HATCH_PIXEL_SCALE",
159
+ "COMPANION_RADIUS",
160
+ "COMPANION_FOLLOW_SPEED",
161
+ "COMPANION_COLOR",
162
+ "SURVIVOR_RADIUS",
163
+ "SURVIVOR_COLOR",
164
+ "SURVIVOR_APPROACH_RADIUS",
165
+ "SURVIVOR_APPROACH_SPEED",
166
+ "SURVIVOR_SPAWN_RATE",
167
+ "SURVIVOR_MAX_SAFE_PASSENGERS",
168
+ "SURVIVOR_SPEED_PENALTY_PER_PASSENGER",
169
+ "SURVIVOR_MIN_SPEED_FACTOR",
170
+ "SURVIVOR_OVERLOAD_DAMAGE_RATIO",
171
+ "SURVIVOR_MESSAGE_DURATION_MS",
172
+ "SURVIVOR_CONVERSION_LINE_KEYS",
173
+ "DEFAULT_FLASHLIGHT_BONUS_SCALE",
174
+ "FLASHLIGHT_WIDTH",
175
+ "FLASHLIGHT_HEIGHT",
176
+ "FLASHLIGHT_PICKUP_RADIUS",
177
+ "DEFAULT_FLASHLIGHT_SPAWN_COUNT",
178
+ "FOOTPRINT_RADIUS",
179
+ "FOOTPRINT_OVERVIEW_RADIUS",
180
+ "FOOTPRINT_COLOR",
181
+ "FOOTPRINT_STEP_DISTANCE",
182
+ "FOOTPRINT_LIFETIME_MS",
183
+ "FOOTPRINT_MAX",
184
+ "FOOTPRINT_MIN_FADE",
185
+ "ZOMBIE_RADIUS",
186
+ "ZOMBIE_SPEED",
187
+ "NORMAL_ZOMBIE_SPEED_JITTER",
188
+ "ZOMBIE_SPAWN_DELAY_MS",
189
+ "MAX_ZOMBIES",
190
+ "INITIAL_ZOMBIES_INSIDE",
191
+ "ZOMBIE_INTERIOR_SPAWN_RATE",
192
+ "ZOMBIE_SPAWN_PLAYER_BUFFER",
193
+ "ZOMBIE_MODE_CHANGE_INTERVAL_MS",
194
+ "ZOMBIE_SIGHT_RANGE",
195
+ "FAST_ZOMBIE_BASE_SPEED",
196
+ "FAST_ZOMBIE_SPEED_JITTER",
197
+ "ZOMBIE_SEPARATION_DISTANCE",
198
+ "CAR_WIDTH",
199
+ "CAR_HEIGHT",
200
+ "CAR_SPEED",
201
+ "CAR_HEALTH",
202
+ "CAR_WALL_DAMAGE",
203
+ "CAR_ZOMBIE_DAMAGE",
204
+ "CAR_HINT_DELAY_MS_DEFAULT",
205
+ "FUEL_CAN_WIDTH",
206
+ "FUEL_CAN_HEIGHT",
207
+ "FUEL_PICKUP_RADIUS",
208
+ "FUEL_HINT_DURATION_MS",
209
+ "INTERNAL_WALL_GRID_SNAP",
210
+ "INTERNAL_WALL_HEALTH",
211
+ "OUTER_WALL_HEALTH",
212
+ "STEEL_BEAM_HEALTH",
213
+ "FOG_RINGS",
214
+ "RENDER_ASSETS",
215
+ ]