Adding an Arena Config
To begin with, let's make the Arena
dimensions configurable. Add this structure to a new file config.rs
.
#[derive(Debug, Deserialize, Serialize)]
struct ArenaConfig {
pub height: f32,
pub width: f32,
}
impl Default for ArenaConfig {
fn default() -> Self {
ArenaConfig {
height: 100.0,
width: 100.0,
}
}
}
The default values match the values used in the full example, so if we don't use a config file things will
look just like the Pong example. Another option would be to use [#serde(default)]
, which allows
you to set the default value of a field if that field is not present in the config file. This is different
than the Default
trait in that you can set default values for some fields while requiring others
be present. For now though, let's just use the Default
trait.
Adding the Config to the World
Now, in main.rs
, add the following lines:
use crate::config::ArenaConfig;
We'll need to load the config at startup, so let's add this to the run
function in main.rs
let arena_config = ArenaConfig::load(&config)?;
Now that we have loaded our config, we want to add it to the world so other modules can access
it. We do this by adding the config as a resource during Application
creation:
.with_resource(arena_config)
.with_bundle(PongBundle::default())?
Now for the difficult part: replacing every use of ARENA_WIDTH
and ARENA_HEIGHT
with our config object.
First, let's change our initialisation steps in pong.rs
.
Add the following line to the top of pong.rs
:
use crate::config::ArenaConfig;
Now, in the initialise_paddles()
function, add the following lines after the initialisation of the
left_transform
and right_transform
.
let (arena_height, arena_width) = {
let config = &world.read_resource::<ArenaConfig>();
(config.height, config.width)
};
Now replace all references to ARENA_HEIGHT
with arena_height
and all references to ARENA_WIDTH
with
arena_width
. Do this for each initialisation function in pong.rs
.
Accessing Config Files from Systems
It is actually simpler to access a Config file from a system than via the World
directly. To access
it in the System
's run()
function, add it to the SystemData
type. This is what the BounceSystem
looks
like when it wants to access the ArenaConfig
.
use crate::config::ArenaConfig;
...
type SystemData = (
WriteStorage<'s, Ball>,
ReadStorage<'s, Paddle>,
ReadStorage<'s, Transform>,
Read<'s, AssetStorage<Source>>,
ReadExpect<'s, Sounds>,
Read<'s, Option<Output>>,
Read<'s, ArenaConfig>,
);
...
fn run(&mut self,
(mut balls, paddles, transforms, storage, sounds, audio_output, arena_config): SystemData) {
Now, in the run()
function, replace the reference to ARENA_HEIGHT
with arena_config.height
.
Add Read<'s, ArenaConfig>
to the WinnerSystem
and PaddleSystem
as well, replacing the reference to
ARENA_WIDTH
with arena_config.width
.
Making config.ron
Now for the final part: actually creating our config.ron
file. This will be very simple right now, and
expand as we add more configurable items. For now, just copy and paste the following into a new file. Feel
free to modify the height and width if you want.
arena: (
height: 100.0,
width: 100.0,
)