Browse Source

Implemented 'Owned' and 'Player' components

raster
Bergmann89 3 years ago
parent
commit
f921990546
20 changed files with 283 additions and 77 deletions
  1. +1
    -0
      Cargo.lock
  2. +1
    -0
      space-crush-app/Cargo.toml
  3. +2
    -1
      space-crush-app/resources/shader/ship/frag.glsl
  4. +51
    -2
      space-crush-app/resources/world.json
  5. +3
    -0
      space-crush-app/src/components/mod.rs
  6. +12
    -0
      space-crush-app/src/components/player_visual.rs
  7. +7
    -0
      space-crush-app/src/constants.rs
  8. +7
    -6
      space-crush-app/src/lib.rs
  9. +19
    -6
      space-crush-app/src/main.rs
  10. +1
    -1
      space-crush-app/src/misc/mod.rs
  11. +26
    -3
      space-crush-app/src/misc/world.rs
  12. +33
    -19
      space-crush-app/src/render/planets.rs
  13. +30
    -13
      space-crush-app/src/render/ships.rs
  14. +4
    -0
      space-crush-common/src/components/mod.rs
  15. +46
    -0
      space-crush-common/src/components/owned.rs
  16. +9
    -0
      space-crush-common/src/components/player.rs
  17. +4
    -1
      space-crush-common/src/dispatcher.rs
  18. +0
    -2
      space-crush-common/src/misc/mod.rs
  19. +0
    -13
      space-crush-common/src/misc/persistence.rs
  20. +27
    -10
      space-crush-common/src/misc/world.rs

+ 1
- 0
Cargo.lock View File

@@ -1510,6 +1510,7 @@ dependencies = [
"glc",
"glutin",
"glyph_brush",
"lazy_static",
"log",
"log4rs",
"ordered-float 2.0.1",


+ 1
- 0
space-crush-app/Cargo.toml View File

@@ -9,6 +9,7 @@ gl = { version = "0.1", features = [ "use_log_crate" ] }
glc = "0.1"
glutin = { version = "0.25", features = [ "serde" ] }
glyph_brush = "0.7"
lazy_static = "1.4"
log = { version = "0.4", features = [ "max_level_trace", "release_max_level_warn" ] }
log4rs = "0.13"
ordered-float = "2.0"


+ 2
- 1
space-crush-app/resources/shader/ship/frag.glsl View File

@@ -4,6 +4,7 @@
#pragma include ../misc/glow.glsl
#pragma include ../misc/global.glsl

const float GLOW_ALPHA = 0.20;
const GlowArgs GLOW_ARGS = {
/* step0 */ 0.100,
/* step1 */ 1.900,
@@ -21,7 +22,7 @@ out vec4 outColor;

void main() {
float alpha = glow(GLOW_ARGS, fragmentData.texCoords - vec2(0.5), uGlobal.time);
vec4 glow = vec4(uGlowColor.rgb, uGlowColor.a * alpha);
vec4 glow = vec4(uGlowColor.rgb, uGlowColor.a * alpha * GLOW_ALPHA);
vec4 tex = texture(uTexture, fragmentData.texCoords);

outColor = tex * tex.a + glow * (1.0 - tex.a);


+ 51
- 2
space-crush-app/resources/world.json View File

@@ -13,6 +13,13 @@
},
null,
{},
null,
{
"owner": [
4
]
},
null,
null
]
},
@@ -38,7 +45,14 @@
null,
{
"type_": "Fighter"
}
},
{
"owner": [
4
]
},
null,
null
]
},
{
@@ -63,7 +77,14 @@
null,
{
"type_": "Bomber"
}
},
{
"owner": [
4
]
},
null,
null
]
},
{
@@ -88,6 +109,34 @@
null,
{
"type_": "Transporter"
},
{
"owner": [
4
]
},
null,
null
]
},
{
"marker": [
4
],
"components": [
null,
null,
null,
null,
null,
{},
{
"color": [
0.0,
0.5,
1.0,
0.1
]
}
]
}


+ 3
- 0
space-crush-app/src/components/mod.rs View File

@@ -0,0 +1,3 @@
mod player_visual;

pub use player_visual::PlayerVisual;

+ 12
- 0
space-crush-app/src/components/player_visual.rs View File

@@ -0,0 +1,12 @@
use glc::vector::Vector4f;
use serde::{Deserialize, Serialize};
use specs::{Component, HashMapStorage};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PlayerVisual {
pub color: Vector4f,
}

impl Component for PlayerVisual {
type Storage = HashMapStorage<Self>;
}

