Adding a map creation plugin #57

Merged
CoCo_Sol merged 39 commits from map-generation into main 2024-02-21 20:10:03 +00:00
2 changed files with 24 additions and 21 deletions
Showing only changes of commit 3cf5d76d00 - Show all commits

View file

@ -35,36 +35,45 @@ pub struct StartMapGeneration {
#[derive(Event)] #[derive(Event)]
pub struct EndMapGeneration; pub struct EndMapGeneration;
/// Spawns the tiles if the event is received. /// Generate each tiles of the map if the [StartMapGeneration] is received.
///
/// The map is generated using the [Perlin] noise function and the [HexSpiral].
///
/// It's generated one tile at a time, until the spiral is finished.
fn generate_map( fn generate_map(
mut event: EventReader<StartMapGeneration>, mut start_generation_events: EventReader<StartMapGeneration>,
mut end_map_event: EventWriter<EndMapGeneration>, mut end_generation_writer: EventWriter<EndMapGeneration>,
mut commands: Commands, mut commands: Commands,
mut local_noise: Local<Option<Perlin>>, mut local_noise: Local<Option<Perlin>>,
mut local_spiral: Local<Option<HexSpiral<i32>>>, mut local_spiral: Local<Option<HexSpiral<i32>>>,
) { ) {
// Handle map generation events. // Handle map generation events and create the spiral and the noise.
for event in event.read() { for event in start_generation_events.read() {
*local_noise = Some(Perlin::new(event.seed)); *local_noise = Some(Perlin::new(event.seed));
*local_spiral = Some(TilePosition::new(0, 0).spiral(event.radius as usize)); *local_spiral = Some(TilePosition::new(0, 0).spiral(event.radius as usize));
} }
// Check if the map is being generated.
let (Some(noise), Some(spiral)) = (local_noise.as_ref(), local_spiral.as_mut()) else { let (Some(noise), Some(spiral)) = (local_noise.as_ref(), local_spiral.as_mut()) else {
return; return;
}; };
// Spawn a tile until the spiral is finished
// If the map is generated, we send [EndMapGeneration] and set the local
// variables to None.
if let Some(position) = spiral.next() { if let Some(position) = spiral.next() {
let pixel_position = position.to_pixel_coordinates((0.2, 0.2)); let pixel_position = position.to_pixel_coordinates() * 0.2;
CoCo_Sol marked this conversation as resolved
Review

This should be in the get_type function and the value shouldn't be hard coded

This should be in the get_type function and the value shouldn't be hard coded
commands.spawn((get_type(pixel_position, noise), position as TilePosition)); commands.spawn((get_type(pixel_position, noise), position as TilePosition));
} else { } else {
end_map_event.send(EndMapGeneration); end_generation_writer.send(EndMapGeneration);
*local_noise = None; *local_noise = None;
*local_spiral = None; *local_spiral = None;
} }
} }
/// Returns the type of the position with the given noise. /// Returns the type of the position with the given noise.
fn get_type(position: (f32, f32), noise: &Perlin) -> Tile { fn get_type(position: Vec2, noise: &Perlin) -> Tile {
let value = noise.get([position.0 as f64, position.1 as f64]); let value = noise.get([position.x as f64, position.y as f64]);
match value { match value {
v if v <= -0.4 => Tile::Hill, v if v <= -0.4 => Tile::Hill,
v if v >= 0.4 => Tile::Forest, v if v >= 0.4 => Tile::Forest,

View file

@ -240,7 +240,6 @@ impl<T: Number> HexPosition<T> {
} }
/// Converts the current [HexPosition] into a pixel coordinate. /// Converts the current [HexPosition] into a pixel coordinate.
/// Input: The size of the hexagon in pixels (witdh, height).
/// ///
/// If you want to learn more about pixel coordinates conversion, /// If you want to learn more about pixel coordinates conversion,
/// you can check the /// you can check the
@ -252,18 +251,13 @@ impl<T: Number> HexPosition<T> {
/// use border_wars::map::hex::HexPosition; /// use border_wars::map::hex::HexPosition;
/// ///
/// let position = HexPosition(1, 0); /// let position = HexPosition(1, 0);
/// assert_eq!( /// assert_eq!(position.to_pixel_coordinates(), (3f32.sqrt(), 0.0));
/// position.to_pixel_coordinates((1.0, 1.0)),
/// (3f32.sqrt(), 0.0)
/// );
/// ``` /// ```
pub fn to_pixel_coordinates(&self, size: (f32, f32)) -> (f32, f32) { pub fn to_pixel_coordinates(&self) -> Vec2 {
( Vec2::new(
size.0 3f32.sqrt()
* 3f32 .mul_add(T::to_f32(self.0), 3f32.sqrt() / 2.0 * T::to_f32(self.1)),
.sqrt() 3.0 / 2.0 * T::to_f32(self.1),
.mul_add(T::to_f32(self.0), 3f32.sqrt() / 2.0 * T::to_f32(self.1)),
size.1 * (3.0 / 2.0 * T::to_f32(self.1)),
) )
} }