M crates/client/src/components.rs => crates/client/src/components.rs +21 -7
@@ 15,7 15,9 @@ pub struct Transform {
}
impl Transform {
pub fn to_matrix(&self) -> Matrix4<f32> {
- self.translation.to_homogeneous() * self.rotation.to_homogeneous().to_homogeneous() * self.scale.to_homogeneous()
+ self.translation.to_homogeneous()
+ * self.rotation.to_homogeneous().to_homogeneous()
+ * self.scale.to_homogeneous()
}
}
@@ 30,7 32,7 @@ pub struct Camera {
pub x: f32,
pub y: f32,
pub zoom: f32,
- pub width: u32, // screen width (these are for aspect ratio)
+ pub width: u32, // screen width (these are for aspect ratio)
pub height: u32, // screen height
}
impl Camera {
@@ 38,17 40,29 @@ impl Camera {
let x_scale = self.zoom / self.width as f32 * 2.0;
let y_scale = self.zoom / self.height as f32 * 2.0;
Matrix4::from_vec(vec![
- x_scale, 0.0, 0.0, 0.0,
- 0.0, y_scale, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- self.x*x_scale, self.y*y_scale, 0.0, 1.0,
+ x_scale,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ y_scale,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ self.x * x_scale,
+ self.y * y_scale,
+ 0.0,
+ 1.0,
])
}
pub fn to_cursor_matrix(&self) -> Matrix3<f32> {
let x = -(self.width as f32 / 2.0);
let y = -(self.height as f32 / 2.0);
Translation2::new(-self.x, -self.y).to_homogeneous()
- * Scale2::new(1.0/self.zoom, 1.0/self.zoom).to_homogeneous()
+ * Scale2::new(1.0 / self.zoom, 1.0 / self.zoom).to_homogeneous()
* Translation2::new(x, y).to_homogeneous()
}
}
M crates/client/src/lib.rs => crates/client/src/lib.rs +16 -7
@@ 14,9 14,9 @@ pub mod platform;
#[path = "native/mod.rs"]
pub mod platform;
-pub mod rendering;
pub mod components;
pub mod networking;
+pub mod rendering;
// Hi, you've found the real main function! This is called AFTER platform-specific initialization code.
pub fn start() {
@@ 47,14 47,23 @@ pub fn start() {
let mut send_packet_events = Events::<SendPacket>::default();
let recv_packet_events = Events::<RecvPacket>::default();
- world.spawn((Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- }, Texture { name: "hearty.svg".to_string() }, Player, Part(false)));
+ world.spawn((
+ Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ Texture {
+ name: "hearty.svg".to_string(),
+ },
+ Player,
+ Part(false),
+ ));
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Wait);
- event_loop.run_app(&mut App::new(world, send_packet_events, recv_packet_events)).unwrap();
+ event_loop
+ .run_app(&mut App::new(world, send_packet_events, recv_packet_events))
+ .unwrap();
}
M crates/client/src/networking/mod.rs => crates/client/src/networking/mod.rs +71 -32
@@ 1,10 1,18 @@
use std::collections::HashMap;
-use bevy_ecs::{entity::Entity, event::Events, query::{QuerySingleError, With}, world::World};
+use bevy_ecs::{
+ entity::Entity,
+ event::Events,
+ query::{QuerySingleError, With},
+ world::World,
+};
use nalgebra::{Rotation2, Scale2, Scale3, Translation3};
use starkingdoms_common::{packet::Packet, PartType, PlanetType};
-use crate::components::{Camera, Part, Planet, Player, RecvPacket, SendPacket, ServerId, SpriteBundle, Texture, Transform};
+use crate::components::{
+ Camera, Part, Planet, Player, RecvPacket, SendPacket, ServerId, SpriteBundle, Texture,
+ Transform,
+};
#[cfg(target_arch = "wasm32")]
#[path = "ws_wasm.rs"]
@@ 23,7 31,8 @@ fn texture_name(part_type: PartType, attached: bool) -> String {
Hub => "hub_on.svg",
LandingThruster => "landingthruster_on.svg",
LandingThrusterSuspension => "landingleg.svg",
- }.to_string()
+ }
+ .to_string()
} else {
match part_type {
Placeholder => panic!("AHHHH PLACEHOLDER PANIC"),
@@ 32,7 41,8 @@ fn texture_name(part_type: PartType, attached: bool) -> String {
Hub => "hub_off.svg",
LandingThruster => "landingthruster_off.svg",
LandingThrusterSuspension => "landingleg.svg",
- }.to_string()
+ }
+ .to_string()
}
}
@@ 53,36 63,52 @@ pub fn process_packets(
let entity = player_query.single(world);
world.entity_mut(entity).insert(ServerId(*id));
}
- PlayerList { players } => { // existing players
+ PlayerList { players } => {
+ // existing players
// username sync, eventually
for player in players {
- world.spawn((Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- }, Texture {
- name: "hearty.svg".to_string(),
- }, ServerId(player.0), Part(false)));
+ world.spawn((
+ Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ Texture {
+ name: "hearty.svg".to_string(),
+ },
+ ServerId(player.0),
+ Part(false),
+ ));
}
}
SpawnPlayer { id, username } => {
// username sync, eventually
- world.spawn((Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- }, Texture {
- name: "hearty.svg".to_string(),
- }, ServerId(*id), Part(false)));
+ world.spawn((
+ Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ Texture {
+ name: "hearty.svg".to_string(),
+ },
+ ServerId(*id),
+ Part(false),
+ ));
}
SpawnPart { id, part } => {
- world.spawn((Transform {
- translation: Translation3::new(part.transform.x, part.transform.y, 0.0),
- rotation: Rotation2::new(part.transform.rot),
- scale: Scale3::new(25.0, 25.0, 1.0),
- }, Texture {
- name: texture_name(part.part_type, part.flags.attached),
- }, ServerId(*id), Part(part.flags.attached)));
+ world.spawn((
+ Transform {
+ translation: Translation3::new(part.transform.x, part.transform.y, 0.0),
+ rotation: Rotation2::new(part.transform.rot),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ Texture {
+ name: texture_name(part.part_type, part.flags.attached),
+ },
+ ServerId(*id),
+ Part(part.flags.attached),
+ ));
}
PartPositions { parts } => {
for (id, part) in parts {
@@ 97,7 123,7 @@ pub fn process_packets(
QuerySingleError::MultipleEntities(s) => {
panic!("There should never multiple players marked as players");
}
- }
+ },
};
if server_id.0 == *id {
let mut camera = world.resource_mut::<Camera>();
@@ 105,8 131,13 @@ pub fn process_packets(
camera.y = -part.transform.y;
}
}
- let mut part_query = world.query::<(Entity, &ServerId, &mut Transform, &mut Texture, &mut Part)>();
- for (entity, server_id, mut transform, mut texture, mut bevy_part) in part_query.iter_mut(world) {
+ let mut part_query =
+ world
+ .query::<(Entity, &ServerId, &mut Transform, &mut Texture, &mut Part)>(
+ );
+ for (entity, server_id, mut transform, mut texture, mut bevy_part) in
+ part_query.iter_mut(world)
+ {
if server_id.0 == *id {
transform.translation.x = part.transform.x;
transform.translation.y = part.transform.y;
@@ 129,7 160,11 @@ pub fn process_packets(
if !planet_types.contains_key(&planet.planet_type) {
let entity = world.spawn(SpriteBundle {
transform: Transform {
- translation: Translation3::new(planet.transform.x, planet.transform.y, 0.0),
+ translation: Translation3::new(
+ planet.transform.x,
+ planet.transform.y,
+ 0.0,
+ ),
rotation: Rotation2::new(planet.transform.rot),
scale: Scale3::new(planet.radius, planet.radius, 1.0),
},
@@ 157,14 192,18 @@ pub fn process_packets(
PlanetType::Uranus => "venus.svg",
PlanetType::Neptune => "mars.svg",
PlanetType::Pluto => "earth.svg",
- }.to_string()
+ }
+ .to_string(),
},
});
planet_types.insert(planet.planet_type, (entity.id(), *server_id));
}
}
}
- EnergyUpdate { amount: m_amount, max: m_max } => {
+ EnergyUpdate {
+ amount: m_amount,
+ max: m_max,
+ } => {
*amount = *m_amount;
*max = *m_max;
}
M crates/client/src/networking/ws_native.rs => crates/client/src/networking/ws_native.rs +22 -5
@@ 1,4 1,7 @@
-use std::{net::TcpStream, sync::{Arc, Mutex}};
+use std::{
+ net::TcpStream,
+ sync::{Arc, Mutex},
+};
use bevy_ecs::system::Resource;
use crossbeam::channel::{unbounded, Receiver, Sender};
@@ 22,7 25,11 @@ impl PacketMessageConvert for Packet {
}
}
fn into_message(&self) -> Message {
- Message::Text(serde_json::to_string(self).expect("failed to serialize packet to json").into())
+ Message::Text(
+ serde_json::to_string(self)
+ .expect("failed to serialize packet to json")
+ .into(),
+ )
}
}
@@ 43,9 50,15 @@ impl Ws {
std::thread::spawn(move || {
let socket = socket_clone;
loop {
- let message = socket.lock().unwrap().read().expect("Failed to reading message");
+ let message = socket
+ .lock()
+ .unwrap()
+ .read()
+ .expect("Failed to reading message");
let packet = Packet::from_message(&message).expect("Server sent invalid packet");
- packet_sender.send(packet).expect("Couldn't send packet to server");
+ packet_sender
+ .send(packet)
+ .expect("Couldn't send packet to server");
}
});
Ws {
@@ 56,6 69,10 @@ impl Ws {
}
}
pub fn send_packet(&mut self, packet: &Packet) {
- self.socket.lock().unwrap().send(packet.into_message()).expect("Couldn't send packet to server");
+ self.socket
+ .lock()
+ .unwrap()
+ .send(packet.into_message())
+ .expect("Couldn't send packet to server");
}
}
M crates/client/src/networking/ws_wasm.rs => crates/client/src/networking/ws_wasm.rs +37 -10
@@ 2,11 2,14 @@ use std::thread::yield_now;
use bevy_ecs::system::Resource;
//use crossbeam::channel::{unbounded, Receiver, Sender};
-use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, SinkExt};
+use futures::{
+ channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender},
+ SinkExt,
+};
+use starkingdoms_common::packet::Packet;
use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
use wasm_bindgen_futures::spawn_local;
use web_sys::{MessageEvent, WebSocket};
-use starkingdoms_common::packet::Packet;
const PORT: u16 = 3000;
@@ 26,8 29,12 @@ pub struct Ws {
impl Ws {
pub fn new() -> Self {
let window = web_sys::window().unwrap();
- let ws = WebSocket::new(&format!("ws://{}:{}",
- window.location().hostname().unwrap(), PORT)).expect("Couldn't connect to server");
+ let ws = WebSocket::new(&format!(
+ "ws://{}:{}",
+ window.location().hostname().unwrap(),
+ PORT
+ ))
+ .expect("Couldn't connect to server");
let (packet_sender, receiver) = unbounded();
//let packet_sender = Rc::new(RwLock::new(packet_sender));
let (sender, packet_receiver) = unbounded();
@@ 40,17 47,28 @@ impl Ws {
jwt: None,
};
- ws_clone.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to string")).expect("Failed to send packet");
+ ws_clone
+ .send_with_str(
+ &serde_json::to_string(&packet).expect("Couldn't convert packet to string"),
+ )
+ .expect("Failed to send packet");
});
ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
onopen_callback.forget();
let onmessage_callback = Closure::<dyn FnMut(_)>::new(move |e: MessageEvent| {
//tracing::error!("{}", ws.ready_state());
- let data = e.data().as_string().expect("Expected string, found some other type");
- let data: Packet = serde_json::from_str(&data).expect("Received invalid json from server");
+ let data = e
+ .data()
+ .as_string()
+ .expect("Expected string, found some other type");
+ let data: Packet =
+ serde_json::from_str(&data).expect("Received invalid json from server");
let mut sender_clone = packet_sender.clone();
spawn_local(async move {
- sender_clone.send(data).await.expect("Couldn't transmit packet to client");
+ sender_clone
+ .send(data)
+ .await
+ .expect("Couldn't transmit packet to client");
});
});
ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
@@ 65,14 83,23 @@ impl Ws {
pub fn send_all_packets_from_channel(&mut self) {
//for packet in self.packet_receiver.iter() {
while let Ok(Some(packet)) = self.packet_receiver.try_next() {
- 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");
+ 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");
+ 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_native.rs => crates/client/src/rendering/assets_native.rs +15 -9
@@ 11,12 11,10 @@ pub struct ImgData {
}
#[derive(Resource)]
-pub struct Assets {
-
-}
+pub struct Assets {}
impl Assets {
pub fn new() -> Self {
- Assets { }
+ Assets {}
}
pub fn get(&self, local_path: impl Into<String>) -> Option<ImgData> {
let local_path = local_path.into();
@@ 26,18 24,27 @@ impl Assets {
default_size: usvg::Size::from_wh(20.0, 20.0).unwrap(),
..Default::default()
};
- let tree = usvg::Tree::from_data(&bytes, &opt).expect(&format!("Couldn't parse svg {}", local_path));
+ 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(200.0, 200.0).unwrap().to_int_size();
assert!(size.width() > 0 && size.height() > 0);
- let mut pixmap = tiny_skia::Pixmap::new(size.width(), size.height()).expect("Failed to construct pixmap");
- resvg::render(&tree, tiny_skia::Transform::from_scale((size.width() as f32)/(tree_size.height() as f32), (size.height() as f32)/(tree_size.height() as f32)), &mut pixmap.as_mut());
+ let mut pixmap = tiny_skia::Pixmap::new(size.width(), size.height())
+ .expect("Failed to construct pixmap");
+ resvg::render(
+ &tree,
+ tiny_skia::Transform::from_scale(
+ (size.width() as f32) / (tree_size.height() as f32),
+ (size.height() as f32) / (tree_size.height() as f32),
+ ),
+ &mut pixmap.as_mut(),
+ );
let data = ImgData {
bytes: pixmap.data().to_vec(),
width: size.width(),
height: size.height(),
};
-
+
Some(data)
} else if local_path.ends_with(".png") {
let img = image::load_from_memory(&bytes).unwrap();
@@ 53,4 60,3 @@ impl Assets {
}
}
}
-
M crates/client/src/rendering/assets_wasm.rs => crates/client/src/rendering/assets_wasm.rs +38 -14
@@ 1,4 1,8 @@
-use std::{collections::HashMap, fmt::Display, sync::{Arc, Mutex}};
+use std::{
+ collections::HashMap,
+ fmt::Display,
+ sync::{Arc, Mutex},
+};
use bevy_ecs::system::Resource;
use image::EncodableLayout;
@@ 42,40 46,54 @@ impl Assets {
}
pub fn get(&self, local_path: impl Into<String>) -> Option<ImgData> {
let local_path = local_path.into();
- let contains_texture = {
- self.textures.lock().unwrap().contains_key(&local_path)
- };
+ let contains_texture = { self.textures.lock().unwrap().contains_key(&local_path) };
let contains_texture_promise = {
- self.texture_promises.lock().unwrap().contains_key(&local_path)
+ self.texture_promises
+ .lock()
+ .unwrap()
+ .contains_key(&local_path)
};
if !contains_texture && !contains_texture_promise {
let local_path_clone = local_path.clone();
let request_promise = poll_promise::Promise::spawn_local(async move {
let window = web_sys::window().unwrap();
- let request = ehttp::Request::get(format!("{}/src/assets/{}", window.location().origin().unwrap(), local_path_clone));
+ let request = ehttp::Request::get(format!(
+ "{}/src/assets/{}",
+ window.location().origin().unwrap(),
+ local_path_clone
+ ));
let response = match ehttp::fetch_async(request).await {
Ok(resp) => resp,
Err(e) => {
panic!("{}", e);
- },
+ }
};
if local_path_clone.ends_with(".svg") {
let opt = usvg::Options {
default_size: usvg::Size::from_wh(20.0, 20.0).unwrap(),
..Default::default()
};
- let tree = usvg::Tree::from_data(&response.bytes, &opt).expect(&format!("Couldn't parse svg {}", local_path_clone));
+ let tree = usvg::Tree::from_data(&response.bytes, &opt)
+ .expect(&format!("Couldn't parse svg {}", local_path_clone));
let tree_size = tree.size().to_int_size();
let size = usvg::Size::from_wh(512.0, 512.0).unwrap().to_int_size();
assert!(size.width() > 0 && size.height() > 0);
- let mut pixmap = tiny_skia::Pixmap::new(size.width(), size.height()).expect("Failed to construct pixmap");
- resvg::render(&tree, tiny_skia::Transform::from_scale((size.width() as f32)/(tree_size.height() as f32), (size.height() as f32)/(tree_size.height() as f32)), &mut pixmap.as_mut());
+ let mut pixmap = tiny_skia::Pixmap::new(size.width(), size.height())
+ .expect("Failed to construct pixmap");
+ resvg::render(
+ &tree,
+ tiny_skia::Transform::from_scale(
+ (size.width() as f32) / (tree_size.height() as f32),
+ (size.height() as f32) / (tree_size.height() as f32),
+ ),
+ &mut pixmap.as_mut(),
+ );
let data = ImgData {
bytes: pixmap.data().to_vec(),
width: size.width(),
height: size.height(),
};
-
+
data
} else if local_path_clone.ends_with(".png") {
let img = image::load_from_memory(&response.bytes).unwrap();
@@ 91,7 109,10 @@ impl Assets {
}
});
{
- self.texture_promises.lock().unwrap().insert(local_path.clone(), request_promise);
+ self.texture_promises
+ .lock()
+ .unwrap()
+ .insert(local_path.clone(), request_promise);
}
None
} else if !contains_texture {
@@ 99,11 120,14 @@ impl Assets {
let promise = texture_promises.get_mut(&local_path).unwrap();
let mut returned_value = None;
if let Some(texture) = promise.ready() {
- self.textures.lock().unwrap().insert(local_path.clone(), texture.clone());
+ self.textures
+ .lock()
+ .unwrap()
+ .insert(local_path.clone(), texture.clone());
returned_value = Some(texture.clone());
texture_promises.remove(&local_path);
}
- return returned_value
+ return returned_value;
} else {
self.textures.lock().unwrap().get(&local_path).cloned()
}
M crates/client/src/rendering/mod.rs => crates/client/src/rendering/mod.rs +283 -118
@@ 11,9 11,14 @@ use egui::{Label, ProgressBar};
use egui_glow::EguiGlow;
use glow::{HasContext, PixelUnpackData};
#[cfg(not(target_arch = "wasm32"))]
-use glutin::surface::{Surface, WindowSurface, GlSurface, SwapInterval};
+use glutin::surface::{GlSurface, Surface, SwapInterval, WindowSurface};
#[cfg(not(target_arch = "wasm32"))]
-use glutin::{config::{ConfigTemplateBuilder, GlConfig}, context::{ContextApi, ContextAttributesBuilder, PossiblyCurrentContext}, display::GetGlDisplay, prelude::{GlDisplay, NotCurrentGlContext}};
+use glutin::{
+ config::{ConfigTemplateBuilder, GlConfig},
+ context::{ContextApi, ContextAttributesBuilder, PossiblyCurrentContext},
+ display::GetGlDisplay,
+ prelude::{GlDisplay, NotCurrentGlContext},
+};
#[cfg(not(target_arch = "wasm32"))]
use glutin_winit::{DisplayBuilder, GlWindow};
use nalgebra::{Vector3, Vector4};
@@ 29,15 34,22 @@ use winit::event_loop::ControlFlow;
use winit::keyboard::{KeyCode, PhysicalKey};
#[cfg(target_arch = "wasm32")]
use winit::platform::web::{WindowAttributesExtWebSys, WindowExtWebSys};
-use winit::{application::ApplicationHandler, dpi::LogicalSize, event::WindowEvent, event_loop::ActiveEventLoop, raw_window_handle::HasWindowHandle, window::{Window, WindowAttributes}};
+use winit::{
+ application::ApplicationHandler,
+ dpi::LogicalSize,
+ event::WindowEvent,
+ event_loop::ActiveEventLoop,
+ raw_window_handle::HasWindowHandle,
+ window::{Window, WindowAttributes},
+};
use crate::components::{Camera, Player, RecvPacket, SendPacket, Texture, Transform};
use crate::networking::process_packets;
use crate::networking::ws::Ws;
-#[cfg(not(target_arch="wasm32"))]
+#[cfg(not(target_arch = "wasm32"))]
#[path = "assets_native.rs"]
pub mod assets;
-#[cfg(target_arch="wasm32")]
+#[cfg(target_arch = "wasm32")]
#[path = "assets_wasm.rs"]
pub mod assets;
@@ 73,21 85,15 @@ pub struct App {
}
const VERTICES: [f32; 16] = [
- -1.0, -1.0, 0.0, 1.0,
- 1.0, -1.0, 1.0, 1.0,
- 1.0, 1.0, 1.0, 0.0,
- -1.0, 1.0, 0.0, 0.0,
-];
-const INDICES: [u32; 6] = [
- 0, 1, 2,
- 2, 3, 0,
+ -1.0, -1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0,
];
+const INDICES: [u32; 6] = [0, 1, 2, 2, 3, 0];
impl App {
pub fn new(
world: World,
send_packet_events: Events<SendPacket>,
- recv_packet_events: Events<RecvPacket>
+ recv_packet_events: Events<RecvPacket>,
) -> Self {
Self {
world,
@@ 104,28 110,53 @@ impl ApplicationHandler for App {
let attributes = {
let document = web_sys::window().unwrap().document().unwrap();
let canvas = document.get_element_by_id("canvas").unwrap();
- let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>()
- .map_err(|_| ()).unwrap();
- canvas.set_width(web_sys::window().unwrap().inner_width().unwrap().as_f64().unwrap() as u32);
- canvas.set_height(web_sys::window().unwrap().inner_height().unwrap().as_f64().unwrap() as u32);
+ let canvas = canvas
+ .dyn_into::<web_sys::HtmlCanvasElement>()
+ .map_err(|_| ())
+ .unwrap();
+ canvas.set_width(
+ web_sys::window()
+ .unwrap()
+ .inner_width()
+ .unwrap()
+ .as_f64()
+ .unwrap() as u32,
+ );
+ canvas.set_height(
+ web_sys::window()
+ .unwrap()
+ .inner_height()
+ .unwrap()
+ .as_f64()
+ .unwrap() as u32,
+ );
Window::default_attributes()
.with_title("StarKingdoms.TK")
.with_canvas(Some(canvas))
};
#[cfg(not(target_arch = "wasm32"))]
let attributes = {
- Window::default_attributes().with_transparent(true).with_title("StarKingdoms.TK")
+ Window::default_attributes()
+ .with_transparent(true)
+ .with_title("StarKingdoms.TK")
.with_inner_size(LogicalSize::new(400, 300))
};
self.window = Some(event_loop.create_window(attributes.clone()).unwrap());
let window = self.window.as_ref().unwrap();
#[cfg(target_arch = "wasm32")]
- let context = window.canvas().unwrap().get_context("webgl2")
- .unwrap().unwrap()
+ let context = window
+ .canvas()
+ .unwrap()
+ .get_context("webgl2")
+ .unwrap()
+ .unwrap()
.dyn_into::<web_sys::WebGl2RenderingContext>()
.unwrap();
#[cfg(target_arch = "wasm32")]
- let (gl, shader_version) = (Arc::new(glow::Context::from_webgl2_context(context)), "#version 300 es");
+ let (gl, shader_version) = (
+ Arc::new(glow::Context::from_webgl2_context(context)),
+ "#version 300 es",
+ );
#[cfg(not(target_arch = "wasm32"))]
let (gl, shader_version) = unsafe {
@@ 133,36 164,55 @@ impl ApplicationHandler for App {
let display_builder = DisplayBuilder::new().with_window_attributes(Some(attributes));
- let (window, gl_config) = display_builder.build(event_loop, template, |configs| {
- configs.reduce(|accum, config| {
- let supports_transparency = config.supports_transparency().unwrap_or(false)
- && !accum.supports_transparency().unwrap_or(false);
- if supports_transparency || config.num_samples() > accum.num_samples() {
- config
- } else {
- accum
- }
- }).unwrap()
- }).unwrap();
- let raw_handle = window.as_ref().map(|window| window.window_handle().unwrap().window_handle().unwrap().as_raw());
+ let (window, gl_config) = display_builder
+ .build(event_loop, template, |configs| {
+ configs
+ .reduce(|accum, config| {
+ let supports_transparency =
+ config.supports_transparency().unwrap_or(false)
+ && !accum.supports_transparency().unwrap_or(false);
+ if supports_transparency || config.num_samples() > accum.num_samples() {
+ config
+ } else {
+ accum
+ }
+ })
+ .unwrap()
+ })
+ .unwrap();
+ let raw_handle = window.as_ref().map(|window| {
+ window
+ .window_handle()
+ .unwrap()
+ .window_handle()
+ .unwrap()
+ .as_raw()
+ });
let gl_display = gl_config.display();
let context_attributes = ContextAttributesBuilder::new()
.with_context_api(ContextApi::OpenGl(Some(glutin::context::Version {
major: 3,
minor: 0,
- }))).build(raw_handle);
+ })))
+ .build(raw_handle);
- let not_current_gl_context = gl_display.create_context(&gl_config, &context_attributes).unwrap();
+ let not_current_gl_context = gl_display
+ .create_context(&gl_config, &context_attributes)
+ .unwrap();
let window = window.unwrap();
let surface_attributes = window.build_surface_attributes(Default::default()).unwrap();
- let gl_surface = gl_display.create_window_surface(&gl_config, &surface_attributes).unwrap();
+ let gl_surface = gl_display
+ .create_window_surface(&gl_config, &surface_attributes)
+ .unwrap();
let gl_context = not_current_gl_context.make_current(&gl_surface).unwrap();
let gl = glow::Context::from_loader_function_cstr(|s| gl_display.get_proc_address(s));
- gl_surface.set_swap_interval(&gl_context, SwapInterval::Wait(NonZeroU32::new(1).unwrap())).unwrap();
+ gl_surface
+ .set_swap_interval(&gl_context, SwapInterval::Wait(NonZeroU32::new(1).unwrap()))
+ .unwrap();
self.gl_surface = Some(gl_surface);
self.gl_context = Some(gl_context);
@@ 171,17 221,31 @@ impl ApplicationHandler for App {
};
unsafe {
let shaders = [
- ("vertex", include_str!("../shaders/vertex.glsl"), glow::VERTEX_SHADER),
- ("fragment", include_str!("../shaders/fragment.glsl"), glow::FRAGMENT_SHADER),
+ (
+ "vertex",
+ include_str!("../shaders/vertex.glsl"),
+ glow::VERTEX_SHADER,
+ ),
+ (
+ "fragment",
+ include_str!("../shaders/fragment.glsl"),
+ glow::FRAGMENT_SHADER,
+ ),
];
let program = gl.create_program().expect("Failed to create program");
for (name, source, shader_type) in shaders {
- let shader = gl.create_shader(shader_type).expect("Failed to create vertex shader");
+ let shader = gl
+ .create_shader(shader_type)
+ .expect("Failed to create vertex shader");
gl.shader_source(shader, &format!("{}\n{}", shader_version, source));
gl.compile_shader(shader);
if !gl.get_shader_compile_status(shader) {
- tracing::error!("error in {} shader: {}", name, gl.get_shader_info_log(shader));
+ tracing::error!(
+ "error in {} shader: {}",
+ name,
+ gl.get_shader_info_log(shader)
+ );
}
gl.attach_shader(program, shader);
gl.delete_shader(shader);
@@ 190,27 254,44 @@ impl ApplicationHandler for App {
gl.use_program(Some(program));
- let vertex_array = gl.create_vertex_array().expect("Failed to create vertex array");
+ let vertex_array = gl
+ .create_vertex_array()
+ .expect("Failed to create vertex array");
gl.bind_vertex_array(Some(vertex_array));
let vertex_buffer = gl.create_buffer().expect("Failed to create vertex buffer");
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer));
let element_buffer = gl.create_buffer().expect("Failed to create element buffer");
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(element_buffer));
- gl.buffer_data_u8_slice(glow::ARRAY_BUFFER,
+ gl.buffer_data_u8_slice(
+ glow::ARRAY_BUFFER,
std::slice::from_raw_parts(VERTICES.as_ptr() as *const u8, size_of_val(&VERTICES)),
- glow::STATIC_DRAW);
- gl.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER,
+ glow::STATIC_DRAW,
+ );
+ gl.buffer_data_u8_slice(
+ glow::ELEMENT_ARRAY_BUFFER,
std::slice::from_raw_parts(INDICES.as_ptr() as *const u8, size_of_val(&INDICES)),
- glow::STATIC_DRAW);
+ glow::STATIC_DRAW,
+ );
- gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, 4*size_of::<f32>() as i32, 0);
+ gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, 4 * size_of::<f32>() as i32, 0);
gl.enable_vertex_attrib_array(0);
- gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, 4*size_of::<f32>() as i32, 2*size_of::<f32>() as i32);
+ gl.vertex_attrib_pointer_f32(
+ 1,
+ 2,
+ glow::FLOAT,
+ false,
+ 4 * size_of::<f32>() as i32,
+ 2 * size_of::<f32>() as i32,
+ );
gl.enable_vertex_attrib_array(1);
-
gl.clear_color(0.1, 0.1, 0.1, 1.0);
- gl.viewport(0, 0, window.inner_size().width as i32, window.inner_size().height as i32);
+ gl.viewport(
+ 0,
+ 0,
+ window.inner_size().width as i32,
+ window.inner_size().height as i32,
+ );
gl.enable(glow::BLEND);
gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA);
@@ 220,14 301,35 @@ impl ApplicationHandler for App {
self.element_buffer = Some(element_buffer);
}
#[cfg(target_arch = "wasm32")]
- web_sys::window().unwrap().set_onresize(Some(Closure::<dyn Fn(Event)>::new(move |_| {
- let document = web_sys::window().unwrap().document().unwrap();
- let canvas = document.get_element_by_id("canvas").unwrap();
- let canvas = canvas.dyn_into::<web_sys::HtmlCanvasElement>()
- .map_err(|_| ()).unwrap();
- canvas.set_width(web_sys::window().unwrap().inner_width().unwrap().as_f64().unwrap() as u32);
- canvas.set_height(web_sys::window().unwrap().inner_height().unwrap().as_f64().unwrap() as u32);
- }).into_js_value().as_ref().unchecked_ref()));
+ web_sys::window().unwrap().set_onresize(Some(
+ Closure::<dyn Fn(Event)>::new(move |_| {
+ let document = web_sys::window().unwrap().document().unwrap();
+ let canvas = document.get_element_by_id("canvas").unwrap();
+ let canvas = canvas
+ .dyn_into::<web_sys::HtmlCanvasElement>()
+ .map_err(|_| ())
+ .unwrap();
+ canvas.set_width(
+ web_sys::window()
+ .unwrap()
+ .inner_width()
+ .unwrap()
+ .as_f64()
+ .unwrap() as u32,
+ );
+ canvas.set_height(
+ web_sys::window()
+ .unwrap()
+ .inner_height()
+ .unwrap()
+ .as_f64()
+ .unwrap() as u32,
+ );
+ })
+ .into_js_value()
+ .as_ref()
+ .unchecked_ref(),
+ ));
let egui_glow = egui_glow::EguiGlow::new(event_loop, gl.clone(), None, None, true);
self.egui_glow = Some(egui_glow);
@@ 245,32 347,33 @@ impl ApplicationHandler for App {
}
WindowEvent::Resized(size) => {
#[cfg(not(target_arch = "wasm32"))]
- self.gl_surface.as_ref().unwrap().resize(self.gl_context.as_ref().unwrap(),
- NonZeroU32::new(size.width).unwrap(), NonZeroU32::new(size.height).unwrap());
+ self.gl_surface.as_ref().unwrap().resize(
+ self.gl_context.as_ref().unwrap(),
+ NonZeroU32::new(size.width).unwrap(),
+ NonZeroU32::new(size.height).unwrap(),
+ );
let mut camera = self.world.get_resource_mut::<Camera>().unwrap();
camera.width = size.width;
camera.height = size.height;
unsafe {
- self.gl.as_ref().unwrap().viewport(0, 0, size.width as i32, size.height as i32);
+ self.gl
+ .as_ref()
+ .unwrap()
+ .viewport(0, 0, size.width as i32, size.height as i32);
}
}
WindowEvent::MouseWheel { delta, .. } => {
let mut camera = self.world.get_resource_mut::<Camera>().unwrap();
let raw_delta = match delta {
- MouseScrollDelta::PixelDelta(pos) => {
- pos.y as f32
- }
- MouseScrollDelta::LineDelta(y, .. ) => {
- y
- }
+ MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
+ MouseScrollDelta::LineDelta(y, ..) => y,
};
let delta = 1.1;
if raw_delta < 0.0 {
camera.zoom *= 1.0 / delta;
} else {
-
camera.zoom *= delta;
}
}
@@ 296,8 399,8 @@ impl ApplicationHandler for App {
self.right = true;
matched = true;
}
- _ => matched = false
- }
+ _ => matched = false,
+ },
ElementState::Released => match key {
KeyCode::KeyW => {
self.up = false;
@@ 315,16 418,17 @@ impl ApplicationHandler for App {
self.right = false;
matched = true;
}
- _ => matched = false
- }
+ _ => matched = false,
+ },
}
if matched {
- self.send_packet_events.send(SendPacket(Packet::PlayerInput {
- up: self.up,
- down: self.down,
- left: self.left,
- right: self.right,
- }));
+ self.send_packet_events
+ .send(SendPacket(Packet::PlayerInput {
+ up: self.up,
+ down: self.down,
+ left: self.left,
+ right: self.right,
+ }));
}
}
PhysicalKey::Unidentified(_) => {} // unsupported
@@ 340,22 444,30 @@ impl ApplicationHandler for App {
};
let camera = self.world.get_resource::<Camera>().unwrap();
let view = camera.to_cursor_matrix();
- let pos = view * Vector3::new(self.mouse_pos.x as f32, self.mouse_pos.y as f32, 1.0);
+ let pos =
+ view * Vector3::new(self.mouse_pos.x as f32, self.mouse_pos.y as f32, 1.0);
let pos = pos / pos.z;
- self.send_packet_events.send(SendPacket(Packet::PlayerMouseInput {
- x: pos.x,
- y: pos.y,
- released: !state.is_pressed(),
- button,
- }));
+ self.send_packet_events
+ .send(SendPacket(Packet::PlayerMouseInput {
+ x: pos.x,
+ y: pos.y,
+ released: !state.is_pressed(),
+ button,
+ }));
}
_ => {}
}
- let event_response = self.egui_glow.as_mut().unwrap()
+ let event_response = self
+ .egui_glow
+ .as_mut()
+ .unwrap()
.on_window_event(self.window.as_ref().unwrap(), &event);
}
fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
- let mut ws = self.world.get_resource_mut::<Ws>().expect("Failed to get Ws resource");
+ let mut ws = self
+ .world
+ .get_resource_mut::<Ws>()
+ .expect("Failed to get Ws resource");
#[cfg(target_arch = "wasm32")]
while let Ok(Some(packet)) = ws.receiver.try_next() {
self.recv_packet_events.send(RecvPacket(packet));
@@ 367,36 479,61 @@ impl ApplicationHandler for App {
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,
- &mut self.amount, &mut self.max);
+ process_packets(
+ &mut self.world,
+ &mut self.send_packet_events,
+ &mut self.recv_packet_events,
+ &mut self.planet_types,
+ &mut self.amount,
+ &mut self.max,
+ );
let window = self.window.as_ref().unwrap();
let gl = self.gl.as_ref().unwrap();
let mut player = self.world.query_filtered::<&Transform, With<Player>>();
let player = player.single(&self.world);
- self.egui_glow.as_mut().unwrap().run(
- self.window.as_ref().unwrap(),
- |ctx| {
- egui::Window::new("Main Menu").resizable(false).show(ctx, |ui| {
- ui.heading("Starkingdoms.tk");
-
- ui.add(Label::new("Fuel:"));
- ui.add(ProgressBar::new((self.amount as f32)/(self.max as f32)).corner_radius(0));
- ui.add(Label::new(format!("Pos: {}, {}", player.translation.x as u32, player.translation.y as u32)));
- });
- },
- );
+ self.egui_glow
+ .as_mut()
+ .unwrap()
+ .run(self.window.as_ref().unwrap(), |ctx| {
+ egui::Window::new("Main Menu")
+ .resizable(false)
+ .show(ctx, |ui| {
+ ui.heading("Starkingdoms.tk");
+
+ ui.add(Label::new("Fuel:"));
+ ui.add(
+ ProgressBar::new((self.amount as f32) / (self.max as f32))
+ .corner_radius(0),
+ );
+ ui.add(Label::new(format!(
+ "Pos: {}, {}",
+ player.translation.x as u32, player.translation.y as u32
+ )));
+ });
+ });
let camera = self.world.get_resource::<Camera>().unwrap();
let x_scale = camera.zoom / camera.width as f32 * 2.0;
let y_scale = camera.zoom / camera.height as f32 * 2.0;
let view = &[
- x_scale, 0.0, 0.0, camera.x*x_scale,
- 0.0, y_scale,0.0, camera.y*y_scale,
- 0.0, 0.0, 1.0, 0.0,
- 0.0, 0.0, 0.0, 1.0,
+ x_scale,
+ 0.0,
+ 0.0,
+ camera.x * x_scale,
+ 0.0,
+ y_scale,
+ 0.0,
+ camera.y * y_scale,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0,
];
let mut sprite_query = self.world.query::<(&Transform, &mut Texture)>();
@@ 413,7 550,7 @@ impl ApplicationHandler for App {
gl.bind_buffer(glow::ARRAY_BUFFER, self.vertex_buffer);
gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, self.element_buffer);
gl.active_texture(glow::TEXTURE0);
-
+
let view_loc = gl.get_uniform_location(self.program.unwrap(), "view");
gl.uniform_matrix_4_f32_slice(view_loc.as_ref(), true, view);
let model_loc = gl.get_uniform_location(self.program.unwrap(), "model");
@@ 423,15 560,29 @@ impl ApplicationHandler for App {
let assets = self.world.resource::<Assets>();
let image = match assets.get(texture.name.clone()) {
Some(t) => t,
- None => continue
+ None => continue,
};
- let texture_object = gl.create_texture().expect("Failed to create texture object");
+ let texture_object = gl
+ .create_texture()
+ .expect("Failed to create texture object");
gl.bind_texture(glow::TEXTURE_2D, Some(texture_object));
- gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR_MIPMAP_LINEAR as i32);
- gl.tex_image_2d(glow::TEXTURE_2D, 0, glow::RGBA as i32,
- image.width as i32, image.height as i32, 0, glow::RGBA,
- glow::UNSIGNED_BYTE, PixelUnpackData::Slice(Some(&image.bytes)));
+ gl.tex_parameter_i32(
+ glow::TEXTURE_2D,
+ glow::TEXTURE_MIN_FILTER,
+ glow::LINEAR_MIPMAP_LINEAR as i32,
+ );
+ gl.tex_image_2d(
+ glow::TEXTURE_2D,
+ 0,
+ glow::RGBA as i32,
+ image.width as i32,
+ image.height as i32,
+ 0,
+ glow::RGBA,
+ glow::UNSIGNED_BYTE,
+ PixelUnpackData::Slice(Some(&image.bytes)),
+ );
gl.generate_mipmap(glow::TEXTURE_2D);
self.textures.insert(texture.name.clone(), texture_object);
@@ 447,17 598,31 @@ impl ApplicationHandler for App {
}
}
- self.egui_glow.as_mut().unwrap().paint(self.window.as_ref().unwrap());
+ self.egui_glow
+ .as_mut()
+ .unwrap()
+ .paint(self.window.as_ref().unwrap());
#[cfg(not(target_arch = "wasm32"))]
- self.gl_surface.as_ref().unwrap().swap_buffers(self.gl_context.as_ref().unwrap()).unwrap();
+ self.gl_surface
+ .as_ref()
+ .unwrap()
+ .swap_buffers(self.gl_context.as_ref().unwrap())
+ .unwrap();
- let mut ws = self.world.get_resource_mut::<Ws>().expect("Failed to get Ws resource");
+ 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.clone());
}
- event_loop.set_control_flow(ControlFlow::WaitUntil(web_time::Instant::now().checked_add(web_time::Duration::from_millis(16)).unwrap()));
+ event_loop.set_control_flow(ControlFlow::WaitUntil(
+ web_time::Instant::now()
+ .checked_add(web_time::Duration::from_millis(16))
+ .unwrap(),
+ ));
}
}