Add simple pause menu

This commit is contained in:
Sofia 2026-07-23 20:10:31 +03:00
parent febc555f38
commit a98c9d2e55
3 changed files with 79 additions and 5 deletions

View File

@ -83,6 +83,11 @@ shoot={
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
] ]
} }
pause={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[physics] [physics]

View File

@ -8,7 +8,7 @@ glow_enabled = true
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node")] [node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node", "pause_panel", "exit_to_lobby")]
look_sensitivity = 1.5 look_sensitivity = 1.5
camera = NodePath("camera_3d") camera = NodePath("camera_3d")
move_speed = 5.0 move_speed = 5.0
@ -19,6 +19,8 @@ dead_cam_target = NodePath("dead_camera_target")
respawn_label = NodePath("respawn_label") respawn_label = NodePath("respawn_label")
ball_origin = NodePath("camera_3d") ball_origin = NodePath("camera_3d")
weapon_node = NodePath("camera_3d/weapon_node") weapon_node = NodePath("camera_3d/weapon_node")
pause_panel = NodePath("pause_menu")
exit_to_lobby = NodePath("pause_menu/v_box_container/exit_to_lobby")
health = 100 health = 100
collision_mask = 4 collision_mask = 4
@ -68,3 +70,40 @@ offset_right = 20.0
offset_bottom = 58.0 offset_bottom = 58.0
grow_horizontal = 2 grow_horizontal = 2
alignment = 1 alignment = 1
[node name="pause_menu" type="Panel" parent="." unique_id=1542204162]
visible = false
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -67.75
offset_top = -101.25
offset_right = 67.75
offset_bottom = 101.25
grow_horizontal = 2
grow_vertical = 2
[node name="v_box_container" type="VBoxContainer" parent="pause_menu" unique_id=839758321]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -20.0
offset_right = 20.0
offset_bottom = 20.0
grow_horizontal = 2
grow_vertical = 2
alignment = 1
[node name="exit_to_lobby" type="Button" parent="pause_menu/v_box_container" unique_id=1816170399]
layout_mode = 2
text = "Exit to Lobby"
[node name="exit" type="Button" parent="pause_menu/v_box_container" unique_id=641638697]
layout_mode = 2
text = "Exit"

View File

@ -2,8 +2,8 @@ use std::{f32::consts::PI, ops::Neg};
use godot::{ use godot::{
classes::{ classes::{
Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D, Input, Button, Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D,
InputEvent, InputEventMouseMotion, Label, Label3D, input::MouseMode, Input, InputEvent, InputEventMouseMotion, Label, Label3D, Panel, input::MouseMode,
}, },
obj::WithBaseField, obj::WithBaseField,
prelude::*, prelude::*,
@ -191,6 +191,10 @@ pub struct LocalPlayer {
#[export] #[export]
weapon_node: Option<Gd<Node3D>>, weapon_node: Option<Gd<Node3D>>,
#[export] #[export]
pause_panel: Option<Gd<Panel>>,
#[export]
exit_to_lobby: Option<Gd<Button>>,
#[export]
health: i32, health: i32,
pub player_id: Option<u16>, pub player_id: Option<u16>,
@ -378,12 +382,12 @@ impl ICharacterBody3D for LocalPlayer {
CommandLinePanel::singleton() CommandLinePanel::singleton()
.signals() .signals()
.on_open() .on_open()
.connect_other(self, |s| s.set_lock(false)); .connect_other(self, |s| s.update_lock());
CommandLinePanel::singleton() CommandLinePanel::singleton()
.signals() .signals()
.on_close() .on_close()
.connect_other(self, |s| { .connect_other(self, |s| {
s.set_lock(true); s.update_lock();
}); });
self.swap_weapon(WeaponType::Raygun); self.swap_weapon(WeaponType::Raygun);
@ -397,6 +401,12 @@ impl ICharacterBody3D for LocalPlayer {
{ {
remover.bind_mut().active = true; remover.bind_mut().active = true;
} }
self.run_deferred(|s| {
if let Some(exit_to_lobby) = &mut s.exit_to_lobby {
exit_to_lobby.set_visible(NetworkManager::singleton().bind().is_host());
}
});
} }
fn process(&mut self, delta: f64) { fn process(&mut self, delta: f64) {
@ -472,6 +482,15 @@ impl ICharacterBody3D for LocalPlayer {
} }
fn input(&mut self, event: Gd<InputEvent>) { fn input(&mut self, event: Gd<InputEvent>) {
if event.is_action_pressed("pause") {
godot_print!("pause");
if let Some(pause_panel) = &mut self.pause_panel {
let is_visible = pause_panel.is_visible();
pause_panel.set_visible(!is_visible);
self.update_lock();
}
}
if self.locked { if self.locked {
if event.is_action_pressed("shoot") { if event.is_action_pressed("shoot") {
let pos = if let Some(camera) = &self.camera { let pos = if let Some(camera) = &self.camera {
@ -551,6 +570,17 @@ impl LocalPlayer {
#[signal] #[signal]
pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32); pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32);
fn update_lock(&mut self) {
self.run_deferred(|s| {
let paused = if let Some(panel) = &s.pause_panel {
panel.is_visible()
} else {
false
};
s.set_lock(!CommandLinePanel::singleton().bind().opened && !paused);
});
}
fn set_lock(&mut self, locked: bool) { fn set_lock(&mut self, locked: bool) {
self.locked = locked; self.locked = locked;
if self.locked { if self.locked {