~starkingdoms/starkingdoms

494c0b1ca0e58be47c24cf6fd937b57dea1cd1f5 — ghostly_zsh 9 months ago f82ad4c
player and parts rendering, but jk it doesnt work
M crates/client/src/ecs.rs => crates/client/src/ecs.rs +7 -0
@@ 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)]

M crates/client/src/lib.rs => crates/client/src/lib.rs +14 -7
@@ 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::<SendPacket>::default();
    let mut send_packet_events = Events::<SendPacket>::default();
    let recv_packet_events = Events::<RecvPacket>::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();
                    });
                    });*/
            });
    }
}

M crates/client/src/networking/mod.rs => crates/client/src/networking/mod.rs +72 -0
@@ 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<SendPacket>,
    recv_packet_events: &mut Events<RecvPacket>,
    planet_types: &mut HashMap<PlanetType, (Entity, u32)>,
) {
    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<Player>>();
                        let mut camera = world.resource_mut::<Camera>();
                        /*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<Planet>>();
                    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);
                    }
                }
            }
            _ => {}
        }
    }
}

M crates/client/src/networking/ws_wasm.rs => crates/client/src/networking/ws_wasm.rs +6 -4
@@ 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");
        });
    }
}

M crates/client/src/rendering/assets_wasm.rs => crates/client/src/rendering/assets_wasm.rs +11 -4
@@ 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

M crates/client/src/rendering/renderer.rs => crates/client/src/rendering/renderer.rs +88 -46
@@ 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<T: UiRenderable> {

    pub size: PhysicalSize<u32>,
    pub logical_size: LogicalSize<u32>,

    pub planet_types: HashMap<PlanetType, (Entity, u32)>, // (world entity, server id)
}

#[allow(clippy::large_enum_variant)]


@@ 210,6 216,7 @@ impl<T: UiRenderable> Renderer<T> {
            local_uniform,
            size,
            surface_configuration: format,
            planet_types: HashMap::new(),
        })
    }



@@ 227,6 234,8 @@ impl<T: UiRenderable> Renderer<T> {
        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<T: UiRenderable> Renderer<T> {
        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::<Assets>().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::<impl 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::<impl 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::<Assets>().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::<impl 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<T: UiRenderable> Renderer<T> {
        let mut ws = self.world.get_resource_mut::<Ws>().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();