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"]
|
||||
|
||||
[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]
|
||||
maps = Array[Map]([ExtResource("1_glms7"), ExtResource("2_udu3i")])
|
||||
|
||||
@ -5,11 +5,12 @@
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
|
||||
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")
|
||||
name_field = NodePath("v_box_container/h_box_container/text_edit")
|
||||
player_listing_prefab = ExtResource("1_o1atq")
|
||||
ready_button = NodePath("ready_button")
|
||||
map_selection = NodePath("v_box_container2/option_button")
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
@ -73,3 +74,13 @@ offset_top = 504.0
|
||||
offset_right = 278.0
|
||||
offset_bottom = 555.0
|
||||
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 serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::map_resource::Map;
|
||||
|
||||
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
||||
|
||||
#[derive(GodotClass)]
|
||||
@ -10,6 +12,9 @@ pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
||||
pub struct GameManager {
|
||||
pub game: Option<Gd<Game>>,
|
||||
base: Base<Node>,
|
||||
|
||||
#[export]
|
||||
pub maps: Array<Gd<Map>>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
@ -20,6 +25,8 @@ impl GameManager {
|
||||
pub fn on_new_player(id: u16);
|
||||
#[signal]
|
||||
pub fn on_player_disconnected(id: u16);
|
||||
#[signal]
|
||||
pub fn on_map_changed(id: u8);
|
||||
|
||||
pub fn singleton() -> Gd<GameManager> {
|
||||
get_autoload_by_name::<GameManager>(GAME_MANAGER_GLOBAL)
|
||||
@ -31,6 +38,7 @@ impl GameManager {
|
||||
}
|
||||
let mut game = Game::new_alloc();
|
||||
game.bind_mut().is_host = is_host;
|
||||
game.bind_mut().maps = self.maps.clone();
|
||||
|
||||
self.run_deferred(|s| {
|
||||
if let Some(game) = &s.game {
|
||||
@ -43,6 +51,9 @@ impl GameManager {
|
||||
game.signals()
|
||||
.on_players_updated()
|
||||
.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)]
|
||||
#[class(base=Node, init)]
|
||||
pub struct Game {
|
||||
pub selected_map_idx: u8,
|
||||
pub selected_map: Option<Gd<Map>>,
|
||||
pub maps: Array<Gd<Map>>,
|
||||
|
||||
is_host: bool,
|
||||
player_counter: u16,
|
||||
pub self_id: Option<u16>,
|
||||
pub players: Vec<Player>,
|
||||
game_started: bool,
|
||||
|
||||
base: Base<Node>,
|
||||
}
|
||||
@ -71,6 +87,8 @@ impl Game {
|
||||
pub fn on_new_player(id: u16);
|
||||
#[signal]
|
||||
pub fn on_player_disconnected(id: u16);
|
||||
#[signal]
|
||||
pub fn on_map_changed(id: u8);
|
||||
|
||||
pub fn singleton() -> Option<Gd<Game>> {
|
||||
GameManager::singleton()
|
||||
@ -78,6 +96,26 @@ impl 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) {
|
||||
self.self_id = Some(id);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ use std::net::SocketAddr;
|
||||
use godot::prelude::*;
|
||||
|
||||
pub mod game_manager;
|
||||
pub mod map_resource;
|
||||
pub mod net;
|
||||
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);
|
||||
}
|
||||
}
|
||||
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 =
|
||||
SocketAddr::from(([0, 0, 0, 0], 0));
|
||||
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) => {
|
||||
@ -416,6 +432,8 @@ pub enum Package {
|
||||
NewPlayer(Player),
|
||||
PlayerLeft(Player),
|
||||
SetReady(u16, bool),
|
||||
SelectMap(u8),
|
||||
GameStarted,
|
||||
}
|
||||
|
||||
pub enum PeerKind {
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
use godot::{
|
||||
classes::{Button, IPanel, Label, Panel, TextEdit, VBoxContainer},
|
||||
classes::{Button, IPanel, Label, OptionButton, Panel, TextEdit, VBoxContainer},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
game_manager::{Game, GameManager},
|
||||
map_resource::Map,
|
||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
||||
ui::player_listing::PlayerListing,
|
||||
};
|
||||
@ -20,6 +21,8 @@ pub struct LobbyPanel {
|
||||
player_listing_prefab: Option<Gd<PackedScene>>,
|
||||
#[export]
|
||||
ready_button: Option<Gd<Button>>,
|
||||
#[export]
|
||||
map_selection: Option<Gd<OptionButton>>,
|
||||
|
||||
is_ready: bool,
|
||||
|
||||
@ -41,6 +44,10 @@ impl IPanel for LobbyPanel {
|
||||
.signals()
|
||||
.on_players_updated()
|
||||
.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 {
|
||||
ready_button
|
||||
@ -48,6 +55,30 @@ impl IPanel for LobbyPanel {
|
||||
.pressed()
|
||||
.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 {
|
||||
name_field
|
||||
@ -143,8 +174,29 @@ impl LobbyPanel {
|
||||
|
||||
peer.send_reliable(socket_addr, Package::SetReady(0, self.is_ready));
|
||||
}
|
||||
PeerKind::Server(_, _) => {
|
||||
godot_print!("Start game!");
|
||||
PeerKind::Server(peer, _) => {
|
||||
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