Because we’re going to spawn more tiles in with the same logic we just used, we’ll pull that logic out into the Board
’s associated functions using an impl
block.
We’ll create two functions: Board::new
and Board::cell_position_to_physical
, as well as creating a new field: physical_size
on Board
.
struct Board {
size: u8,
physical_size: f32,
}
impl Board {
fn new(size: u8) -> Self {
let physical_size = f32::from(size) * TILE_SIZE
+ f32::from(size + 1) * TILE_SPACER;
Board {
size,
physical_size,
}
}
fn cell_position_to_physical(&self, pos: u8) -> f32 {
let offset =
-self.physical_size / 2.0 + 0.5 * TILE_SIZE;
offset
+ f32::from(pos) * TILE_SIZE
+ f32::from(pos + 1) * TILE_SPACER
}
}
Board::new
will instantiate a new Board
struct for us. The pattern of defining a new
method is fairly common in the Rust ecosystem. We can take advantage of this to add an additional physical_size
field on the struct, even though the user will never need to know how it's created.
Self
in this case refers to Board
because that's the type we're implementing methods for.
cell_position_to_physical
is a copy/paste of the logic we've already defined from earlier lessons. The biggest difference is that we're now using self.physical_size
because we are going to call this method on an instantiated struct, which means we have access to the fields on the Board
struct. cell_position_to_physical
will turn a grid position like 0,1,2,3 into a physical position like 10.0, 50.0, etc.
In spawn_board
we can now instantiate the board with
let board = Board::new(4);
and we can remove the old physical_board_size
in spawn_board
, replacing it with using board.physical_size
when spawning our board.
commands
.spawn(SpriteBundle {
sprite: Sprite {
color: colors::BOARD,
custom_size: Some(Vec2::new(
board.physical_size,
board.physical_size,
)),
..default()
},
..default()
})
Our Transform
component for the tile_placeholders can now use the board to translate an x or y into a physical position, cleaning up our code quite a bit by removing the math bits floating around, and giving a name to what we’re trying to do in each place.
transform: Transform::from_xyz(
board.cell_position_to_physical(tile.0),
board.cell_position_to_physical(tile.1),
1.0,
),
remember to remove the offset
from .with_children
as well, since we aren’t using it anymore.