

Making Games in Rust - Part 6 - Generating a Map
source link: https://dev.to/sbelzile/making-games-in-rust-part-6-generating-a-map-4aic
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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);
}
Enter fullscreen mode
Exit fullscreen mode
Compared to our previous code, we:
- Moved the content of the
spawn_floor
function to anadd_tile
function. - Modify the input of the
add_tile
function so that it receives anx
coordinate as well. - Modify the width of our tiles from 10 to 1 world unit.
- 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.
(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);
}
Enter fullscreen mode
Exit fullscreen mode
We will randomly determine the height to provide:
- Add the
rand
crate to yourcargo.toml
:
[dependencies]
rand = "0.8.4"
Enter fullscreen mode
Exit fullscreen mode
- 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
}
Enter fullscreen mode
Exit fullscreen mode
- 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
};
}
Enter fullscreen mode
Exit fullscreen mode
- Finally, modify the
spawn_floor
function to send a random height to theadd_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)
}
}
Enter fullscreen mode
Exit fullscreen mode
Running the game should render a prettier map:
The final code is available here.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK