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.