This commit is contained in:
Sofia 2026-07-21 20:31:39 +03:00
parent 25fe3e5ae6
commit b57d31065a
13 changed files with 118 additions and 23 deletions

View File

@ -2,6 +2,7 @@
[ext_resource type="PackedScene" uid="uid://ct70bpbca8one" path="res://scenes/player/local_player.tscn" id="1_yjvui"]
[ext_resource type="PackedScene" uid="uid://kfxc0migw80o" path="res://scenes/player/remote_player.tscn" id="2_kcncr"]
[ext_resource type="PackedScene" uid="uid://dfnbc8sbufa4j" path="res://scenes/misc/ball.tscn" id="3_e0nj3"]
[sub_resource type="ImageTexture" id="ImageTexture_3vyb7"]
@ -14,10 +15,12 @@ size = Vector2(100, 100)
[sub_resource type="BoxShape3D" id="BoxShape3D_1cgct"]
size = Vector3(100, 0.01, 100)
[node name="map" type="Map" unique_id=914577955 node_paths=PackedStringArray("spawner")]
[node name="map" type="Map" unique_id=914577955 node_paths=PackedStringArray("spawner", "ball_spawner")]
spawner = NodePath("spawner")
ball_spawner = NodePath("ball_spawner")
local_player = ExtResource("1_yjvui")
remote_player = ExtResource("2_kcncr")
ball = ExtResource("3_e0nj3")
[node name="net_stats_label" type="NetStatsLabel" parent="." unique_id=1821474986]
anchors_preset = 2
@ -44,3 +47,6 @@ transform = Transform3D(1, 0, 0, 0, 0.7274598, 0.6861503, 0, -0.6861503, 0.72745
[node name="spawner" type="Node3D" parent="." unique_id=1364438299]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.028572083, 3.9666176, 0.031027317)
[node name="ball_spawner" type="Node3D" parent="." unique_id=1149426253]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.080344, 4.78083, -9.363691)

View File

@ -1,6 +1,6 @@
[gd_scene format=3 uid="uid://bwd6bj21x310s"]
[ext_resource type="PackedScene" uid="uid://ccd0wj2usx5os" path="res://scenes/player_listing.tscn" id="1_o1atq"]
[ext_resource type="PackedScene" uid="uid://ccd0wj2usx5os" path="res://scenes/ui/player_listing.tscn" id="1_o1atq"]
[sub_resource type="LabelSettings" id="LabelSettings_1cgct"]
font_size = 32

View File

@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://dfnbc8sbufa4j"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_yxhor"]
noise_type = 2
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_yli5f"]
noise = SubResource("FastNoiseLite_yxhor")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3g557"]
albedo_color = Color(0, 1, 0, 1)
albedo_texture = SubResource("NoiseTexture2D_yli5f")
[sub_resource type="SphereMesh" id="SphereMesh_1cgct"]
material = SubResource("StandardMaterial3D_3g557")
[sub_resource type="SphereShape3D" id="SphereShape3D_1cgct"]
[node name="ball" type="Ball" unique_id=816748600]
collision_layer = 4
collision_mask = 7
[node name="mesh_instance_3d" type="MeshInstance3D" parent="." unique_id=2076561614]
mesh = SubResource("SphereMesh_1cgct")
[node name="collision_shape_3d" type="CollisionShape3D" parent="." unique_id=1408432914]
shape = SubResource("SphereShape3D_1cgct")

18
rust/src/ball.rs Normal file
View File

@ -0,0 +1,18 @@
use godot::{classes::RigidBody3D, prelude::*};
use crate::player::NetTransform;
#[derive(GodotClass)]
#[class(base=RigidBody3D, init)]
pub struct Ball {
base: Base<RigidBody3D>,
}
impl Ball {
pub fn get_transform(&self) -> NetTransform {
NetTransform {
location: self.base().get_global_position().into(),
rotation: self.base().get_global_rotation().into(),
}
}
}

View File

