用途
本技能用于在 Bevy 引擎中实现作物生长与收获循环。当作物按计时器推进生长阶段,并且需要一条收获消息来记录产出时,可加载本技能。
主要能力
- 生长推进:作物组件存储阶段索引与已用时间,生长在
Time<Fixed>固定时钟上按间隔推进一个阶段。 - 收获消息:
Harvested是一次性的产出事实,仅在最后一个阶段就绪时触发,由库存系统消费。 - 离线追赶:读取
Time::elapsed_secs与记录上次访问时间的资源对比,应用自上次访问以来的秒数,然后存储新的时间标记。 - 季节缩放:
Season资源提供生长缩放系数,用于缩放整局中每株作物的生长速度。
使用方式
ECS 结构:
- 组件:生长已用时间与你定义的阶段索引。
- 资源:上次访问时间与季节缩放存放在资源中。
- 系统:在
FixedUpdate上推进生长,使用.chain()使收获读取生长刚写入的阶段。 - 消息:
Harvested是一次性产出事实,库存系统应用它。
示例代码(生长与收获):
#[derive(Component)]
struct Crop {
stage: u8,
elapsed: f32,
stage_seconds: f32,
stages: u8,
}
#[derive(Message)]
struct Harvested {
plot: Entity,
yield_item: u32,
}
fn grow(time: Res<Time<Fixed>>, mut crops: Query<&mut Crop>) {
let dt = time.delta_secs();
for mut crop in &mut crops {
if crop.stage + 1 >= crop.stages {
continue;
}
crop.elapsed += dt;
if crop.elapsed >= crop.stage_seconds {
crop.elapsed = 0.0;
crop.stage += 1;
}
}
}
fn harvest(
mut commands: Commands,
crops: Query<(Entity, &Crop)>,
mut harvested: MessageWriter<Harvested>,
) {
for (entity, crop) in &crops {
if crop.stage + 1 < crop.stages {
continue;
}
harvested.write(Harvested {
plot: entity,
yield_item: 7,
});
commands.entity(entity).despawn();
}
}
pub struct HarvestPlugin;
impl Plugin for HarvestPlugin {
fn build(&self, app: &mut App) {
app.add_message::<Harvested>()
.add_systems(FixedUpdate, (grow, harvest).chain());
}
}
离线追赶示例:
#[derive(Resource)]
struct LastVisit {
elapsed_secs: f32,
}
fn catch_up(time: Res<Time>, mut last: ResMut<LastVisit>, mut crops: Query<&mut Crop>) {
let now = time.elapsed_secs();
let gap = (now - last.elapsed_secs).max(0.0);
last.elapsed_secs = now;
if gap <= 0.0 {
return;
}
for mut crop in &mut crops {
let mut left = gap;
while left > 0.0 && crop.stage + 1 < crop.stages {
let need = (crop.stage_seconds - crop.elapsed).max(0.0);
if left < need {
crop.elapsed += left;
left = 0.0;
} else {
left -= need;
crop.elapsed = 0.0;
crop.stage += 1;
}
}
}
}
季节缩放示例:
#[derive(Resource)]
struct Season {
growth_scale: f32,
}
fn season_grow(time: Res<Time<Fixed>>, season: Res<Season>, mut crops: Query<&mut Crop>) {
let dt = time.delta_secs() * season.growth_scale.max(0.0);
for mut crop in &mut crops {
if crop.stage + 1 >= crop.stages {
continue;
}
crop.elapsed += dt;
if crop.elapsed >= crop.stage_seconds {
crop.elapsed -= crop.stage_seconds;
crop.stage += 1;
}
}
}
适用场景
- 作物按计时器推进生长阶段,成熟后触发收获消息。
- 需要离线追赶:玩家离开后再次进入时,按经过的时间补算生长。
- 需要全局季节系数缩放所有作物生长速度。
限制与约束
- 目标版本为 Bevy 0.20+。
- 核心 ECS 类型包括:
Component、Resource、Query、Commands、Startup、Update、Fixed/FixedMain(bevy::time)、.chain()、Plugin、DefaultPlugins、MinimalPlugins。消息与观察者属于所有权槽位,其 API 参见 bevy-events-messaging。 - 除非用
.chain()排序冲突系统,否则系统并行运行。 - 两个都可变查询同一组件的系统必须排序(
.chain())或拆分,使只有一个写入。 - 不要在文档 URL 中固定
/0.20.0/。 - 不要在本技能中发明物理、导航、网络或 XR crate。
- 本机制不使用场景树节点或信号总线。
- 不要使用虚构 API 或未命名的第三方 crate 作为求解器。
相关技能
前置:bevy-master、bevy-ecs-composition、bevy-inventory-system、bevy-data-resources、bevy-events-messaging。
补充:bevy-state-machines。