From 494c0b1ca0e58be47c24cf6fd937b57dea1cd1f5 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Sun, 2 Mar 2025 01:43:27 -0600 Subject: [PATCH] player and parts rendering, but jk it doesnt work --- crates/client/src/ecs.rs | 7 ++ crates/client/src/lib.rs | 21 ++-- crates/client/src/networking/mod.rs | 72 +++++++++++ crates/client/src/networking/ws_wasm.rs | 10 +- crates/client/src/rendering/assets_wasm.rs | 15 ++- crates/client/src/rendering/renderer.rs | 134 ++++++++++++++------- 6 files changed, 198 insertions(+), 61 deletions(-) diff --git a/crates/client/src/ecs.rs b/crates/client/src/ecs.rs index 98697409b85cef17aa904a120d42793fc68434e9..8879b7ebdc3c82e97ac1d61c900bf9cc9e967c48 100644 --- a/crates/client/src/ecs.rs +++ b/crates/client/src/ecs.rs @@ -4,6 +4,7 @@ use bevy_ecs::event::Event; use bevy_ecs::system::Resource; use nalgebra::Matrix3; use starkingdoms_common::packet::Packet; +use starkingdoms_common::PlanetType; #[derive(Component, Debug, Clone, Copy)] pub struct Translation { @@ -88,6 +89,12 @@ pub struct Camera { pub zoom: f32, } +#[derive(Component, Debug, Clone, Copy)] +pub struct Player; + +#[derive(Component, Debug, Clone, Copy)] +pub struct Planet(PlanetType); + #[derive(Event, Clone, PartialEq)] pub struct SendPacket(pub Packet); #[derive(Event, Clone, PartialEq)] diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index c4a283d9903b01013a4870bc1fcd239d00f230a2..cdec437c84e09565dbafd88535fbf7433f6c221e 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -6,10 +6,11 @@ use bevy_ecs::event::{EventReader, Events}; use bevy_ecs::schedule::Schedule; use bevy_ecs::system::ResMut; use bevy_ecs::world::World; -use ecs::{RecvPacket, SendPacket, Shear}; +use ecs::{Player, RecvPacket, SendPacket, Shear}; use egui::{Context, DragValue}; use networking::ws::Ws; use rendering::assets::Assets; +use starkingdoms_common::packet::Packet; use tracing::info; use winit::event_loop::{ControlFlow, EventLoop}; @@ -51,7 +52,7 @@ pub fn start() { world.insert_resource(Assets::new()); world.insert_resource(Ws::new()); - let send_packet_events = Events::::default(); + let mut send_packet_events = Events::::default(); let recv_packet_events = Events::::default(); let mut start_schedule = Schedule::default(); @@ -64,7 +65,13 @@ pub fn start() { // Caution: This will run once before there are things on screen update_schedule.add_systems(zoom_camera_on_mouse_events); - world.spawn(SpriteBundle { + send_packet_events.send(SendPacket(Packet::ClientLogin { + username: String::new(), + save: None, + jwt: None, + })); + + world.spawn((SpriteBundle { position: Translation { x: 100.0, y: 100.0 @@ -78,12 +85,12 @@ pub fn start() { height: 100.0, }, rotation: Rotation { - radians: 45.0_f32.to_radians() + radians: 0.0_f32.to_radians() }, texture: SpriteTexture { texture: "hearty".to_string(), }, - }); + }, Player)); let event_loop = EventLoop::new().unwrap(); event_loop.set_control_flow(ControlFlow::Poll); @@ -120,7 +127,7 @@ impl UiRenderable for Gui { ui.separator(); let mut sprites = world.query::<(&mut Translation, &mut Shear, &mut Scale, &SpriteTexture, &mut Rotation)>(); - for (mut pos, mut shear, mut scale, tex, mut rot) in sprites.iter_mut(world) { + /*for (mut pos, mut shear, mut scale, tex, mut rot) in sprites.iter_mut(world) { ui.heading(&tex.texture); egui::Grid::new("sprite_grid") @@ -180,7 +187,7 @@ impl UiRenderable for Gui { ui.label("Camera Zoom"); ui.add(DragValue::new(&mut camera.zoom).speed(0.1)); ui.end_row(); - }); + });*/ }); } } diff --git a/crates/client/src/networking/mod.rs b/crates/client/src/networking/mod.rs index df5ea3202602c5840202e3db641640a74fc9f50e..115a7b6f28dbfba46161f1c4ef64f77722f2fb6c 100644 --- a/crates/client/src/networking/mod.rs +++ b/crates/client/src/networking/mod.rs @@ -1,6 +1,78 @@ +use std::collections::HashMap; + +use bevy_ecs::{entity::Entity, event::Events, query::With, world::World}; +use starkingdoms_common::{packet::Packet, PartType, PlanetType}; + +use crate::ecs::{Camera, Planet, Player, RecvPacket, Rotation, Scale, SendPacket, Shear, SpriteBundle, SpriteTexture, Translation}; + #[cfg(target_arch = "wasm32")] #[path = "ws_wasm.rs"] pub mod ws; #[cfg(not(target_arch = "wasm32"))] #[path = "ws_native.rs"] pub mod ws; + +pub fn process_packets( + world: &mut World, + send_packet_events: &mut Events, + recv_packet_events: &mut Events, + planet_types: &mut HashMap, +) { + use Packet::*; + let mut recv_cursor = recv_packet_events.get_cursor(); + for recv in recv_cursor.read(&recv_packet_events) { + match &recv.0 { + PartPositions { parts } => { + for (id, part) in parts { + if part.part_type == PartType::Hearty { + let mut player_query = world.query_filtered::<(&mut Translation, &mut Rotation), With>(); + let mut camera = world.resource_mut::(); + /*camera.x = part.transform.x; + camera.y = part.transform.y;*/ + camera.x = 0.0; + camera.y = 1.0; + tracing::info!("camera real {:?}", camera); + for (mut translation, mut rotation) in player_query.iter_mut(world) { + translation.x = 0.0; + translation.y = 1.0; + //rotation.radians = part.transform.rot; + tracing::info!("part real {:?}", translation); + } + tracing::info!("part {:?}", part.transform); + } + } + } + PlanetPositions { planets } => { + for (server_id, planet) in planets { + let mut planet_query = world.query_filtered::<(&mut Translation, &mut Rotation), With>(); + if !planet_types.contains_key(&planet.planet_type) { + let entity = world.spawn(SpriteBundle { + position: Translation { x: planet.transform.x, y: planet.transform.y }, + shear: Shear { x: 0.0, y: 0.0 }, + rotation: Rotation { radians: planet.transform.rot }, + scale: Scale { width: planet.radius, height: planet.radius }, + texture: SpriteTexture { + texture: match planet.planet_type { + PlanetType::Sun => "sun", + PlanetType::Mercury => "mercury", + PlanetType::Venus => "venus", + PlanetType::Earth => "earth", + PlanetType::Moon => "moon", + PlanetType::Mars => "mars", + PlanetType::Jupiter => "jupiter", + PlanetType::Saturn => "saturn", + PlanetType::Uranus => "uranus", + PlanetType::Neptune => "neptune", + PlanetType::Pluto => "pluto", + }.to_string() + }, + }); + planet_types.insert(planet.planet_type, (entity.id(), *server_id)); + tracing::info!("{:?}", planet.transform); + } + } + } + _ => {} + } + } +} diff --git a/crates/client/src/networking/ws_wasm.rs b/crates/client/src/networking/ws_wasm.rs index 4d57ec6432f837efb4c2720d7dd1c5da90bf1d29..48a94ee8d14e786c14515728c747ee65ec8e10e5 100644 --- a/crates/client/src/networking/ws_wasm.rs +++ b/crates/client/src/networking/ws_wasm.rs @@ -1,5 +1,3 @@ -use std::{any::Any, cell::{OnceCell, RefCell}, rc::Rc, sync::{Arc, Mutex, RwLock}}; - use bevy_ecs::system::Resource; //use crossbeam::channel::{unbounded, Receiver, Sender}; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, SinkExt}; @@ -63,7 +61,11 @@ impl Ws { self.socket.0.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server"); } } - pub fn send_packet(&mut self, packet: &Packet) { - self.socket.0.send_with_str(&serde_json::to_string(packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server"); + pub fn send_packet(&mut self, packet: Packet) { + let socket = self.socket.0.clone(); + spawn_local(async move { + while socket.ready_state() != 1 {} + socket.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server"); + }); } } diff --git a/crates/client/src/rendering/assets_wasm.rs b/crates/client/src/rendering/assets_wasm.rs index e3db11cad3cb3d3bb7d044e42049b6622b0f2a94..ab94ab82336c34166338f9142b4ff7ae43ed2ba5 100644 --- a/crates/client/src/rendering/assets_wasm.rs +++ b/crates/client/src/rendering/assets_wasm.rs @@ -52,7 +52,9 @@ impl Assets { }; if !contains_texture && !contains_texture_receiver { let textures = self.textures.clone(); - self.texture_receivers.lock().unwrap().insert(local_path.clone(), rx); + { + self.texture_receivers.lock().unwrap().insert(local_path.clone(), rx); + } spawn_local(async move { let window = web_sys::window().unwrap(); let resp = match reqwest::get(format!("{}/src/textures/{}", window.location().origin().unwrap(), local_path)).await { @@ -83,7 +85,7 @@ impl Assets { default_size: usvg::Size::from_wh(20.0, 20.0).unwrap(), ..Default::default() }; - let tree = usvg::Tree::from_data(&bytes, &opt).expect("Couldn't parse svg"); + let tree = usvg::Tree::from_data(&bytes, &opt).expect(&format!("Couldn't parse svg {}", local_path)); let tree_size = tree.size().to_int_size(); let size = usvg::Size::from_wh(100.0, 100.0).unwrap().to_int_size(); assert!(size.width() > 0 && size.height() > 0); @@ -95,7 +97,9 @@ impl Assets { height: size.height(), }; - textures.lock().unwrap().insert(local_path, data.clone()); + { + textures.lock().unwrap().insert(local_path, data.clone()); + } tx.send(data).unwrap(); } else if local_path.ends_with(".png") { let img = image::load_from_memory(&bytes).unwrap(); @@ -105,7 +109,9 @@ impl Assets { width: rgba.width(), height: rgba.height(), }; - textures.lock().unwrap().insert(local_path, data.clone()); + { + textures.lock().unwrap().insert(local_path, data.clone()); + } tx.send(data).unwrap(); } }); @@ -115,6 +121,7 @@ impl Assets { let rx = texture_receivers.get_mut(&local_path).unwrap(); if let Ok(Some(texture)) = rx.try_recv() { self.texture_receivers.lock().unwrap().remove(&local_path); + self.textures.lock().unwrap().insert(local_path, texture.clone()); return Some(texture); } None diff --git a/crates/client/src/rendering/renderer.rs b/crates/client/src/rendering/renderer.rs index e5675427706d45d49db102456d616c1e3b223ff7..6db434c780dc215271c115082b29bd9f22bedaf8 100644 --- a/crates/client/src/rendering/renderer.rs +++ b/crates/client/src/rendering/renderer.rs @@ -1,15 +1,19 @@ use crate::ecs::{Camera, RecvPacket, Rotation, Scale, SendPacket, Shear, SpriteTexture, Translation}; +use crate::networking::process_packets; use crate::networking::ws::Ws; use crate::rendering::assets::Assets; use crate::rendering::mipmap::MipGenerator; use crate::rendering::renderer::RenderInitRes::{Initialized, NotReadyYet}; use crate::rendering::texture; use crate::rendering::ui::UiRenderable; +use bevy_ecs::entity::Entity; use bevy_ecs::event::Events; use bevy_ecs::schedule::Schedule; use bevy_ecs::world::World; use egui::ViewportId; -use std::collections::HashMap; +use starkingdoms_common::PlanetType; +use std::collections::hash_map::Entry; +use std::collections::{HashMap, HashSet}; use std::fmt::{Debug, Formatter}; use std::sync::Arc; use tracing::info; @@ -60,6 +64,8 @@ pub struct Renderer { pub size: PhysicalSize, pub logical_size: LogicalSize, + + pub planet_types: HashMap, // (world entity, server id) } #[allow(clippy::large_enum_variant)] @@ -210,6 +216,7 @@ impl Renderer { local_uniform, size, surface_configuration: format, + planet_types: HashMap::new(), }) } @@ -227,6 +234,8 @@ impl Renderer { self.update_schedule.run(&mut self.world); self.send_packet_events.update(); self.recv_packet_events.update(); + + process_packets(&mut self.world, &mut self.send_packet_events, &mut self.recv_packet_events, &mut self.planet_types); // update the UI let egui_output = self .gui_ctx @@ -290,51 +299,84 @@ impl Renderer { self.queue.write_buffer(&self.frame_uniform, 0, &frame_uniform); for (pos, shear, scale, tex, rot) in sprites_to_render { - let tex = self.textures.entry(tex.texture.clone()).or_insert({ - info!("loading texture {}", &tex.texture); - let assets = self.world.get_resource::().unwrap(); - let b = match tex.texture.as_str() { - "f" => match assets.get("f.png") { - Some(b) => b, - None => continue, - } - "happy-tree" => match assets.get("happy-tree.png") { - Some(b) => b, - None => continue, - } - "uv" => match assets.get("uv.png") { - Some(b) => b, - None => continue, - } - "hearty" => match assets.get("hearty.svg") { - Some(b) => b, - None => continue, - } - "earth" => match assets.get("earth.svg") { - Some(b) => b, - None => continue, - } - "mars" => match assets.get("mars.svg") { - Some(b) => b, - None => continue, - } - u => panic!("unknown texture {u}, has it been added in rendering::renderer::::render()?") - }; - /*let b: &[u8] = match tex.texture.as_str() { - "f" => include_bytes!("../textures/f.png"), - "happy-tree" => include_bytes!("../textures/happy-tree.png"), - "uv" => include_bytes!("../textures/uv.png"), - u => panic!("unknown texture {u}, has it been added in rendering::renderer::::render()?") - };*/ - texture::Texture::new( - b, - &tex.texture, - &self.device, - &self.queue, - &mut self.mip_generator, - ) - }); + let tex = match self.textures.entry(tex.texture.clone()) { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => { + let assets = self.world.get_resource::().unwrap(); + let b = match tex.texture.as_str() { + "f" => match assets.get("f.png") { + Some(b) => b, + None => continue, + } + "happy-tree" => match assets.get("happy-tree.png") { + Some(b) => b, + None => continue, + } + "uv" => match assets.get("uv.png") { + Some(b) => b, + None => continue, + } + "hearty" => match assets.get("hearty.svg") { + Some(b) => b, + None => continue, + } + "sun" => match assets.get("sun.svg") { + Some(b) => b, + None => continue, + } + "mercury" => match assets.get("moon.svg") { + Some(b) => b, + None => continue, + } + "venus" => match assets.get("mars.svg") { + Some(b) => b, + None => continue, + } + "earth" => match assets.get("earth.svg") { + Some(b) => b, + None => continue, + } + "moon" => match assets.get("moon.svg") { + Some(b) => b, + None => continue, + } + "mars" => match assets.get("mars.svg") { + Some(b) => b, + None => continue, + } + "jupiter" => match assets.get("sun.svg") { + Some(b) => b, + None => continue, + } + "saturn" => match assets.get("moon.svg") { + Some(b) => b, + None => continue, + } + "uranus" => match assets.get("earth.svg") { + Some(b) => b, + None => continue, + } + "neptune" => match assets.get("moon.svg") { + Some(b) => b, + None => continue, + } + "pluto" => match assets.get("mars.svg") { + Some(b) => b, + None => continue, + } + u => panic!("unknown texture {u}, has it been added in rendering::renderer::::render()?") + }; + entry.insert(texture::Texture::new( + b, + &tex.texture, + &self.device, + &self.queue, + &mut self.mip_generator, + )) + } + }; + info!("render: {:?}", pos); let xy_matrix = pos.as_matrix(); let shear_matrix = shear.as_matrix(); let rot_matrix = rot.as_matrix(); @@ -435,7 +477,7 @@ impl Renderer { let mut ws = self.world.get_resource_mut::().expect("Failed to get Ws resource"); let mut send_event_cursor = self.send_packet_events.get_cursor(); for event in send_event_cursor.read(&self.send_packet_events) { - ws.send_packet(&event.0); + ws.send_packet(event.0.clone()); } let buffer = encoder.finish();