Add basic falling sand
This commit is contained in:
parent
ce4e13005f
commit
754466ea16
|
@ -11,14 +11,17 @@ use bevy::{
|
||||||
sprite::SpriteBundle,
|
sprite::SpriteBundle,
|
||||||
transform::components::Transform,
|
transform::components::Transform,
|
||||||
};
|
};
|
||||||
use rand::random;
|
use rand::Rng;
|
||||||
|
|
||||||
pub struct FallingSandPlugin;
|
pub struct FallingSandPlugin;
|
||||||
|
|
||||||
impl Plugin for FallingSandPlugin {
|
impl Plugin for FallingSandPlugin {
|
||||||
fn build(&self, app: &mut bevy::prelude::App) {
|
fn build(&self, app: &mut bevy::prelude::App) {
|
||||||
app.add_systems(Startup, setup);
|
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 {
|
.spawn(Chunk {
|
||||||
width: 256,
|
width: 256,
|
||||||
height: 256,
|
height: 256,
|
||||||
|
cells: vec![Elements::Air; 256 * 256],
|
||||||
})
|
})
|
||||||
.insert(SpriteBundle {
|
.insert(SpriteBundle {
|
||||||
|
sprite: Sprite {
|
||||||
|
flip_y: true,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
texture: image_handle,
|
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()
|
..default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,6 +61,63 @@ fn setup(mut commands: Commands, mut images: ResMut<Assets<Image>>) {
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
width: usize,
|
width: usize,
|
||||||
height: 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(
|
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) {
|
if let Some(image) = images.get_mut(image_handle) {
|
||||||
for y in 0..chunk.height {
|
for y in 0..chunk.height {
|
||||||
for x in 0..chunk.width {
|
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;
|
let index = (x + y * chunk.width) * 4;
|
||||||
image.data[index] = random::<u8>();
|
image.data[index] = colour.0;
|
||||||
image.data[index + 1] = random::<u8>();
|
image.data[index + 1] = colour.1;
|
||||||
image.data[index + 2] = random::<u8>();
|
image.data[index + 2] = colour.2;
|
||||||
image.data[index + 3] = 255;
|
image.data[index + 3] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
enum Elements {
|
||||||
|
Air,
|
||||||
|
Sand,
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue