Making Games in Rust – Part 6 – Generating a Map

If you did not read the previous articles, you may start here.

For future features, we will need a bigger world to move our player in. We need a bigger map.

This article builds on top of our previous code (the code I started with can be found here) a…


This content originally appeared on DEV Community and was authored by Sébastien Belzile

If you did not read the previous articles, you may start here.

For future features, we will need a bigger world to move our player in. We need a bigger map.

This article builds on top of our previous code (the code I started with can be found here) and adds an automatically generated map to our world.

Flat Floor

In map.rs, let's replace our spawn_floor method with the following code:

pub fn spawn_floor(mut commands: Commands, materials: Res<Materials>) {
    for x in 0..50 {
        add_tile(&mut commands, &materials, x as f32)
    }
}

fn add_tile(commands: &mut Commands, materials: &Res<Materials>, x: f32) {
    let rigid_body = RigidBodyBundle {
        position: Vec2::new(x, -2.).into(),
        body_type: RigidBodyType::Static,
        ..Default::default()
    };
    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(0.5, 0.5),
        ..Default::default()
    };
    commands
        .spawn_bundle(SpriteBundle {
            material: materials.floor_material.clone(),
            sprite: Sprite::new(Vec2::new(1., 1.)),
            ..Default::default()
        })
        .insert_bundle(rigid_body)
        .insert_bundle(collider)
        .insert(RigidBodyPositionSync::Discrete);
}

Compared to our previous code, we:

  1. Moved the content of the spawn_floor function to an add_tile function.
  2. Modify the input of the add_tile function so that it receives an x coordinate as well.
  3. Modify the width of our tiles from 10 to 1 world unit.
  4. Set the x component of our rigid body to the x coordinate provided as input.

The new spawn_floor function now contains a loop which calls our add_tile function with a coordinate going from 0 to 50.

Running the game will display a flat floor of length 50.

Image description

(Ha! Yeah! our player is also pink now)

Going Up or Down

To make this more interesting, our map should go up or down. Let's modify our add_tile function so that it takes a height as input:

fn add_tile(commands: &mut Commands, materials: &Res<Materials>, x: f32, height: u8) {
    let half_height = height as f32 / 2.;
    let rigid_body = RigidBodyBundle {
        position: Vec2::new(x, -2. + half_height).into(),
        body_type: RigidBodyType::Static,
        ..Default::default()
    };
    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(0.5, half_height),
        ..Default::default()
    };
    commands
        .spawn_bundle(SpriteBundle {
            material: materials.floor_material.clone(),
            sprite: Sprite::new(Vec2::new(1., height as f32)),
            ..Default::default()
        })
        .insert_bundle(rigid_body)
        .insert_bundle(collider)
        .insert(RigidBodyPositionSync::Discrete);
}

We will randomly determine the height to provide:

  1. Add the rand crate to your cargo.toml:
[dependencies]
rand = "0.8.4"
  1. Add a function to randomly pick an height variation:
use rand::prelude::*;
// ...
fn get_random_height_delta() -> i8 {
    let mut rng = thread_rng();
    let random_number: u32 = rng.gen_range(0..100);
    let delta = match random_number {
        0..=70 => 0,
        71..=80 => -1,
        81..=90 => 1,
        _ => 2,
    };
    delta
}
  1. Add a function to calculate the next height from the current height:
fn get_next_height(current_height: u8) -> u8 {
    let next_height = current_height as i8 + get_random_height_delta();
    return if next_height > 0 {
        next_height as u8
    } else {
        1
    };
}
  1. Finally, modify the spawn_floor function to send a random height to the add_tile function:
pub fn spawn_floor(mut commands: Commands, materials: Res<Materials>) {
    let mut height = 1;
    for x in 0..150 {
        add_tile(&mut commands, &materials, x as f32, height);
        height = get_next_height(height)
    }
}

Running the game should render a prettier map:

Image description

Image description

The final code is available here.


This content originally appeared on DEV Community and was authored by Sébastien Belzile


Print Share Comment Cite Upload Translate Updates
APA

Sébastien Belzile | Sciencx (2021-12-26T19:16:40+00:00) Making Games in Rust – Part 6 – Generating a Map. Retrieved from https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/

MLA
" » Making Games in Rust – Part 6 – Generating a Map." Sébastien Belzile | Sciencx - Sunday December 26, 2021, https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/
HARVARD
Sébastien Belzile | Sciencx Sunday December 26, 2021 » Making Games in Rust – Part 6 – Generating a Map., viewed ,<https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/>
VANCOUVER
Sébastien Belzile | Sciencx - » Making Games in Rust – Part 6 – Generating a Map. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/
CHICAGO
" » Making Games in Rust – Part 6 – Generating a Map." Sébastien Belzile | Sciencx - Accessed . https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/
IEEE
" » Making Games in Rust – Part 6 – Generating a Map." Sébastien Belzile | Sciencx [Online]. Available: https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/. [Accessed: ]
rf:citation
» Making Games in Rust – Part 6 – Generating a Map | Sébastien Belzile | Sciencx | https://www.scien.cx/2021/12/26/making-games-in-rust-part-6-generating-a-map/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.