Add basic falling sand
This commit is contained in:
parent
ce4e13005f
commit
754466ea16
|
@ -11,14 +11,17 @@ use bevy::{
|
|||
sprite::SpriteBundle,
|
||||
transform::components::Transform,
|
||||
};
|
||||
use rand::random;
|
||||
use rand::Rng;
|
||||
|
||||
pub struct FallingSandPlugin;
|
||||
|
||||
impl Plugin for FallingSandPlugin {
|
||||
fn build(&self, app: &mut bevy::prelude::App) {
|
||||
app.add_systems(Startup, setup);
|
||||
app.add_systems(Update, update_chunk_texture_system);
|
||||
app.add_systems(
|
||||
Update,
|
||||
(simulate_chunk_system, update_chunk_texture_system).chain(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,10 +43,16 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
|||
.spawn(Chunk {
|
||||
width: 256,
|
||||
height: 256,
|
||||
cells: vec![Elements::Air; 256 * 256],
|
||||
})
|
||||
.insert(SpriteBundle {
|
||||
sprite: Sprite {
|
||||
flip_y: true,
|
||||
..default()
|
||||
},
|
||||
texture: image_handle,
|
||||
transform: Transform::from_translation(Vec3::new(256., 0., 0.)),
|
||||
transform: Transform::from_translation(Vec3::new(256., 0., 0.))
|
||||
.with_scale(Vec3::new(2., 2., 0.)),
|
||||
..default()
|
||||
});
|
||||
}
|
||||
|
@ -52,6 +61,63 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
|||
pub struct Chunk {
|
||||
width: usize,
|
||||
height: usize,
|
||||
cells: Vec<Elements>,
|
||||
}
|
||||
|
||||
pub fn simulate_chunk_system(mut chunk: Query<&mut Chunk>) {
|
||||
// We know for now there's only one chunk
|
||||
let chunk = chunk.get_single_mut();
|
||||
if chunk.is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut query = chunk.unwrap();
|
||||
let chunk = query.as_mut();
|
||||
|
||||
// Place sand
|
||||
let frac = chunk.width / 2;
|
||||
let x = (chunk.width - frac) / 2 + rand::thread_rng().gen_range(0..frac);
|
||||
let y = chunk.height - 1;
|
||||
chunk.cells[x + y * chunk.width] = Elements::Sand;
|
||||
|
||||
// Simulate sand
|
||||
for y in 0..chunk.height {
|
||||
for x in 0..chunk.width {
|
||||
let index = x + y * chunk.width;
|
||||
let element = chunk.cells.get(index).unwrap();
|
||||
match element {
|
||||
Elements::Air => {}
|
||||
Elements::Sand => {
|
||||
if y != 0 {
|
||||
let b_index = index - chunk.width;
|
||||
let bottom = chunk.cells.get(b_index).unwrap();
|
||||
if *bottom == Elements::Air {
|
||||
chunk.cells.swap(index, b_index);
|
||||
continue;
|
||||
}
|
||||
|
||||
if x != 0 {
|
||||
let bl_index = b_index - 1;
|
||||
let bottom_left = chunk.cells.get(bl_index).unwrap();
|
||||
if *bottom_left == Elements::Air {
|
||||
chunk.cells.swap(index, bl_index);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if x != chunk.width - 1 {
|
||||
let br_index = b_index + 1;
|
||||
let bottom_right = chunk.cells.get(br_index).unwrap();
|
||||
if *bottom_right == Elements::Air {
|
||||
chunk.cells.swap(index, br_index);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_chunk_texture_system(
|
||||
|
@ -68,13 +134,26 @@ pub fn update_chunk_texture_system(
|
|||
if let Some(image) = images.get_mut(image_handle) {
|
||||
for y in 0..chunk.height {
|
||||
for x in 0..chunk.width {
|
||||
// Just set each pixel to random colours for now
|
||||
let mut colour = (0, 0, 0);
|
||||
if let Some(element) = chunk.cells.get(x + y * chunk.width) {
|
||||
match element {
|
||||
Elements::Air => colour = (25, 24, 26),
|
||||
Elements::Sand => colour = (255, 216, 102),
|
||||
}
|
||||
}
|
||||
|
||||
let index = (x + y * chunk.width) * 4;
|
||||
image.data[index] = random::<u8>();
|
||||
image.data[index + 1] = random::<u8>();
|
||||
image.data[index + 2] = random::<u8>();
|
||||
image.data[index] = colour.0;
|
||||
image.data[index + 1] = colour.1;
|
||||
image.data[index + 2] = colour.2;
|
||||
image.data[index + 3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
enum Elements {
|
||||
Air,
|
||||
Sand,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue