Implement resetting the game

This commit is contained in:
Sofia 2026-07-22 21:31:03 +03:00
parent e1ad6b12d7
commit a9d99390d9
5 changed files with 58 additions and 14 deletions

View File

@ -1,7 +1,8 @@
[gd_scene format=3 uid="uid://df84sctteh4kw"] [gd_scene format=3 uid="uid://df84sctteh4kw"]
[node name="game_finished" type="GameFinishedScreen" unique_id=700430082 node_paths=PackedStringArray("title_container")] [node name="game_finished" type="GameFinishedScreen" unique_id=700430082 node_paths=PackedStringArray("title_container", "back_button")]
title_container = NodePath("title_container") title_container = NodePath("title_container")
back_button = NodePath("button")
anchors_preset = 15 anchors_preset = 15
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
@ -19,3 +20,19 @@ offset_right = 168.0
offset_bottom = 110.0 offset_bottom = 110.0
grow_horizontal = 2 grow_horizontal = 2
alignment = 1 alignment = 1
[node name="button" type="Button" parent="." unique_id=1264024304]
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -22.0
offset_top = -103.0
offset_right = 23.0
offset_bottom = -69.0
grow_horizontal = 2
grow_vertical = 0
theme_override_font_sizes/font_size = 32
text = "Back"

View File

@ -1,10 +1,12 @@
[gd_scene format=3 uid="uid://bii6018k3ip3t"] [gd_scene format=3 uid="uid://bii6018k3ip3t"]
[ext_resource type="PackedScene" uid="uid://bwd6bj21x310s" path="res://scenes/lobby.tscn" id="1_3ama4"]
[ext_resource type="MapResource" uid="uid://c7n1tacc7a73t" path="res://maps/default_map.tres" id="1_glms7"] [ext_resource type="MapResource" uid="uid://c7n1tacc7a73t" path="res://maps/default_map.tres" id="1_glms7"]
[ext_resource type="PackedScene" uid="uid://df84sctteh4kw" path="res://scenes/game_finished.tscn" id="1_qf2qp"] [ext_resource type="PackedScene" uid="uid://df84sctteh4kw" path="res://scenes/game_finished.tscn" id="1_qf2qp"]
[ext_resource type="MapResource" uid="uid://bsjoandgu476y" path="res://maps/diner.tres" id="2_glms7"] [ext_resource type="MapResource" uid="uid://bsjoandgu476y" path="res://maps/diner.tres" id="2_glms7"]
[node name="game_manager" type="GameManager" unique_id=1442044769] [node name="game_manager" type="GameManager" unique_id=1442044769]
respawn_timer = 10.0 respawn_timer = 10.0
lobby_screen = ExtResource("1_3ama4")
game_finished_screen = ExtResource("1_qf2qp") game_finished_screen = ExtResource("1_qf2qp")
maps = Array[MapResource]([ExtResource("1_glms7"), ExtResource("2_glms7")]) maps = Array[MapResource]([ExtResource("1_glms7"), ExtResource("2_glms7")])

View File

