gres/src/view/game.rs

172 lines
5.4 KiB
Rust

use bevy::prelude::*;
use crate::grid::{Grid,GridElement};
use crate::MAX_FLUID_AMOUNT;
const FLUID_FULLNES_STAGES: usize = 7;
pub struct GameViewPlugin;
impl Plugin for GameViewPlugin {
fn build(&self, app: &mut App) {
app
.init_resource::<CubeStages>()
.init_resource::<TileMaterials>()
.add_systems(Startup, (setup_building_planes,setup_view_cubes))
.add_systems(Update, update_cubes);
}
}
#[derive(Resource, Default)]
pub struct CubeStages(pub Vec<Handle<Mesh>>);
#[derive(Component, Clone, Default)]
pub struct TileWatch{
pub index: usize,
pub previous_element: GridElement
}
#[derive(Resource, Default)]
pub struct TileMaterials {
pub solid: Handle<StandardMaterial>,
pub water: Handle<StandardMaterial>,
pub drain: Handle<StandardMaterial>,
pub source: Handle<StandardMaterial>,
}
pub fn setup_building_planes(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
grid: Res<Grid>
) {
let mut mesh: Mesh = (Cuboid::new(grid.size.x as f32, grid.size.y as f32, grid.size.z as f32).mesh()).into();
let _ = mesh.invert_winding();
let mesh_handle = meshes.add(mesh);
let center = (grid.size.as_vec3() - Vec3::ONE)/2.;
commands.spawn_scene(bsn!{
Mesh3d(mesh_handle)
Transform {
translation: center
}
MeshMaterial3d<StandardMaterial>(asset_value(
StandardMaterial {
base_color: Color::WHITE,
..default()
}
))
Visibility::Visible
});
}
pub fn setup_view_cubes(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
mut stages: ResMut<CubeStages>,
mut tile_materials: ResMut<TileMaterials>,
grid: Res<Grid>) {
for i in 0..FLUID_FULLNES_STAGES {
let tile_height = ((i+1) as f32)/(FLUID_FULLNES_STAGES as f32);
let mesh = meshes.add(Cuboid::new(1., tile_height, 1.));
stages.0.push(mesh);
}
*tile_materials = TileMaterials {
solid: materials.add(StandardMaterial {
base_color: Color::hsl(268., 0.778, 0.499),
..default()
}),
water: materials.add(StandardMaterial {
base_color: Color::hsl(172.,0.502,0.571),
..default()
}),
drain: materials.add(StandardMaterial {
base_color: Color::hsl(342., 0.628, 0.685),
..default()
}),
source: materials.add(StandardMaterial {
base_color: Color::hsl(172., 0.502, 0.371),
..default()
})
};
let mesh = stages.0[FLUID_FULLNES_STAGES-1].clone();
for i in 0..grid.cell_amount() {
commands.spawn_scene(
cube(
grid.deindexify(i as u32).as_vec3(),
i as usize,
mesh.clone()
)
);
}
}
pub fn cube(position: Vec3,index: usize,mesh: Handle<Mesh>) -> impl Scene {
bsn! {
Mesh3d(mesh)
MeshMaterial3d<StandardMaterial>
Transform::from_translation(position)
TileWatch{
index
}
Visibility::Hidden
}
}
pub fn update_cubes(query: Query<(&mut Mesh3d,&mut Visibility,&mut MeshMaterial3d<StandardMaterial>,&mut TileWatch, &mut Transform)>, materials: Res<TileMaterials>, stages: Res<CubeStages>, grid: Res<Grid>) {
if grid.is_changed() == false { return; }
for (mut mesh,mut visibility, mut material, mut tile_data, mut transform) in query {
let state = grid.data[tile_data.index];
if tile_data.previous_element == state {
continue;
}
match state {
GridElement::Air => {
*visibility = Visibility::Hidden;
},
GridElement::Water { amount } => {
*visibility = Visibility::Visible;
material.0 = materials.water.clone();
let stage = ((amount as f32)/(MAX_FLUID_AMOUNT as f32) * (FLUID_FULLNES_STAGES-1) as f32).ceil() as usize;
transform.translation = grid.deindexify(tile_data.index as u32).as_vec3() - vec3(0.,((FLUID_FULLNES_STAGES-1-stage) as f32 / (FLUID_FULLNES_STAGES as f32))/2.,0.);
mesh.0 = stages.0[stage].clone();
},
GridElement::Solid => {
*visibility = Visibility::Visible;
material.0 = materials.solid.clone();
mesh.0 = stages.0[FLUID_FULLNES_STAGES-1].clone();
transform.translation = Vec3::ZERO;
},
GridElement::Drain => {
*visibility = Visibility::Visible;
material.0 = materials.drain.clone();
mesh.0 = stages.0[FLUID_FULLNES_STAGES-1].clone();
transform.translation = Vec3::ZERO;
},
GridElement::Source { source_amount } => {
*visibility = Visibility::Visible;
material.0 = materials.source.clone();
let stage = ((source_amount as f32)/(MAX_FLUID_AMOUNT as f32) * (FLUID_FULLNES_STAGES-1) as f32).ceil() as usize;
transform.translation = grid.deindexify(tile_data.index as u32).as_vec3() - vec3(0.,((FLUID_FULLNES_STAGES-1-stage) as f32 / (FLUID_FULLNES_STAGES as f32))/2.,0.);
mesh.0 = stages.0[stage].clone();
}
}
tile_data.previous_element = state;
}
}