Add simple finish game screen
This commit is contained in:
parent
8db0495242
commit
3b0332ad6e
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"]
|
[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="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"]
|
[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
|
||||||
|
game_finished_screen = ExtResource("1_qf2qp")
|
||||||
maps = Array[MapResource]([ExtResource("1_glms7"), ExtResource("2_glms7")])
|
maps = Array[MapResource]([ExtResource("1_glms7"), ExtResource("2_glms7")])
|
||||||
|
|||||||
@ -27,6 +27,8 @@ pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
|||||||
pub struct GameManager {
|
pub struct GameManager {
|
||||||
#[export]
|
#[export]
|
||||||
pub respawn_timer: f64,
|
pub respawn_timer: f64,
|
||||||
|
#[export]
|
||||||
|
pub game_finished_screen: Option<Gd<PackedScene>>,
|
||||||
|
|
||||||
pub game: Option<Gd<Game>>,
|
pub game: Option<Gd<Game>>,
|
||||||
base: Base<Node>,
|
base: Base<Node>,
|
||||||
@ -73,6 +75,9 @@ impl GameManager {
|
|||||||
game.signals()
|
game.signals()
|
||||||
.on_map_changed()
|
.on_map_changed()
|
||||||
.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()
|
||||||
|
.on_game_finished()
|
||||||
|
.connect_other(s, |s| s.on_game_finished());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -80,6 +85,12 @@ impl GameManager {
|
|||||||
|
|
||||||
self.game = Some(game);
|
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 {
|
pub struct GameOptions {
|
||||||
@ -254,6 +265,8 @@ impl Game {
|
|||||||
pub fn options_changed();
|
pub fn options_changed();
|
||||||
#[signal]
|
#[signal]
|
||||||
pub fn on_goal();
|
pub fn on_goal();
|
||||||
|
#[signal]
|
||||||
|
pub fn on_game_finished();
|
||||||
|
|
||||||
pub fn singleton() -> Option<Gd<Game>> {
|
pub fn singleton() -> Option<Gd<Game>> {
|
||||||
GameManager::singleton()
|
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) {
|
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]
|
#[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 cli;
|
||||||
|
pub mod game_finished_screen;
|
||||||
pub mod lobby;
|
pub mod lobby;
|
||||||
pub mod lobby_player_listing;
|
pub mod lobby_player_listing;
|
||||||
pub mod net_stats;
|
pub mod net_stats;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user