@ -28,6 +28,8 @@ pub struct GameManager {
#[export] #[export]
pub respawn_timer: f64, pub respawn_timer: f64,
#[export] #[export]
pub lobby_screen: Option<Gd<PackedScene>>,
#[export]
pub game_finished_screen: Option<Gd<PackedScene>>, pub game_finished_screen: Option<Gd<PackedScene>>,
pub game: Option<Gd<Game>>, pub game: Option<Gd<Game>>,
@ -77,7 +79,7 @@ impl GameManager {
.connect_other(s, |s, id| s.signals().on_map_changed().emit(id)); .connect_other(s, |s, id| s.signals().on_map_changed().emit(id));
game.signals() game.signals()
.on_game_finished() .on_game_finished()
.connect_other(s, |s| s.on_game_finished()); .connect_other(s, |s| s.go_to_finish_screen());
} }
}); });
@ -86,11 +88,17 @@ impl GameManager {
self.game = Some(game); self.game = Some(game);
} }
pub fn on_game_finished(&mut self) { pub fn go_to_finish_screen(&self) {
if let Some(scene) = &self.game_finished_screen { if let Some(scene) = &self.game_finished_screen {
self.base().get_tree().change_scene_to_packed(scene); self.base().get_tree().change_scene_to_packed(scene);
} }
} }
pub fn go_to_lobby(&self) {
if let Some(lobby) = &self.lobby_screen {
self.base().get_tree().change_scene_to_packed(lobby);
}
}
} }
pub struct GameOptions { pub struct GameOptions {
@ -274,6 +282,17 @@ impl Game {
.map(|g| g.cast::<Game>()) .map(|g| g.cast::<Game>())
} }
pub fn reset_game(&mut self) {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer
&& let Some(player) = self.find_player_mut(self.self_id.unwrap_or(0))
{
player.ready = true;
peer.broadcast_reliable(Package::SetReady(player.id(), true));
}
self.goals.clear();
}
pub fn change_option(&mut self, opt: GameOption, value: GameOptionValue) { pub fn change_option(&mut self, opt: GameOption, value: GameOptionValue) {
self.opts.values.insert(opt, value); self.opts.values.insert(opt, value);
self.run_deferred(move |s| { self.run_deferred(move |s| {
@ -556,10 +575,13 @@ impl Game {
if let Some(mut character) = player.character.take() { if let Some(mut character) = player.character.take() {
character.queue_free(); character.queue_free();
} }
player.ready = false;
} }
if let Some(mut ball) = self.world_ball.take() { if let Some(mut ball) = self.world_ball.take() {
ball.queue_free(); ball.queue_free();
} }
self.current_map.take();
self.game_started = false;
self.run_deferred(|s| s.signals().on_game_finished().emit()); self.run_deferred(|s| s.signals().on_game_finished().emit());
} }

View File

@ -19,9 +19,6 @@ use crate::{
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Node)] #[class(base=Node)]
pub struct NetworkManager { pub struct NetworkManager {
#[export]
lobby_scene: Option<Gd<PackedScene>>,
pub peer: Option<PeerKind>, pub peer: Option<PeerKind>,
last_hello: Instant, last_hello: Instant,
@ -37,8 +34,6 @@ pub const NETWORK_SINGLETON_NAME: &str = "NetworkManagerGlob";
impl INode for NetworkManager { impl INode for NetworkManager {
fn init(base: Base<Node>) -> Self { fn init(base: Base<Node>) -> Self {
NetworkManager { NetworkManager {
lobby_scene: None,
peer: None, peer: None,
last_hello: Instant::now(), last_hello: Instant::now(),
@ -219,10 +214,8 @@ impl NetworkManager {
} }
pub fn swap_to_lobby(&self, is_host: bool) { pub fn swap_to_lobby(&self, is_host: bool) {
if let Some(scene) = &self.lobby_scene {
self.base().get_tree().change_scene_to_packed(scene);
GameManager::singleton().bind_mut().init_game(is_host); GameManager::singleton().bind_mut().init_game(is_host);
} GameManager::singleton().bind().go_to_lobby();
} }
pub fn update_nick(&mut self, nick: String) { pub fn update_nick(&mut self, nick: String) {

View File

@ -1,15 +1,17 @@
use godot::{ use godot::{
classes::{HBoxContainer, IPanel, Label, Panel}, classes::{Button, HBoxContainer, IPanel, Label, Panel},
prelude::*, prelude::*,
}; };
use crate::game_manager::Game; use crate::game_manager::{Game, GameManager};
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Panel, init)] #[class(base=Panel, init)]
pub struct GameFinishedScreen { pub struct GameFinishedScreen {
#[export] #[export]
title_container: Option<Gd<HBoxContainer>>, title_container: Option<Gd<HBoxContainer>>,
#[export]
back_button: Option<Gd<Button>>,
base: Base<Panel>, base: Base<Panel>,
} }
@ -18,6 +20,14 @@ pub struct GameFinishedScreen {
impl IPanel for GameFinishedScreen { impl IPanel for GameFinishedScreen {
fn ready(&mut self) { fn ready(&mut self) {
self.produce_title(); self.produce_title();
if let Some(back) = &self.back_button {
back.signals().pressed().connect_other(self, |_| {
if let Some(mut game) = Game::singleton() {
game.bind_mut().reset_game();
}
GameManager::singleton().bind().go_to_lobby();
});
}
} }
} }