Add map selection and entering game
This commit is contained in:
parent
c594af3bd1
commit
73c7c5b850
7
godot/maps/default_map.tres
Normal file
7
godot/maps/default_map.tres
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[gd_resource type="Map" format=3 uid="uid://b4rw48yjf7q3q"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://lahirbqfppvw" path="res://scenes/main.tscn" id="1_k5804"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
name = "Default Map"
|
||||||
|
scene = ExtResource("1_k5804")
|
||||||
7
godot/maps/default_map_2.tres
Normal file
7
godot/maps/default_map_2.tres
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[gd_resource type="Map" format=3 uid="uid://crti664evgfmj"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://lahirbqfppvw" path="res://scenes/main.tscn" id="1_gr7ev"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
name = "Default Map 2"
|
||||||
|
scene = ExtResource("1_gr7ev")
|
||||||
@ -1,3 +1,7 @@
|
|||||||
[gd_scene format=3 uid="uid://bii6018k3ip3t"]
|
[gd_scene format=3 uid="uid://bii6018k3ip3t"]
|
||||||
|
|
||||||
|
[ext_resource type="Map" uid="uid://b4rw48yjf7q3q" path="res://maps/default_map.tres" id="1_glms7"]
|
||||||
|
[ext_resource type="Map" uid="uid://crti664evgfmj" path="res://maps/default_map_2.tres" id="2_udu3i"]
|
||||||
|
|
||||||
[node name="game_manager" type="GameManager" unique_id=1442044769]
|
[node name="game_manager" type="GameManager" unique_id=1442044769]
|
||||||
|
maps = Array[Map]([ExtResource("1_glms7"), ExtResource("2_udu3i")])
|
||||||
|
|||||||
@ -5,11 +5,12 @@
|
|||||||
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
||||||
font_size = 32
|
font_size = 32
|
||||||
|
|
||||||
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field", "ready_button")]
|
[node name="lobby" type="LobbyPanel" unique_id=915192272 node_paths=PackedStringArray("players_list", "name_field", "ready_button", "map_selection")]
|
||||||
players_list = NodePath("v_box_container/players_list")
|
players_list = NodePath("v_box_container/players_list")
|
||||||
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
||||||
player_listing_prefab = ExtResource("1_o1atq")
|
player_listing_prefab = ExtResource("1_o1atq")
|
||||||
ready_button = NodePath("ready_button")
|
ready_button = NodePath("ready_button")
|
||||||
|
map_selection = NodePath("v_box_container2/option_button")
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
@ -73,3 +74,13 @@ offset_top = 504.0
|
|||||||
offset_right = 278.0
|
offset_right = 278.0
|
||||||
offset_bottom = 555.0
|
offset_bottom = 555.0
|
||||||
text = "Not Ready"
|
text = "Not Ready"
|
||||||
|
|
||||||
|
[node name="v_box_container2" type="VBoxContainer" parent="." unique_id=653902328]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_left = 716.0
|
||||||
|
offset_top = 146.0
|
||||||
|
offset_right = 824.0
|
||||||
|
offset_bottom = 204.0
|
||||||
|
|
||||||
|
[node name="option_button" type="OptionButton" parent="v_box_container2" unique_id=426342653]
|
||||||
|
layout_mode = 2
|
||||||
|
|||||||
@ -3,6 +3,8 @@ use std::net::SocketAddr;
|
|||||||
use godot::{prelude::*, tools::get_autoload_by_name};
|
use godot::{prelude::*, tools::get_autoload_by_name};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::map_resource::Map;
|
||||||
|
|
||||||
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
||||||
|
|
||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
@ -10,6 +12,9 @@ pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
|||||||
pub struct GameManager {
|
pub struct GameManager {
|
||||||
pub game: Option<Gd<Game>>,
|
pub game: Option<Gd<Game>>,
|
||||||
base: Base<Node>,
|
base: Base<Node>,
|
||||||
|
|
||||||
|
#[export]
|
||||||
|
pub maps: Array<Gd<Map>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
@ -20,6 +25,8 @@ impl GameManager {
|
|||||||
pub fn on_new_player(id: u16);
|
pub fn on_new_player(id: u16);
|
||||||
#[signal]
|
#[signal]
|
||||||
pub fn on_player_disconnected(id: u16);
|
pub fn on_player_disconnected(id: u16);
|
||||||
|
#[signal]
|
||||||
|
pub fn on_map_changed(id: u8);
|
||||||
|
|
||||||
pub fn singleton() -> Gd<GameManager> {
|
pub fn singleton() -> Gd<GameManager> {
|
||||||
get_autoload_by_name::<GameManager>(GAME_MANAGER_GLOBAL)
|
get_autoload_by_name::<GameManager>(GAME_MANAGER_GLOBAL)
|
||||||
@ -31,6 +38,7 @@ impl GameManager {
|
|||||||
}
|
}
|
||||||
let mut game = Game::new_alloc();
|
let mut game = Game::new_alloc();
|
||||||
game.bind_mut().is_host = is_host;
|
game.bind_mut().is_host = is_host;
|
||||||
|
game.bind_mut().maps = self.maps.clone();
|
||||||
|
|
||||||
self.run_deferred(|s| {
|
self.run_deferred(|s| {
|
||||||
if let Some(game) = &s.game {
|
if let Some(game) = &s.game {
|
||||||
@ -43,6 +51,9 @@ impl GameManager {
|
|||||||
game.signals()
|
game.signals()
|
||||||
.on_players_updated()
|
.on_players_updated()
|
||||||
.connect_other(s, |s| s.signals().on_players_updated().emit());
|
.connect_other(s, |s| s.signals().on_players_updated().emit());
|
||||||
|
game.signals()
|
||||||
|
.on_map_changed()
|
||||||
|
.connect_other(s, |s, id| s.signals().on_map_changed().emit(id));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -55,10 +66,15 @@ impl GameManager {
|
|||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(base=Node, init)]
|
#[class(base=Node, init)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
|
pub selected_map_idx: u8,
|
||||||
|
pub selected_map: Option<Gd<Map>>,
|
||||||
|
pub maps: Array<Gd<Map>>,
|
||||||
|
|
||||||
is_host: bool,
|
is_host: bool,
|
||||||
player_counter: u16,
|
player_counter: u16,
|
||||||
pub self_id: Option<u16>,
|
pub self_id: Option<u16>,
|
||||||
pub players: Vec<Player>,
|
pub players: Vec<Player>,
|
||||||
|
game_started: bool,
|
||||||
|
|
||||||
base: Base<Node>,
|
base: Base<Node>,
|
||||||
}
|
}
|
||||||
@ -71,6 +87,8 @@ impl Game {
|
|||||||
pub fn on_new_player(id: u16);
|
pub fn on_new_player(id: u16);
|
||||||
#[signal]
|
#[signal]
|
||||||
pub fn on_player_disconnected(id: u16);
|
pub fn on_player_disconnected(id: u16);
|
||||||
|
#[signal]
|
||||||
|
pub fn on_map_changed(id: u8);
|
||||||
|
|
||||||
pub fn singleton() -> Option<Gd<Game>> {
|
pub fn singleton() -> Option<Gd<Game>> {
|
||||||
GameManager::singleton()
|
GameManager::singleton()
|
||||||
@ -78,6 +96,26 @@ impl Game {
|
|||||||
.map(|g| g.cast::<Game>())
|
.map(|g| g.cast::<Game>())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_map_selection(&mut self, map_idx: u8, emit: bool) {
|
||||||
|
self.selected_map_idx = map_idx;
|
||||||
|
if let Some(map) = self.maps.get(map_idx as usize) {
|
||||||
|
self.selected_map = Some(map);
|
||||||
|
if emit {
|
||||||
|
self.run_deferred(move |s| s.signals().on_map_changed().emit(map_idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start_game(&mut self) {
|
||||||
|
self.game_started = true;
|
||||||
|
godot_print!("{:?}", self.selected_map);
|
||||||
|
if let Some(map) = &self.selected_map {
|
||||||
|
if let Some(scene) = &map.bind().scene {
|
||||||
|
self.base().get_tree().change_scene_to_packed(scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_self(&mut self, id: u16) {
|
pub fn set_self(&mut self, id: u16) {
|
||||||
self.self_id = Some(id);
|
self.self_id = Some(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use std::net::SocketAddr;
|
|||||||
use godot::prelude::*;
|
use godot::prelude::*;
|
||||||
|
|
||||||
pub mod game_manager;
|
pub mod game_manager;
|
||||||
|
pub mod map_resource;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod ui;
|
pub mod ui;
|
||||||
|
|
||||||
|
|||||||
27
rust/src/map_resource.rs
Normal file
27
rust/src/map_resource.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use godot::prelude::*;
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Resource, init, tool)]
|
||||||
|
pub struct Map {
|
||||||
|
#[export]
|
||||||
|
pub name: GString,
|
||||||
|
#[export]
|
||||||
|
pub scene: Option<Gd<PackedScene>>,
|
||||||
|
|
||||||
|
base: Base<Resource>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl IResource for Map {
|
||||||
|
fn on_notification(&mut self, what: godot::classes::notify::ObjectNotification) {}
|
||||||
|
|
||||||
|
fn to_string(&self) -> GString {
|
||||||
|
"Hello there".to_gstring()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup_local_to_scene(&mut self) {}
|
||||||
|
|
||||||
|
fn reset_state(&mut self) {}
|
||||||
|
|
||||||
|
fn set_path_cache(&self, path: GString) {}
|
||||||
|
}
|
||||||
@ -196,6 +196,17 @@ impl INode for NetworkManager {
|
|||||||
.update_player_ready(player_id, is_ready);
|
.update_player_ready(player_id, is_ready);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Package::SelectMap(map_id) => {
|
||||||
|
if let Some(game) = &mut Game::singleton() {
|
||||||
|
game.bind_mut().change_map_selection(map_id, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Package::GameStarted => {
|
||||||
|
if let Some(game) = &mut Game::singleton() {
|
||||||
|
godot_print!("Game started");
|
||||||
|
game.bind_mut().start_game();
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -236,6 +247,11 @@ impl INode for NetworkManager {
|
|||||||
sent_player.connection_addr =
|
sent_player.connection_addr =
|
||||||
SocketAddr::from(([0, 0, 0, 0], 0));
|
SocketAddr::from(([0, 0, 0, 0], 0));
|
||||||
peer.broadcast_reliable(Package::NewPlayer(sent_player));
|
peer.broadcast_reliable(Package::NewPlayer(sent_player));
|
||||||
|
|
||||||
|
peer.send_reliable(
|
||||||
|
&connection.address,
|
||||||
|
Package::SelectMap(game.bind().selected_map_idx),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
teanet::PeerMessage::Disconnected(connection, connection_error) => {
|
teanet::PeerMessage::Disconnected(connection, connection_error) => {
|
||||||
@ -416,6 +432,8 @@ pub enum Package {
|
|||||||
NewPlayer(Player),
|
NewPlayer(Player),
|
||||||
PlayerLeft(Player),
|
PlayerLeft(Player),
|
||||||
SetReady(u16, bool),
|
SetReady(u16, bool),
|
||||||
|
SelectMap(u8),
|
||||||
|
GameStarted,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum PeerKind {
|
pub enum PeerKind {
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use godot::{
|
use godot::{
|
||||||
classes::{Button, IPanel, Label, Panel, TextEdit, VBoxContainer},
|
classes::{Button, IPanel, Label, OptionButton, Panel, TextEdit, VBoxContainer},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game_manager::{Game, GameManager},
|
game_manager::{Game, GameManager},
|
||||||
|
map_resource::Map,
|
||||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
net::network_manager::{NetworkManager, Package, PeerKind},
|
||||||
ui::player_listing::PlayerListing,
|
ui::player_listing::PlayerListing,
|
||||||
};
|
};
|
||||||
@ -20,6 +21,8 @@ pub struct LobbyPanel {
|
|||||||
player_listing_prefab: Option<Gd<PackedScene>>,
|
player_listing_prefab: Option<Gd<PackedScene>>,
|
||||||
#[export]
|
#[export]
|
||||||
ready_button: Option<Gd<Button>>,
|
ready_button: Option<Gd<Button>>,
|
||||||
|
#[export]
|
||||||
|
map_selection: Option<Gd<OptionButton>>,
|
||||||
|
|
||||||
is_ready: bool,
|
is_ready: bool,
|
||||||
|
|
||||||
@ -41,6 +44,10 @@ impl IPanel for LobbyPanel {
|
|||||||
.signals()
|
.signals()
|
||||||
.on_players_updated()
|
.on_players_updated()
|
||||||
.connect_other(self, |s| s.update_players(false));
|
.connect_other(self, |s| s.update_players(false));
|
||||||
|
GameManager::singleton()
|
||||||
|
.signals()
|
||||||
|
.on_map_changed()
|
||||||
|
.connect_other(self, |s, id| s.update_map_selection(id));
|
||||||
|
|
||||||
if let Some(ready_button) = &self.ready_button {
|
if let Some(ready_button) = &self.ready_button {
|
||||||
ready_button
|
ready_button
|
||||||
@ -48,6 +55,30 @@ impl IPanel for LobbyPanel {
|
|||||||
.pressed()
|
.pressed()
|
||||||
.connect_other(self, |s| s.on_ready());
|
.connect_other(self, |s| s.on_ready());
|
||||||
}
|
}
|
||||||
|
if let Some(map_selection) = &self.map_selection {
|
||||||
|
map_selection
|
||||||
|
.signals()
|
||||||
|
.item_selected()
|
||||||
|
.connect_other(self, |s, id| {
|
||||||
|
s.update_map_selection(id as u8);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(game) = Game::singleton() {
|
||||||
|
if let Some(map_selection) = &mut self.map_selection {
|
||||||
|
for map in game.bind().maps.iter_shared() {
|
||||||
|
map_selection.add_item(&map.bind().name);
|
||||||
|
}
|
||||||
|
let is_host = if let Some(peer) = &NetworkManager::singleton().bind().peer {
|
||||||
|
peer.is_host()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
map_selection.set_disabled(!is_host);
|
||||||
|
map_selection.select(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.update_map_selection(0);
|
||||||
|
|
||||||
if let Some(name_field) = &self.name_field {
|
if let Some(name_field) = &self.name_field {
|
||||||
name_field
|
name_field
|
||||||
@ -143,8 +174,29 @@ impl LobbyPanel {
|
|||||||
|
|
||||||
peer.send_reliable(socket_addr, Package::SetReady(0, self.is_ready));
|
peer.send_reliable(socket_addr, Package::SetReady(0, self.is_ready));
|
||||||
}
|
}
|
||||||
PeerKind::Server(_, _) => {
|
PeerKind::Server(peer, _) => {
|
||||||
godot_print!("Start game!");
|
if let Some(game) = &mut Game::singleton() {
|
||||||
|
game.bind_mut().start_game();
|
||||||
|
}
|
||||||
|
peer.broadcast_reliable(Package::GameStarted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_map_selection(&mut self, idx: u8) {
|
||||||
|
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||||
|
match peer {
|
||||||
|
PeerKind::Client(..) => {
|
||||||
|
if let Some(map_selection) = &mut self.map_selection {
|
||||||
|
map_selection.select(idx as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PeerKind::Server(peer, _) => {
|
||||||
|
if let Some(game) = &mut Game::singleton() {
|
||||||
|
game.bind_mut().change_map_selection(idx, false);
|
||||||
|
}
|
||||||
|
peer.broadcast_reliable(Package::SelectMap(idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 4d843d2ccb5566a4bc7dc4f3af2bdf181ebf0c38
|
Subproject commit a947f3a8cbad03b939dedfc1486de75226d90c0a
|
||||||
Loading…
Reference in New Issue
Block a user