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