#2d-grid #grid #2d #utility #gamedev #macro-derive #game

game-grid

一个简单的2D网格,用于游戏原型设计。包括易于解析、索引和迭代器。

4个版本

0.1.3 2023年1月18日
0.1.2 2023年1月17日
0.1.1 2023年1月17日
0.1.0 2023年1月17日

#879 in 游戏开发

MIT 许可证

25KB
382

游戏网格

game-grid 提供了一个简单的2D网格,可以用于游戏原型设计。

主要功能

  • 通过 derive 宏,可以轻松地将字符串字面量解析为有类型的2D网格。
  • 使用二维向量结构进行索引,例如:Point { x: i32, y: i32 } 而不是总是写常规的 i = y * 宽度 + x
  • 类似于 std 的迭代器和实用工具。

描述

主结构是 Grid,它实现了可以包含用户 Cell 类型值的网格。用户单元格可以是任何类型,但最好与实现 GridCell 特质的枚举一起使用。 GridCell derive 宏允许自动将转换到和从 char,允许将网格转换为字符串或将字符串转换为网格。 Grid 提供了对单元格的访问,使用实现 GridPosition 特质的用户类型进行二维索引。在此基础上,Grid 提供了迭代器和其他实用工具。

参考

参考文档可以在 docs.rs 上找到:[https://docs.rs/game-grid/0.1.0/game_grid/](https://docs.rs/game-grid/0.1.0/game_grid/)

使用 Grid 和 Bevy IVec2

game-grid 的一个核心特性是能够使用我们用于制作游戏的二维向量结构索引网格。如果你在使用 Bevy,特性 bevy-ivec2 包含了 game_grid::GridPosition 的 trait 实现,允许使用 IVec2 作为索引。要使用它,请将以下行添加到你的 Cargo.toml

[dependencies]
game-grid = { features = ["bevy-ivec2"] }

示例

use game_grid::*;
// A custom Cell type deriving the trait GridCell with associated char literals.
#[derive(GridCell, Copy, Clone, Debug, PartialEq, Eq, Default)]
enum Cell {
    // Wall cells are represented by '#'.
    #[cell('#')]
    Wall,

    // Empty cells are represented by both ' ' and '.', the former will be used for display.
    // A default value can be used by some Grid functionalities.
    #[cell(' '|'.')]
    #[default]
    Empty,
     
    #[cell('o')]
    Food,

    // It is also possible to provide a range, the actual character can be captured.
    #[cell('A'..='Z')]
    Player(char),
}

// A 2D point struct deriving GridPosition in order to be used as index into the grid.
#[derive(GridPosition, PartialEq, Eq, Debug)]
struct Point {
    x: i32,
    y: i32,
}

// Create a grid of cells by parsing a string literal.
let grid: Grid<Cell> = "#####\n\
                        #A o#\n\
                        #####".parse().unwrap();

// Use iter() to iterate over the cells with associated position.
let food_position: Point = grid.iter().find(|(_, cell)| *cell == Cell::Food).unwrap().0;
assert_eq!(food_position, Point{ x: 3, y: 1 });

// Index into the grid with 2D point type and retrieved the enum value captured during parsing.
if let Cell::Player(player_char) = grid[Point::new(1, 1)] {
    println!("Player id: {player_char}");
}

// Print the grid.
print!("{grid}");
// outputs:
// #####
// #A o#
// #####

依赖关系

~1–19MB
~245K SLoC