Bevy 0.4:Rust内置的面向数据的游戏引擎

2020-12-20 03:55:15

在发布Bevy 0.3之后一个多月的时间,感谢66位贡献者,178个请求请求以及我们慷慨的赞助者,我很高兴宣布在crates.io上发布Bevy 0.4!

对于那些不知道的人,Bevy是一个内置在Rust中的令人耳目一新的简单数据驱动游戏引擎。您可以查看快速入门指南以开始使用。 Bevy也是免费的,永远开源!您可以在GitHub上获取完整的源代码。

Bevy现在有一个WebGL2渲染后端! @ mrk-its一直在努力构建Bevy WebGL2插件并扩展bevy_render以满足网络需求。他还组建了一个不错的网站,展示了各种Bevy示例和网络上运行的游戏。

在大多数受支持的Bevy平台上,您只能使用常规的主要功能(例如Windows,MacOS,Linux和Web)。这是在这些平台上运行的最小的Bevy应用程序:

但是,某些平台(当前为Android和iOS)需要额外的样板。这种不可思议的魔术容易出错,会占用空间,而且看起来也不是特别好。到现在为止,Bevy用户必须提供自己的样板……但仅此而已! Bevy 0.4添加了一个新的#[bevy_main] proc-macro,它将为您插入相关的样板。这是我们“只要在任何地方运行一次编写”的重要一步。目标。

这个Bevy App具有在Windows,MacOS,Linux,Android,iOS和Web上运行所需的所有代码:

现在,Bevy可以在运行时更新对着色器的更改,从而为您提供即时反馈,而无需重新启动应用程序。该视频没有加速!

///此系统遵循[Commands] [Resources] [Queries]顺序,并按预期方式编译为fn valid_system(mut命令:Commands,时间:Res< Time&gt ;,查询:Query<& Transform>){ } ///此系统未遵循要求的排序,这导致编译因fn invalid_system而失败(查询:Query<& Transform>,mut命令:Commands,time:Res< Time>){}

新手将不断成为这一目标的牺牲品。这些完全任意的约束是内部实现的一个怪癖。 IntoSystem特性仅针对特定订单实施。支持每个命令将成倍地影响编译时间。内部实现也使用著名的复杂宏构造。

为了解决这个问题,我彻底重写了我们如何生成系统。现在,我们使用SystemParam特征,我们为每种参数类型实现了该特征。这有很多好处:

轻松添加新参数:现在,我们(和用户)可以轻松创建新参数。只需实现SystemParam特性!

更简单的实现:新的实现要小得多,并且也更易于维护和理解。

//在Bevy 0.4中,该系统现在完全有效。凉! fn系统(查询:查询&转换&gt ;,命令:& mut命令,时间:响应<时间>){}

请注意,在Bevy 0.4中,命令现在看起来像命令:& mut命令,而不是mut命令:命令。

困惑?您不会是第一个!您可以将上面的查询解释为“对具有A分量,不具有B分量并且具有已更改的Velocity分量的所有实体的Transform和Velocity分量具有不变的引用”。

首先,通过有/无的类型嵌套使事情变得非常不清楚。此外,很难说出已更改的< Velocity>参数呢。它只是一个过滤器吗?它也返回Velocity分量吗?如果是这样,它是不变的还是可变的?

打破这些概念很有意义。在Bevy 0.4中,查询过滤器与查询组件是分开的。上面的查询如下所示:

//在系统中使用过滤器进行查询(查询:查询<(& Transform,& Velocity),(带有< A>,没有< B>,已更改的< Velocity>)>){} //在系统中没有过滤器的情况下查询(查询:查询<((& Transform,& Velocity)>){}

这样一目了然,您就可以轻松分辨出查询在做什么。这也使行为更具可组合性。例如,您现在可以在Changed< Velocity>无需实际获取Velocity分量。

系统现在可以具有输入和输出。这打开了许多有趣的行为,例如系统错误处理:

fn main(){App :: build()。 add_system(result_system.system()。chain(error_handler.system()))。 run();} fn result_system(query:Query<& Transform>)->结果<()> {让transform = query。得到(SOME_ENTITY)?; println! ("找到实体transform:{:?}&#34 ;, transform); OK(())} fn error_handler_system(In(result):In<结果<()&gt ;, error_handler:Res< MyErrorHandler>){如果让Err(err)=结果{error_handler。 handle_error(err); }}

//没有输入,也没有输出System< In =(),Out =()> //以usize作为输入并返回f32 System< In = usize,Out = f32> Bevy的旧时间表很好。 系统注册易于阅读且易于编写。 但是它也有很多局限性: 为了解决这些问题,我从头开始编写了一个新的Schedule系统。 在您担心之前,这些基本上都是不变的更改。 高级"应用程序构建器" 您知道并喜欢的语法仍然可用: 构造MyStage; impl MyStage的舞台{fn run(& mut self,world:& mut World,资源:& mut资源){//在这里做舞台。 //您具有访问世界和资源的独特权限,因此您可以自由地做任何事情}}