回答有点晚了,但以防其他人遇到这个问题。
紫水晶书中给出的一些示例(在本例中为事件通道示例)依赖于捆绑您的系统,而不是直接将它们输入到 GameDataBuilder 中。
捆绑包在构建时可以访问世界对象。
请参阅官方紫水晶示例中的此示例,该示例展示了如何在系统构建中利用事件通道和访问世界对象。
https://github.com/amethyst/amethyst/tree/master/examples/events
例如:
# Custom Bundle.
#[derive(Debug)]
struct MyBundle;
impl<'a, 'b> SystemBundle<'a, 'b> for MyBundle {
fn build(
self,
world: &mut World,
builder: &mut DispatcherBuilder<'a, 'b>,
) -> Result<(), Error> {
builder.add(SpammingSystem, "spamming_system", &[]);
builder.add(
ReceivingSystemDesc::default().build(world),
"receiving_system",
&[],
);
Ok(())
}
}
# System.
#[derive(SystemDesc)]
#[system_desc(name(ReceivingSystemDesc))]
struct ReceivingSystem {
#[system_desc(event_channel_reader)]
reader: ReaderId<MyEvent>,
}
impl ReceivingSystem {
pub fn new(reader: ReaderId<MyEvent>) -> Self {
ReceivingSystem { reader }
}
}
impl<'a> System<'a> for ReceivingSystem {
type SystemData = Read<'a, EventChannel<MyEvent>>;
fn run(&mut self, my_event_channel: Self::SystemData) {
for event in my_event_channel.read(&mut self.reader) {
println!("Received an event: {:?}", event);
}
}
}
# Adding your bundle.
fn main() -> amethyst::Result<()> {
amethyst::start_logger(Default::default());
let assets_dir = application_root_dir()?.join("examples/events/assets");
let game_data = GameDataBuilder::default().with_bundle(MyBundle)?;
let mut game = Application::build(assets_dir, GameplayState)?
.with_frame_limit(FrameRateLimitStrategy::Sleep, 1)
.build(game_data)?;
game.run();
Ok(())
}