用途
本技能用于在 Bevy 引擎中实现遭遇战的波次循环:当敌人以波次形式到达、并在清空后推进波次索引时加载。关键词包括 Bevy、waves、spawn、encounter、ECS。
主要能力
技能围绕 ECS 结构给出实现约定:
- 组件:波次索引与剩余数量由使用者自行定义。
- 资源:运行期全局表存放在资源中(参见 bevy-data-resources)。
- 系统:在 Update 或固定时间步上修改这些组件;当伤害必须先于死亡结算时使用 .chain()。
- 消息:一次性事实(命中、拾取、任务推进)通过 bevy-events-messaging 处理;波次推进本身是资源,而不是新的消息类型。
使用方式
示例依赖为 bevy = "0.20"。波次索引与生成预算合为一个资源,每个敌人是一个实体。生成与清空共享 WaveDirector,因此这两个系统被串联。
#[derive(Resource)]
struct WaveDirector {
index: u32,
budget: u32,
intermission: f32,
}
#[derive(Component)]
struct Enemy;
fn boot(mut commands: Commands) {
commands.insert_resource(WaveDirector {
index: 1,
budget: 4,
intermission: 0.0,
});
}
fn spawn_budget(mut commands: Commands, mut wave: ResMut<WaveDirector>) {
if wave.intermission > 0.0 || wave.budget == 0 {
return;
}
for _ in 0..wave.budget {
commands.spawn(Enemy);
}
wave.budget = 0;
}
fn advance_on_clear(
enemies: Query<(), With<Enemy>>,
mut wave: ResMut<WaveDirector>,
time: Res<Time>,
) {
if !enemies.is_empty() {
wave.intermission = 0.0;
return;
}
wave.intermission += time.delta_secs();
if wave.intermission < 2.0 {
return;
}
wave.index += 1;
wave.budget = 3 + wave.index;
wave.intermission = 0.0;
}
fn install(app: &mut App) {
app.add_systems(Startup, boot)
.add_systems(Update, (spawn_budget, advance_on_clear).chain());
}
固定步适合对存活敌人的剩余时间进行计时。上面的清空系统留在 Update 上,只读取 Enemy。
#[derive(Component)]
struct Lifetime(f32);
fn age_enemies(
mut commands: Commands,
mut enemies: Query<(Entity, &mut Lifetime)>,
time: Res<Time<Fixed>>,
) {
for (entity, mut life) in &mut enemies {
life.0 -= time.delta_secs();
if life.0 <= 0.0 {
commands.entity(entity).despawn();
}
}
}
fn install_lifetime(app: &mut App) {
app.add_systems(FixedUpdate, age_enemies);
}
状态归属
| 部分 | 归属 | 谁可修改 | 调度 |
|---|---|---|---|
| 单个实体上的数据 | Component | 一个系统通过 Query | Update 或 FixedMain |
| 整个应用的一个值 | Resource | 一个系统 | Startup 插入,随后由读取它的调度 |
| 生成 | Commands | 执行生成的系统 | 初始世界用 Startup;运行期生成用后续调度 |
| 不可竞争的顺序 | .chain() | 仅被串联的系统 | 同一调度 |
| 插件边界 | Plugin | build 注册系统与资源 | 应用运行之前 |
借用规则:两个系统若都可变查询同一组件,必须排序(.chain())或拆分,使只有一个写入。无关系统保持并行。
决策
| 如果你需要 | 这样做 | 不要 |
|---|---|---|
| 每实体数据 | Component + Query | 所有实体共享一个可变大对象 |
| 应用级配置或时钟 | Resource | 把值复制到每个实体 |
| 稳定的模拟步 | FixedMain 与 Fixed 时钟 | 把模拟绑定到原始帧 Update |
| 启动时生成 | Startup 中的 Commands | 从渲染系统生成 |
| 非共享状态的跨系统通知 | bevy-events-messaging 中的消息或观察者槽位 | 在本文件中新造事件类型 |
| 文档集合之外的 API | 阅读 Bevy 官方页面 | 编造的 crate 或 API |
适用场景
- 敌人按波次到达、清空后推进波次索引的遭遇战。
- 需要把波次、生成器与遭遇数据构建为组件的场景。
- 需要区分每实体数据、应用级资源与一次性消息的 ECS 设计。
限制与边界
- 波次、生成器与遭遇数据由使用者自行构建为组件。
- 敌人移动路由到 bevy-ai-navigation 与 bevy-character-movement。
- 目标为 Bevy 0.20+。核心 ECS 类型包括 Component、Resource、Query、Commands、Startup、Update、Fixed / FixedMain(bevy::time)、.chain()、Plugin、DefaultPlugins、MinimalPlugins。消息与观察者属于归属槽位,其 API 见 bevy-events-messaging。除非 .chain() 对冲突系统排序,否则系统并行运行。
- 不要在文档 URL 中固定 /0.20.0/;链接保持指向最新版本,0.20 目标只在正文中说明一次。
- 不要从两个未排序的系统可变查询同一组件。
- 不要在此处发明物理、导航、网络或 XR crate;本技能只命名有文档的 Bevy crate 与模块。
- 不要使用编造的 API 或未命名的第三方 crate 作为选定求解器;Bevy 代码保持惯用 ECS,只使用有文档的 Bevy API。
- 参考:bevy-master 的库固定为 0.20.0;官方页面保持在无版本站点上。
相关技能
前置:bevy-master(枢纽与调度)、bevy-ecs-composition(组件与系统)、bevy-ai-navigation(生成角色做什么)、bevy-data-resources(表与定义)、bevy-events-messaging(一次性事实)。
补充:bevy-state-machines(模式标志)。
下游/消费者:暂无。
主技能:bevy-master(Bevy 路由器)。