+ 7
- 0
space-crush-app/src/constants.rs View File

@@ -1,2 +1,9 @@
use glc::vector::Vector4f;
use lazy_static::lazy_static;

pub const UNIFORM_BUFFER_INDEX_CAMERA: gl::GLuint = 0;
pub const UNIFORM_BUFFER_INDEX_UNIFORM: gl::GLuint = 1;

lazy_static! {
pub static ref PLAYER_COLOR_DEFAULT: Vector4f = Vector4f::new(1.0, 1.0, 1.0, 0.1);
}

+ 7
- 6
space-crush-app/src/lib.rs View File

@@ -1,9 +1,10 @@
mod constants;
mod error;
mod misc;
mod render;
mod resources;
mod systems;
pub mod components;
pub mod constants;
pub mod error;
pub mod misc;
pub mod render;
pub mod resources;
pub mod systems;

use specs::{Dispatcher, DispatcherBuilder, World};



+ 19
- 6
space-crush-app/src/main.rs View File

@@ -50,16 +50,26 @@ fn run(vfs: Vfs) -> Result<(), Error> {
}

fn create_world(world: &mut World) {
use glc::vector::Vector2f;
use glc::vector::{Vector2f, Vector4f};
use space_crush_app::{components::PlayerVisual, misc::PersistWorld};
use space_crush_common::{
components::{Planet, Position, Ship, ShipType, Velocity},
misc::{PersistWorld, Persistence},
components::{Owned, Planet, Player, Position, Ship, ShipType, Velocity},
misc::Persistence,
};
use specs::{saveload::MarkedBuilder, Builder};

let player1 = world
.create_entity()
.with(Player {})
.with(PlayerVisual {
color: Vector4f::new(0.0, 0.5, 1.0, 0.1),
})
.build();

world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(Owned { owner: player1 })
.with(Position {
pos: Vector2f::default(),
size: 500.0,
@@ -74,9 +84,10 @@ fn create_world(world: &mut World) {
world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(Owned { owner: player1 })
.with(Position {
pos: Vector2f::new(250.0 * x, 250.0 * y),
size: 100.0,
size: 30.0,
})
.with(Velocity {
dir: Vector2f::new(i as f32 - 1.0, 1.0).normalize(),
@@ -96,7 +107,8 @@ fn create_world(world: &mut World) {

fn load_world(world: &mut World, path: &str) -> Result<bool, Error> {
use serde_json::de::{Deserializer, IoRead};
use space_crush_common::misc::{PersistWorld, Persistence, WorldHelper};
use space_crush_app::misc::PersistWorld;
use space_crush_common::misc::{Persistence, WorldHelper};

PersistWorld::setup(world);

@@ -116,7 +128,8 @@ fn load_world(world: &mut World, path: &str) -> Result<bool, Error> {

fn save_world(world: &mut World, path: &str) -> Result<(), Error> {
use serde_json::Serializer;
use space_crush_common::misc::{PersistWorld, WorldHelper};
use space_crush_app::misc::PersistWorld;
use space_crush_common::misc::WorldHelper;

let vfs = world.resource::<Vfs>()?;
let mut file = vfs.join(path)?.create_file()?;


+ 1
- 1
space-crush-app/src/misc/mod.rs View File

@@ -6,4 +6,4 @@ mod world;
pub use events::{Events, KeyboardEvent, MouseButton, MouseEvent, VirtualKeyCode, WindowEvent};
pub use text::{Text, TextCache, TextManager};
pub use window::Window;
pub use world::WorldHelper;
pub use world::{PersistWorld, WorldHelper};

+ 26
- 3
space-crush-app/src/misc/world.rs View File

@@ -5,10 +5,33 @@ use glc::{
shader::{Program, Shader, Type},
texture::{Data, FilterMag, FilterMin, Target, Texture, Wrap},
};
use space_crush_common::misc::Vfs;
use specs::World;
use space_crush_common::{
components::{Owned, Planet, Player, Position, Ship, Velocity},
misc::{Persistence, Vfs},
};
use specs::{saveload::SimpleMarker, World};

use crate::{components::PlayerVisual, Error};

/* PersistWorld */

pub struct PersistWorld;
pub struct PersistWorldMarker;

impl Persistence for PersistWorld {
type Marker = SimpleMarker<PersistWorldMarker>;
type Components = (
Position,
Velocity,
Planet,
Ship,
Owned,
Player,
PlayerVisual,
);
}

use crate::Error;
/* WorldHelper */

pub trait WorldHelper {
fn load_program<I>(&self, iter: I) -> Result<Program, Error>


+ 33
- 19
space-crush-app/src/render/planets.rs View File

@@ -1,16 +1,17 @@
use glc::{
matrix::Matrix4f,
misc::Bindable,
misc::{BindGuard, Bindable},
shader::{Program, Type, Uniform},
texture::Texture,
vector::Vector4f,
};
use log::error;
use space_crush_common::components::{Planet, Position};
use space_crush_common::components::{Owned, Planet, Position};
use specs::{prelude::*, ReadExpect, ReadStorage, System, World};

use crate::{
constants::{UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
components::PlayerVisual,
constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
misc::WorldHelper,
resources::Geometry,
Error,
@@ -19,7 +20,8 @@ use crate::{
pub struct Planets {
program: Program,
texture: Texture,
model_location: gl::GLint,
location_model: gl::GLint,
location_glow_color: gl::GLint,
}

impl Planets {
@@ -32,13 +34,11 @@ impl Planets {
program.uniform_block_binding("Camera", UNIFORM_BUFFER_INDEX_CAMERA)?;
program.uniform_block_binding("Global", UNIFORM_BUFFER_INDEX_UNIFORM)?;

let glow_color = Vector4f::new(1.0, 1.0, 1.0, 0.1);
let glow_color = Uniform::Vector4f(&glow_color);
let model_location = program.uniform_location("uModel")?;
let location_model = program.uniform_location("uModel")?;
let location_glow_color = program.uniform_location("uGlowColor")?;

program.bind();
program.uniform("uTexture", Uniform::Texture(0))?;
program.uniform("uGlowColor", glow_color)?;
program.unbind();

let texture = world.load_texture("resources/textures/planet01.png")?;
@@ -46,7 +46,8 @@ impl Planets {
Ok(Self {
program,
texture,
model_location,
location_model,
location_glow_color,
})
}
}
@@ -56,6 +57,8 @@ pub struct PlanetsData<'a> {
geometry: ReadExpect<'a, Geometry>,
position: ReadStorage<'a, Position>,
planet: ReadStorage<'a, Planet>,
owned: ReadStorage<'a, Owned>,
player_visual: ReadStorage<'a, PlayerVisual>,
}

impl<'a> System<'a> for Planets {
@@ -66,29 +69,43 @@ impl<'a> System<'a> for Planets {
geometry,
position,
planet,
owned,
player_visual,
} = data;

gl::enable(gl::BLEND);
gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);

self.texture.bind();
self.program.bind();
let _guard = BindGuard::new(&self.program);
let _guard = BindGuard::new(&self.texture);

for (p, _) in (&position, &planet).join() {
let x = p.pos.x;
let y = p.pos.y;
for (p, _, owned) in (&position, &planet, owned.maybe()).join() {
let p_x = p.pos.x;
let p_y = p.pos.y;
let s = p.size;

let c = match owned.and_then(|owned| player_visual.get(owned.owner)) {
Some(pv) => &pv.color,
None => &*PLAYER_COLOR_DEFAULT,
};

let m = Matrix4f::new(
Vector4f::new(s, 0.0, 0.0, 0.0),
Vector4f::new(0.0, s, 0.0, 0.0),
Vector4f::new(0.0, 0.0, s, 0.0),
Vector4f::new(x, y, 0.0, 1.0),
Vector4f::new(p_x, p_y, 0.0, 1.0),
);

if let Err(err) = self
.program
.uniform(self.model_location, Uniform::Matrix4f(&m))
.uniform(self.location_glow_color, Uniform::Vector4f(&c))
{
error!("Error while updating glow color: {}", err);
}

if let Err(err) = self
.program
.uniform(self.location_model, Uniform::Matrix4f(&m))
{
error!("Error while updating model matrix: {}", err);
}
@@ -96,9 +113,6 @@ impl<'a> System<'a> for Planets {
geometry.render_quad();
}

self.program.unbind();
self.texture.unbind();

gl::disable(gl::BLEND);
}
}

+ 30
- 13
space-crush-app/src/render/ships.rs View File

@@ -6,11 +6,12 @@ use glc::{
vector::Vector4f,
};
use log::error;
use space_crush_common::components::{Position, Ship, ShipType, Velocity};
use space_crush_common::components::{Owned, Position, Ship, ShipType, Velocity};
use specs::{prelude::*, ReadExpect, ReadStorage, System, World};

use crate::{
constants::{UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
components::PlayerVisual,
constants::{PLAYER_COLOR_DEFAULT, UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
misc::WorldHelper,
resources::Geometry,
Error,
@@ -18,10 +19,11 @@ use crate::{

pub struct Ships {
program: Program,
texture_fighter: Texture,
texture_bomber: Texture,
texture_fighter: Texture,
texture_transporter: Texture,
model_location: gl::GLint,
location_model: gl::GLint,
location_glow_color: gl::GLint,
}

impl Ships {
@@ -34,25 +36,24 @@ impl Ships {
program.uniform_block_binding("Camera", UNIFORM_BUFFER_INDEX_CAMERA)?;
program.uniform_block_binding("Global", UNIFORM_BUFFER_INDEX_UNIFORM)?;

let glow_color = Vector4f::new(1.0, 1.0, 1.0, 0.02);
let glow_color = Uniform::Vector4f(&glow_color);
let model_location = program.uniform_location("uModel")?;
let location_model = program.uniform_location("uModel")?;
let location_glow_color = program.uniform_location("uGlowColor")?;

program.bind();
program.uniform("uTexture", Uniform::Texture(0))?;
program.uniform("uGlowColor", glow_color)?;
program.unbind();

let texture_fighter = world.load_texture("resources/textures/ship_fighter.png")?;
let texture_bomber = world.load_texture("resources/textures/ship_bomber.png")?;
let texture_fighter = world.load_texture("resources/textures/ship_fighter.png")?;
let texture_transporter = world.load_texture("resources/textures/ship_transporter.png")?;

Ok(Self {
program,
texture_fighter,
texture_bomber,
texture_fighter,
texture_transporter,
model_location,
location_model,
location_glow_color,
})
}
}
@@ -63,6 +64,8 @@ pub struct ShipsData<'a> {
position: ReadStorage<'a, Position>,
velocity: ReadStorage<'a, Velocity>,
ship: ReadStorage<'a, Ship>,
owned: ReadStorage<'a, Owned>,
player_visual: ReadStorage<'a, PlayerVisual>,
}

impl<'a> System<'a> for Ships {
@@ -74,6 +77,8 @@ impl<'a> System<'a> for Ships {
position,
velocity,
ship,
owned,
player_visual,
} = data;

gl::enable(gl::BLEND);
@@ -81,13 +86,18 @@ impl<'a> System<'a> for Ships {

let _guard = BindGuard::new(&self.program);

for (p, v, ship) in (&position, &velocity, &ship).join() {
for (p, v, ship, owned) in (&position, &velocity, &ship, owned.maybe()).join() {
let _guard = match ship.type_ {
ShipType::Fighter => BindGuard::new(&self.texture_fighter),
ShipType::Bomber => BindGuard::new(&self.texture_bomber),
ShipType::Transporter => BindGuard::new(&self.texture_transporter),
};

let c = match owned.and_then(|owned| player_visual.get(owned.owner)) {
Some(pv) => &pv.color,
None => &*PLAYER_COLOR_DEFAULT,
};

let p_x = p.pos.x;
let p_y = p.pos.y;
let d_x = v.dir.x;
@@ -103,7 +113,14 @@ impl<'a> System<'a> for Ships {

if let Err(err) = self
.program
.uniform(self.model_location, Uniform::Matrix4f(&m))
.uniform(self.location_glow_color, Uniform::Vector4f(&c))
{
error!("Error while updating glow color: {}", err);
}

if let Err(err) = self
.program
.uniform(self.location_model, Uniform::Matrix4f(&m))
{
error!("Error while updating model matrix: {}", err);
}


+ 4
- 0
space-crush-common/src/components/mod.rs View File

@@ -1,9 +1,13 @@
mod owned;
mod planet;
mod player;
mod position;
mod ship;
mod velocity;

pub use owned::Owned;
pub use planet::Planet;
pub use player::Player;
pub use position::Position;
pub use ship::{Ship, Type as ShipType};
pub use velocity::Velocity;

+ 46
- 0
space-crush-common/src/components/owned.rs View File

@@ -0,0 +1,46 @@
use serde::{Deserialize, Serialize};
use specs::{
error::NoError,
saveload::{ConvertSaveload, Marker},
Component, Entity, VecStorage,
};

#[derive(Clone, Debug)]
pub struct Owned {
pub owner: Entity,
}

#[derive(Serialize, Deserialize)]
pub struct OwnedData<M> {
pub owner: M,
}

impl Component for Owned {
type Storage = VecStorage<Self>;
}

impl<M> ConvertSaveload<M> for Owned
where
for<'de> M: Marker + Serialize + Deserialize<'de>,
{
type Data = OwnedData<M>;
type Error = NoError;

fn convert_into<F>(&self, mut ids: F) -> Result<Self::Data, Self::Error>
where
F: FnMut(Entity) -> Option<M>,
{
let owner = ids(self.owner).unwrap();

Ok(OwnedData { owner })
}

fn convert_from<F>(data: Self::Data, mut ids: F) -> Result<Self, Self::Error>
where
F: FnMut(M) -> Option<Entity>,
{
let owner = ids(data.owner).unwrap();

Ok(Owned { owner })
}
}

+ 9
- 0
space-crush-common/src/components/player.rs View File

@@ -0,0 +1,9 @@
use serde::{Deserialize, Serialize};
use specs::{Component, NullStorage};

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Player {}

impl Component for Player {
type Storage = NullStorage<Self>;
}

+ 4
- 1
space-crush-common/src/dispatcher.rs View File

@@ -1,6 +1,7 @@
use specs::{Dispatcher as Inner, DispatcherBuilder, World};
use specs::{Dispatcher as Inner, DispatcherBuilder, World, WorldExt};

use crate::{
components::Player,
resources::Global,
systems::{Movement, Process},
};
@@ -13,6 +14,8 @@ impl<'a, 'b> Dispatcher<'a, 'b> {
pub fn new(world: &mut World) -> Self {
world.insert(Global::default());

world.register::<Player>();

let mut dispatcher = DispatcherBuilder::new()
.with(Process::default(), "process", &[])
.with(Movement::default(), "movement", &[])


+ 0
- 2
space-crush-common/src/misc/mod.rs View File

@@ -1,9 +1,7 @@
mod log;
mod persistence;
mod vfs;
mod world;

pub use self::log::init as init_logger;
pub use self::vfs::{Vfs, VfsError};
pub use persistence::PersistWorld;
pub use world::{Persistence, WorldHelper};

+ 0
- 13
space-crush-common/src/misc/persistence.rs View File

@@ -1,13 +0,0 @@
use specs::saveload::SimpleMarker;

use crate::components::{Planet, Position, Ship, Velocity};

use super::Persistence;

pub struct PersistWorld;
pub struct PersistWorldMarker;

impl Persistence for PersistWorld {
type Marker = SimpleMarker<PersistWorldMarker>;
type Components = (Position, Velocity, Planet, Ship);
}

+ 27
- 10
space-crush-common/src/misc/world.rs View File

@@ -1,14 +1,11 @@
use std::any::type_name;

use serde::{
de::{DeserializeOwned, Deserializer},
ser::{Serialize, Serializer},
};
use serde::{de::Deserializer, ser::Serializer};
use shred::{Fetch, FetchMut, Resource};
use shrev::{Event, EventChannel, ReaderId};
use specs::{
error::NoError,
saveload::{DeserializeComponents, Marker, SerializeComponents},
saveload::{ConvertSaveload, DeserializeComponents, Marker, SerializeComponents},
Component, Entities, ReadStorage, World, WorldExt, Write, WriteStorage,
};

@@ -133,16 +130,31 @@ macro_rules! define_persistence_components {
where
M: Marker,
M::Allocator: Default,
$($T: Component + Serialize + DeserializeOwned + Clone,)+
$($T: Component + ConvertSaveload<M, Error = NoError>,)+
{
fn serialize<S>(world: &World, serializer: S) -> Result<(), S::Error>
where
S: Serializer,
{
let (entities, marker, $($T,)+) =
world.system_data::<(Entities, ReadStorage<M>, $(ReadStorage<$T>,)+)>();
let (
entities,
mut marker,
mut allocator,
$($T,)+
) = world.system_data::<(
Entities,
WriteStorage<M>,
Write<M::Allocator>,
$(ReadStorage<$T>,
)+)>();

SerializeComponents::<NoError, M>::serialize(&($($T,)+), &entities, &marker, serializer)?;
SerializeComponents::<NoError, M>::serialize_recursive
(&($($T,)+),
&entities,
&mut marker,
&mut allocator,
serializer,
)?;

Ok(())
}
@@ -151,7 +163,12 @@ macro_rules! define_persistence_components {
where
D: Deserializer<'de>,
{
let (entities, mut marker, mut allocator, $($T,)+) = world.system_data::<(
let (
entities,
mut marker,
mut allocator,
$($T,)+
) = world.system_data::<(
Entities,
WriteStorage<M>,
Write<M::Allocator>,


Loading…
Cancel
Save