feat: simulation boundaries
parent
6c1b68d1fd
commit
c9d7e17a60
|
|
@ -77,7 +77,6 @@ fn camera_system(
|
|||
None => return,
|
||||
};
|
||||
|
||||
// let offset = Vec3::new(WORLD_WIDTH as f32 / 2.0, 0.0, 999.9);
|
||||
for (mut camera_transform, projection) in camera_query.iter_mut() {
|
||||
let left_limit = 0.0;
|
||||
let right_limit = WORLD_WIDTH as f32;
|
||||
|
|
@ -101,6 +100,7 @@ fn camera_system(
|
|||
);
|
||||
}
|
||||
}
|
||||
// horizontal boundaries
|
||||
let camera_x = camera_transform.translation.x;
|
||||
camera_transform.translation += Vec3::new(
|
||||
(left_limit - (projection.left * projection.scale + camera_x)).max(0.0),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub struct TerrainDebugPlugin;
|
|||
impl Plugin for TerrainDebugPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.insert_resource(TerrainBrush2D::default())
|
||||
// .add_system_to_stage(TerrainStages::EventHandler, dirty_rect_visualizer)
|
||||
.add_system_to_stage(TerrainStages::EventHandler, dirty_rect_visualizer)
|
||||
.add_system(debug_painter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,10 @@ pub use terrain_gen2d::*;
|
|||
pub use texel2d::*;
|
||||
pub use texel_behaviour2d::*;
|
||||
|
||||
use crate::util::{frame_counter::FrameCounter, math::*, Vector2I};
|
||||
use crate::{
|
||||
game::camera::WORLD_WIDTH,
|
||||
util::{frame_counter::FrameCounter, math::*, Vector2I},
|
||||
};
|
||||
|
||||
pub struct Terrain2DPlugin;
|
||||
|
||||
|
|
@ -42,7 +45,7 @@ impl Plugin for Terrain2DPlugin {
|
|||
);
|
||||
|
||||
app.register_type::<TerrainChunk2D>()
|
||||
.insert_resource(Terrain2D::new())
|
||||
.insert_resource(Terrain2D::new(Some(WORLD_WIDTH * 2), Some(0), Some(0), Some(WORLD_WIDTH)))
|
||||
.add_event::<TerrainEvent2D>()
|
||||
.add_system_to_stage(TerrainStages::Simulation, terrain_simulation)
|
||||
.add_system_to_stage(TerrainStages::EventHandler, emit_terrain_events)
|
||||
|
|
@ -191,13 +194,26 @@ pub enum TerrainEvent2D {
|
|||
pub struct Terrain2D {
|
||||
chunk_map: HashMap<Chunk2DIndex, Chunk2D>,
|
||||
events: Vec<TerrainEvent2D>,
|
||||
pub top_boundary: Option<i32>,
|
||||
pub bottom_boundary: Option<i32>,
|
||||
pub left_boundary: Option<i32>,
|
||||
pub right_boundary: Option<i32>,
|
||||
}
|
||||
|
||||
impl Terrain2D {
|
||||
pub fn new() -> Terrain2D {
|
||||
pub fn new(
|
||||
top_boundary: Option<i32>,
|
||||
bottom_boundary: Option<i32>,
|
||||
left_boundary: Option<i32>,
|
||||
right_boundary: Option<i32>,
|
||||
) -> Terrain2D {
|
||||
Terrain2D {
|
||||
chunk_map: HashMap::new(),
|
||||
events: Vec::new(),
|
||||
top_boundary,
|
||||
bottom_boundary,
|
||||
left_boundary,
|
||||
right_boundary,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +272,30 @@ impl Terrain2D {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_within_boundaries(&self, global: &Vector2I) -> bool {
|
||||
if let Some(top) = self.top_boundary {
|
||||
if global.y > top {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Some(bottom) = self.bottom_boundary {
|
||||
if global.y < bottom {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Some(left) = self.left_boundary {
|
||||
if global.x < left {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Some(right) = self.right_boundary {
|
||||
if global.x > right {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn get_texel(&self, global: &Vector2I) -> Option<Texel2D> {
|
||||
self.global_to_chunk(global)
|
||||
.map_or(None, |chunk| chunk.get_texel(&global_to_local(global)))
|
||||
|
|
@ -268,11 +308,18 @@ impl Terrain2D {
|
|||
let texel = self.get_texel(global);
|
||||
(
|
||||
texel,
|
||||
texel.map_or(None, |t| TexelBehaviour2D::from_id(&t.id)),
|
||||
if self.is_within_boundaries(global) {
|
||||
texel.map_or(None, |t| TexelBehaviour2D::from_id(&t.id))
|
||||
} else {
|
||||
Some(TexelBehaviour2D::OUT_OF_BOUNDS)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn set_texel(&mut self, global: &Vector2I, id: TexelID, simulation_frame: Option<u8>) {
|
||||
if !self.is_within_boundaries(global) {
|
||||
return
|
||||
}
|
||||
let index = global_to_chunk_index(global);
|
||||
let changed = match self.index_to_chunk_mut(&index) {
|
||||
Some(chunk) => chunk.set_texel(&global_to_local(global), id, simulation_frame),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::util::Vector2I;
|
|||
use super::TexelID;
|
||||
use bevy::prelude::*;
|
||||
use lazy_static::lazy_static;
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, borrow::Cow};
|
||||
|
||||
lazy_static! {
|
||||
static ref ID_MAP: HashMap<TexelID, TexelBehaviour2D> = {
|
||||
|
|
@ -12,7 +12,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
1,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("loose sand"),
|
||||
name: Cow::Borrowed("loose sand"),
|
||||
color: Color::rgb(0.61, 0.49, 0.38),
|
||||
gravity: Some(TexelGravity::Down(100)),
|
||||
has_collision: true,
|
||||
|
|
@ -23,7 +23,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
2,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("loose stone"),
|
||||
name: Cow::Borrowed("loose stone"),
|
||||
color: Color::rgb(0.21, 0.19, 0.17),
|
||||
gravity: Some(TexelGravity::Down(100)),
|
||||
has_collision: true,
|
||||
|
|
@ -34,7 +34,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
3,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("loose sturdy stone"),
|
||||
name: Cow::Borrowed("loose sturdy stone"),
|
||||
color: Color::rgb(0.11, 0.11, 0.11),
|
||||
gravity: Some(TexelGravity::Down(100)),
|
||||
has_collision: true,
|
||||
|
|
@ -45,7 +45,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
4,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("water"),
|
||||
name: Cow::Borrowed("water"),
|
||||
color: Color::rgba(0.0, 0.0, 1.0, 0.5),
|
||||
form: TexelForm::Liquid,
|
||||
gravity: Some(TexelGravity::Down(10)),
|
||||
|
|
@ -56,7 +56,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
5,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("oil"),
|
||||
name: Cow::Borrowed("oil"),
|
||||
color: Color::rgba(0.0, 1.0, 0.0, 0.5),
|
||||
form: TexelForm::Gas,
|
||||
gravity: Some(TexelGravity::Up(50)),
|
||||
|
|
@ -67,7 +67,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
6,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("gas"),
|
||||
name: Cow::Borrowed("gas"),
|
||||
color: Color::rgba(0.5, 0.5, 0.25, 0.5),
|
||||
form: TexelForm::Liquid,
|
||||
gravity: Some(TexelGravity::Down(5)),
|
||||
|
|
@ -78,7 +78,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
11,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("sand"),
|
||||
name: Cow::Borrowed("sand"),
|
||||
color: Color::rgb(0.61, 0.49, 0.38),
|
||||
has_collision: true,
|
||||
..default()
|
||||
|
|
@ -88,7 +88,7 @@ lazy_static! {
|
|||
result.insert(
|
||||
12,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("stone"),
|
||||
name: Cow::Borrowed("stone"),
|
||||
color: Color::rgb(0.21, 0.19, 0.17),
|
||||
has_collision: true,
|
||||
..default()
|
||||
|
|
@ -98,22 +98,13 @@ lazy_static! {
|
|||
result.insert(
|
||||
13,
|
||||
TexelBehaviour2D {
|
||||
name: String::from("sturdy stone"),
|
||||
name: Cow::Borrowed("sturdy stone"),
|
||||
color: Color::rgb(0.11, 0.11, 0.11),
|
||||
has_collision: true,
|
||||
..default()
|
||||
},
|
||||
);
|
||||
|
||||
result.insert(
|
||||
u8::MAX,
|
||||
TexelBehaviour2D {
|
||||
color: Color::BLACK,
|
||||
has_collision: true,
|
||||
..default()
|
||||
},
|
||||
);
|
||||
|
||||
result
|
||||
};
|
||||
}
|
||||
|
|
@ -146,7 +137,7 @@ impl From<TexelGravity> for Vector2I {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct TexelBehaviour2D {
|
||||
pub name: String,
|
||||
pub name: Cow<'static, str>,
|
||||
pub color: Color,
|
||||
pub form: TexelForm,
|
||||
pub has_collision: bool,
|
||||
|
|
@ -157,7 +148,7 @@ pub struct TexelBehaviour2D {
|
|||
impl Default for TexelBehaviour2D {
|
||||
fn default() -> Self {
|
||||
TexelBehaviour2D {
|
||||
name: "Unnamed material".to_string(),
|
||||
name: Cow::Borrowed("Unnamed material"),
|
||||
color: Color::PINK,
|
||||
form: TexelForm::Solid,
|
||||
has_collision: false,
|
||||
|
|
@ -169,6 +160,15 @@ impl Default for TexelBehaviour2D {
|
|||
|
||||
// TODO: change form-based functions like is_solid to behaviour based (e.g. has_collision)
|
||||
impl TexelBehaviour2D {
|
||||
pub const OUT_OF_BOUNDS: Self = TexelBehaviour2D {
|
||||
name: Cow::Borrowed(":)"),
|
||||
color: Color::BLACK,
|
||||
has_collision: true,
|
||||
form: TexelForm::Solid,
|
||||
gravity: None,
|
||||
toughness: None,
|
||||
};
|
||||
|
||||
pub fn from_id(id: &TexelID) -> Option<Self> {
|
||||
ID_MAP.get(id).cloned()
|
||||
}
|
||||
|
|
@ -181,12 +181,12 @@ impl TexelBehaviour2D {
|
|||
ID_MAP.get(id).map_or(false, |b| b.has_collision)
|
||||
}
|
||||
|
||||
/// Can this type of material displace another?
|
||||
pub fn can_displace(from: &TexelBehaviour2D, to: &Option<TexelBehaviour2D>) -> bool {
|
||||
let to = if let Some(to) = to { to } else { return true };
|
||||
|
||||
match (from.form, to.form) {
|
||||
(_, TexelForm::Solid) => false,
|
||||
(_, _) => {
|
||||
(_, to_form) => {
|
||||
if let (Some(from_grav), Some(to_grav)) = (from.gravity, to.gravity) {
|
||||
match (from_grav, to_grav) {
|
||||
(TexelGravity::Down(from_grav), TexelGravity::Down(to_grav)) => {
|
||||
|
|
@ -198,7 +198,8 @@ impl TexelBehaviour2D {
|
|||
(_, _) => true,
|
||||
}
|
||||
} else {
|
||||
true
|
||||
// Solids can also be displaced, but only if the other material has gravity
|
||||
to_form != TexelForm::Solid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue