Add simple finish game screen
This commit is contained in:
parent
c03299ec63
commit
c81f41828c
21
godot/scenes/game_finished.tscn
Normal file
21
godot/scenes/game_finished.tscn
Normal file
@ -0,0 +1,21 @@
|
||||
[gd_scene format=3 uid="uid://df84sctteh4kw"]
|
||||
|
||||
[node name="game_finished" type="GameFinishedScreen" unique_id=700430082 node_paths=PackedStringArray("title_container")]
|
||||
title_container = NodePath("title_container")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="title_container" type="HBoxContainer" parent="." unique_id=980404596]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -168.0
|
||||
offset_top = 55.0
|
||||
offset_right = 168.0
|
||||
offset_bottom = 110.0
|
||||
grow_horizontal = 2
|
||||
alignment = 1
|
||||
@ -1,8 +1,10 @@
|
||||
[gd_scene format=3 uid="uid://bii6018k3ip3t"]
|
||||
|
||||
[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="MapResource" uid="uid://bsjoandgu476y" path="res://maps/diner.tres" id="2_glms7"]
|
||||
|
||||
[node name="game_manager" type="GameManager" unique_id=1442044769]
|
||||
respawn_timer = 10.0
|
||||
game_finished_screen = ExtResource("1_qf2qp")
|
||||
maps = Array[MapResource]([ExtResource("1_glms7"), ExtResource("2_glms7")])
|
||||
|
||||
@ -27,6 +27,8 @@ pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
||||
pub struct GameManager {
|
||||
#[export]
|
||||
pub respawn_timer: f64,
|
||||
#[export]
|
||||
pub game_finished_screen: Option<Gd<PackedScene>>,
|
||||
|
||||
pub game: Option<Gd<Game>>,
|
||||
base: Base<Node>,
|
||||
@ -73,6 +75,9 @@ impl GameManager {
|
||||
game.signals()
|
||||
.on_map_changed()
|
||||
.connect_other(s, |s, id| s.signals().on_map_changed().emit(id));
|
||||
game.signals()
|
||||
.on_game_finished()
|
||||
.connect_other(s, |s| s.on_game_finished());
|
||||
}
|
||||
});
|
||||
|
||||
@ -80,6 +85,12 @@ impl GameManager {
|
||||
|
||||
self.game = Some(game);
|
||||
}
|
||||
|
||||
pub fn on_game_finished(&mut self) {
|
||||
if let Some(scene) = &self.game_finished_screen {
|
||||
self.base().get_tree().change_scene_to_packed(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GameOptions {
|
||||
@ -254,6 +265,8 @@ impl Game {
|
||||
pub fn options_changed();
|
||||
#[signal]
|
||||
pub fn on_goal();
|
||||
#[signal]
|
||||
pub fn on_game_finished();
|
||||
|
||||
pub fn singleton() -> Option<Gd<Game>> {
|
||||
GameManager::singleton()
|
||||
@ -532,6 +545,22 @@ impl Game {
|
||||
}
|
||||
}
|
||||
});
|
||||
let max_goals = self.goals.values().max().copied().unwrap_or(0);
|
||||
if max_goals >= 1 {
|
||||
self.finish_game();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish_game(&mut self) {
|
||||
for player in &mut self.players {
|
||||
if let Some(mut character) = player.character.take() {
|
||||
character.queue_free();
|
||||
}
|
||||
}
|
||||
if let Some(mut ball) = self.world_ball.take() {
|
||||
ball.queue_free();
|
||||
}
|
||||
self.run_deferred(|s| s.signals().on_game_finished().emit());
|
||||
}
|
||||
|
||||
pub fn handle_ball_pickup(&mut self, player_id: u16) {
|
||||
|
||||
@ -528,6 +528,10 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit_tree(&mut self) {
|
||||
self.set_lock(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
|
||||
69
rust/src/ui/game_finished_screen.rs
Normal file
69
rust/src/ui/game_finished_screen.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use godot::{
|
||||
classes::{HBoxContainer, IPanel, Label, Panel},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::game_manager::Game;
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(base=Panel, init)]
|
||||
pub struct GameFinishedScreen {
|
||||
#[export]
|
||||
title_container: Option<Gd<HBoxContainer>>,
|
||||
|
||||
base: Base<Panel>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl IPanel for GameFinishedScreen {
|
||||
fn ready(&mut self) {
|
||||
self.produce_title();
|
||||
}
|
||||
}
|
||||
|
||||
impl GameFinishedScreen {
|
||||
fn produce_title(&mut self) {
|
||||
if let Some(game) = Game::singleton() {
|
||||
let max_goals = game
|
||||
.bind()
|
||||
.goals
|
||||
.iter()
|
||||
.map(|(_, v)| v)
|
||||
.max()
|
||||
.copied()
|
||||
.unwrap_or(0);
|
||||
let winning_team_ids = game
|
||||
.bind()
|
||||
.goals
|
||||
.iter()
|
||||
.filter(|(_, goals)| **goals == max_goals)
|
||||
.map(|(team, _)| *team)
|
||||
.collect::<Vec<_>>();
|
||||
let winning_teams = game
|
||||
.bind()
|
||||
.get_teams()
|
||||
.iter_shared()
|
||||
.enumerate()
|
||||
.filter(|(id, _)| winning_team_ids.contains(&((*id) as u8)))
|
||||
.map(|(_, team)| team)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Some(container) = &mut self.title_container {
|
||||
for (idx, team) in winning_teams.iter().enumerate() {
|
||||
let mut label = Label::new_alloc();
|
||||
label.set_text(&team.bind().name);
|
||||
label.set_modulate(team.bind().color);
|
||||
if idx > 0 {
|
||||
let mut and_label = Label::new_alloc();
|
||||
and_label.set_text(" and ");
|
||||
container.add_child(&and_label);
|
||||
}
|
||||
container.add_child(&label);
|
||||
}
|
||||
let mut end = Label::new_alloc();
|
||||
end.set_text(" victory!");
|
||||
container.add_child(&end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
pub mod cli;
|
||||
pub mod game_finished_screen;
|
||||
pub mod lobby;
|
||||
pub mod lobby_player_listing;
|
||||
pub mod net_stats;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user