@ -14,7 +14,7 @@ use crate::{
},
util::NetVector3,
},
player::{DamageSource, IPlayer, LocalPlayer, NetPlayerTransform, RemotePlayer},
player::{DamageSource, IPlayer, LocalPlayer, NetTransform, RemotePlayer},
};
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
@ -300,11 +300,26 @@ impl Game {
for player in s.players.clone() {
s.spawn_player_server(player.id);
}
s.spawn_ball(None);
});
}
}
}
pub fn spawn_ball(&mut self, transform: Option<NetTransform>) {
if let Some(map) = &mut self.current_map {
let ball = map.bind_mut().spawn_ball(transform);
self.run_deferred(|_| {
if let Some(ball) = ball
&& let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer
{
peer.broadcast_reliable(Package::SpawnBall(ball.bind().get_transform()));
}
});
}
}
pub fn spawn_player_server(&mut self, id: u16) -> Option<DynGd<CharacterBody3D, dyn IPlayer>> {
if let Some(player) = self.find_player_mut(id)
&& let Some(character) = &mut player.character
@ -360,7 +375,7 @@ impl Game {
}
// Method called on the client-side whenever a player has spawned
pub fn spawn_player_client(&mut self, id: u16, transform: NetPlayerTransform) {
pub fn spawn_player_client(&mut self, id: u16, transform: NetTransform) {
if let Some(map) = &mut self.current_map {
if let Some(player) = self.players.iter_mut().find(|p| p.id == id) {
if let Some(character) = &mut player.character {
@ -423,7 +438,7 @@ impl Game {
&mut self,
player_id: u16,
to: Vector3,
transform: NetPlayerTransform,
transform: NetTransform,
look_up: f32,
deal_damage: bool,
) -> bool {
@ -487,7 +502,7 @@ pub struct Player {
}
impl Player {
pub fn get_transform(&self) -> Option<NetPlayerTransform> {
pub fn get_transform(&self) -> Option<NetTransform> {
if let Some(character) = &self.character {
Some(character.dyn_bind().get_transform())
} else {
@ -495,7 +510,7 @@ impl Player {
}
}
pub fn set_transform(&mut self, transform: NetPlayerTransform) {
pub fn set_transform(&mut self, transform: NetTransform) {
if let Some(character) = &mut self.character {
character.dyn_bind_mut().apply_transform(transform);
}
@ -562,7 +577,7 @@ impl Player {
pub fn try_shoot(
&mut self,
to: Vector3,
transform: NetPlayerTransform,
transform: NetTransform,
look_up: f32,
deal_damage: bool,
) -> bool {

View File

@ -1,5 +1,6 @@
use godot::prelude::*;
pub mod ball;
pub mod game_manager;
pub mod killbox;
pub mod map;

View File

@ -1,8 +1,9 @@
use godot::{classes::CharacterBody3D, prelude::*};
use crate::{
ball::Ball,
game_manager::Game,
player::{IPlayer, LocalPlayer, NetPlayerTransform, RemotePlayer},
player::{IPlayer, LocalPlayer, NetTransform, RemotePlayer},
};
#[derive(GodotClass)]
@ -11,9 +12,13 @@ pub struct Map {
#[export]
pub spawner: Option<Gd<Node3D>>,
#[export]
pub ball_spawner: Option<Gd<Node3D>>,
#[export]
pub local_player: Option<Gd<PackedScene>>,
#[export]
pub remote_player: Option<Gd<PackedScene>>,
#[export]
pub ball: Option<Gd<PackedScene>>,
base: Base<Node3D>,
}
@ -36,7 +41,7 @@ impl Map {
&mut self,
player_id: u16,
is_local: bool,
transform: Option<NetPlayerTransform>,
transform: Option<NetTransform>,
) -> Option<DynGd<CharacterBody3D, dyn IPlayer + 'static>> {
if is_local {
if let Some(local_player) = &self.local_player {
@ -84,4 +89,22 @@ impl Map {
None
}
}
pub fn spawn_ball(&mut self, transform: Option<NetTransform>) -> Option<Gd<Ball>> {
if let Some(ball_spawner) = self.ball_spawner.clone()
&& let Some(ball_prefab) = &self.ball
{
let mut ball = ball_prefab.instantiate_as::<Ball>();
self.base_mut().add_child(&ball);
if let Some(transform) = transform {
ball.set_global_position(transform.location.into());
ball.set_global_rotation(transform.rotation.into());
} else {
ball.set_global_position(ball_spawner.get_global_position());
}
Some(ball)
} else {
None
}
}
}

View File

@ -11,7 +11,7 @@ use teanet::{Peer, PeerConfig};
use crate::{
game_manager::{Game, GameManager, NetPlayer},
net::{net_stats::Stats, util::NetVector3},
player::{DamageSource, NetPlayerTransform},
player::{DamageSource, NetTransform},
ui::cli::{CliColor, CommandLinePanel},
};
@ -257,6 +257,11 @@ impl INode for NetworkManager {
.handle_kill(source_player_id, target_player_id);
}
}
Package::SpawnBall(transform) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().spawn_ball(Some(transform));
}
}
_ => {}
},
}
@ -567,20 +572,21 @@ pub enum Package {
MapLoaded,
// Game packages
SpawnPlayer(u16, NetPlayerTransform),
SpawnPlayer(u16, NetTransform),
Sync(HashMap<u16, SyncPackage>),
SelfSync(SyncPackage),
Jump(u16),
Shoot(u16, NetVector3, NetPlayerTransform, f32),
Shoot(u16, NetVector3, NetTransform, f32),
TakeDamage(DamageSource, u16, i32),
Kill(DamageSource, u16),
SpawnBall(NetTransform),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncPackage {
pub movement_direction: NetVector3,
pub look_up: f32,
pub transform: NetPlayerTransform,
pub transform: NetTransform,
}
pub enum PeerKind {

View File

@ -26,7 +26,7 @@ use crate::{
};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct NetPlayerTransform {
pub struct NetTransform {
pub location: NetVector3,
pub rotation: NetVector3,
}
@ -38,11 +38,11 @@ pub trait IPlayer {
fn get_movement_dir(&self) -> Vector3;
fn set_movement_dir(&mut self, dir: Vector3);
fn get_move_speed(&self) -> f32;
fn apply_transform(&mut self, transform: NetPlayerTransform);
fn apply_transform(&mut self, transform: NetTransform);
fn apply_rotation(&mut self, rot: Vector3);
fn apply_look_up(&mut self, rot: f32);
fn get_look_up(&self) -> f32;
fn get_transform(&self) -> NetPlayerTransform;
fn get_transform(&self) -> NetTransform;
fn jump(&mut self);
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
fn take_damage(&mut self, source_player: DamageSource, damage: i32, kill: bool);
@ -143,7 +143,7 @@ impl IPlayer for LocalPlayer {
self.move_speed
}
fn apply_transform(&mut self, transform: NetPlayerTransform) {
fn apply_transform(&mut self, transform: NetTransform) {
self.base_mut()
.set_global_position(transform.location.into());
self.base_mut()
@ -152,8 +152,8 @@ impl IPlayer for LocalPlayer {
fn apply_rotation(&mut self, _rot: Vector3) {}
fn get_transform(&self) -> NetPlayerTransform {
NetPlayerTransform {
fn get_transform(&self) -> NetTransform {
NetTransform {
location: self.base().get_global_position().into(),
rotation: self.base().get_global_rotation().into(),
}
@ -470,7 +470,7 @@ impl IPlayer for RemotePlayer {
self.player_id
}
fn apply_transform(&mut self, transform: NetPlayerTransform) {
fn apply_transform(&mut self, transform: NetTransform) {
self.base_mut()
.set_global_position(transform.location.into());
self.base_mut()
@ -481,8 +481,8 @@ impl IPlayer for RemotePlayer {
self.base_mut().set_global_rotation(rot);
}
fn get_transform(&self) -> NetPlayerTransform {
NetPlayerTransform {
fn get_transform(&self) -> NetTransform {
NetTransform {
location: self.base().get_global_position().into(),
rotation: self.base().get_global_rotation().into(),
}