Bevy ECS是否有进行复杂查询的方法?

3

能否直接通过组件中字段的创建复杂查询来进行过滤?

例如,假设我有一个二维棋盘游戏(比如国际象棋之类的),我想知道特定坐标上是否有棋子。我的组件将如下所示:

#[derive(Component)]
struct BoardPosition {
    x: usize,
    y: usize,
}

我希望找到位置为(4,5)的方块。然后,我的查询将会遍历整个棋盘:

fn some_system(pieces: Query<&BoardPosition>) {
    for piece in pieces.iter() {
        if piece.x == 4 && piece.y == 5 {
            // This is my piece, now I can do whatever I want with it
        }
    }

}

但很明显,这需要O(n)的时间才能找到一个简单的棋子。如果我将棋盘存储为双向链表(即[[T; N]; N]),那么通过简单地执行board[4][5]就可以在O(1)的时间内找到这个棋子,但由于bevy拥有组件,我不能像这样简单地访问实体(或其它组件)。
有没有更聪明的方法,可以允许快速查询并且允许我获取(或更改)查询实体的其他组件?
1个回答

5
你可以使用数组来快速查找,同时让 Bevy 管理这些棋子。只需创建一个Board 资源(或带有Board 组件的实体),将其他实体的引用保存在其中。这样,您就可以在棋子 Query 上使用 .get() 来获取棋子。 示例代码如下:
struct Board {
    tiles: [[Option<Entity>; 8]; 8],
}

#[derive(Component)]
struct Piece {
    // they can still have x, y if you want
}

fn some_system(board: Res<Board>, pieces: Query<&Piece>) {
    let entity = board.tiles[4][5].expect("no entity at (4, 5)");
    let piece = pieces.get(entity).expect("entity at (4, 5) is not a Piece");
    // do whatever you want with the piece
}

酷!非常感谢!我是否需要在.get(entity)中要求一个查询参数,或者有其他方法可以获取实体的组件? 另外,为了升级这个答案 - 我认为将板作为资源插入而不是普通实体组件会更加简洁 :) - nir shahar
1
据我所知,是的,你必须拥有Query <&Piece>才能获取Piece。如果只有一个棋盘,那么你绝对应该使用资源;我只是不想在我的答案中做出假设。:) 我会更新的。 - kmdreko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接