extends Node var _sound: Script = load("res://scripts/sound_manager.gd") ## GameManager (автоматически запускается как Autoload). ## Этап 4: централизованное состояние игры — счёт, жизни, таймер, ## победы/поражение, save/load рекорда, звуковое сопровождение. # Счёт игрока var score: int = 0 # Оставшиеся жизни var lives: int = 3 # Прошедшее время в секундах (таймер уровня) var time_elapsed: float = 0.0 # Лучшее время прохождения (в секундах), сохраняется в user://save.cfg var best_time: float = -1.0 # Состояние игры: "playing" | "won" | "lost" var state: String = "playing" # Сумма очков для победы на текущем уровне (задается уровнем) var win_score_threshold: int = 500 # Ссылки на звуковые проигрыватели для win/lose экранов var _bgm_win: AudioStreamPlayer2D var _bgm_over: AudioStreamPlayer2D func _ready() -> void: # Загружаем сохранённый рекорд (если есть) _load_best_time() print("[GameManager] Проект инициализирован. Состояние: playing. Лучшее время: ", _fmt_time(best_time)) # Фонки для экранов победы/поражения _bgm_win = AudioStreamPlayer2D.new() _bgm_win.bus = "Master" _bgm_over = AudioStreamPlayer2D.new() _bgm_over.bus = "Master" add_child(_bgm_win) add_child(_bgm_over) func _process(delta: float) -> void: if state == "playing": time_elapsed += delta func _fmt_time(t: float) -> String: if t < 0.0: return "--:--" var minutes := int(t) / 60 var seconds := int(t) % 60 return "%02d:%02d" % [minutes, seconds] # ==== Счёт ==== func add_score(points: int) -> void: if state != "playing": return score += points print("[GameManager] +", points, " очков. Итого: ", score) if score >= win_score_threshold: win() # ==== Жизни ==== func lose_life() -> bool: lives = maxi(0, lives - 1) print("[GameManager] -1 жизнь. Осталось: ", lives) if lives <= 0: over() return false return true func respawn() -> void: print("[GameManager] Возрождение Fox.") # ==== Состояния игры ==== signal state_changed(state: String) func win() -> void: if state != "playing": return state = "won" _save_best_time() print("[GameManager] ПОБЕДА! Счёт: ", score, " | Время: ", _fmt_time(time_elapsed)) if _bgm_win.stream == null: _bgm_win.stream = load("res://audio/sound_win.ogg") _bgm_win.play(0.0) state_changed.emit("won") func over() -> void: if state != "playing": return state = "lost" _save_best_time() print("[GameManager] ИГРА ОКОНЧЕНА. Счёт: ", score) if _bgm_over.stream == null: _bgm_over.stream = load("res://audio/sound_over.ogg") _bgm_over.play(0.0) state_changed.emit("lost") # ==== Save/Load ==== func save_best_time() -> void: if best_time < 0.0 or time_elapsed < best_time: best_time = time_elapsed _save_best_time() func _load_best_time() -> void: var cfg := ConfigFile.new() var err := cfg.load("user://save.cfg") if err == OK and cfg.has_section("records"): best_time = cfg.get_value("records", "best_time", -1.0) func _save_best_time() -> void: var cfg := ConfigFile.new() if cfg.load("user://save.cfg") == OK and cfg.has_section("records"): cfg.set_value("records", "best_time", best_time) cfg.save("user://save.cfg") # ==== Звук (через SoundManager) ==== func sfx(name: String) -> void: var node := get_tree().root.get_node_or_null("SoundManager") if node != null: if node.has_method("play"): node.call("play", name)