一、前言
目前市面上的游戏大都是由C/C++、C#这两个语言开发的,但rust同样也可以开发游戏,用到的就是本文要介绍的bevy框架:bevy
从初步使用来说,bevy框架很优秀,整体运行逻辑不算复杂,就像开发一个正常的软件一样即可,最终编译得到的就是一个二进制文件,你发送给别人、别人就能直接启动运行。
只不过美中不足的是,我们只能通过调整代码的方式配置各种资源,并不能像使用Unity那样可以直接在工作台拖拽资源实现游戏开发。
但个人感觉它的潜力是很大的。
二、基本配置
bevy可以作为一个crate引入到你的项目中去:
[dependencies]
bevy = "0.14"
同时为了提高编译速度,官方推荐再添加下面两个配置项到你的配置文件中去:
# Enable a small amount of optimization in the dev profile.
[profile.dev]
opt-level = 1
# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]
opt-level = 3
这样编译出来的可执行文件目前大概在45M左右,但可以进一步缩减,你需要再添加配置项:
[profile.release]
strip = true # Automatically strip symbols from the binary.
opt-level = "z" # Optimize for size.
lto = true
codegen-units = 1
panic = "abort"
这样编译出来的可执行文件就只有十多兆了,非常小巧。
此时整个配置文件的格式为:
[package]
name = "game"
version = "0.1.0"
edition = "2021"
[dependencies]
bevy = "0.14"
# Enable a small amount of optimization in the dev profile.
[profile.dev]
opt-level = 1
# Enable a large amount of optimization in the dev profile for dependencies.
[profile.dev.package."*"]
opt-level = 3
[profile.release]
strip = true # Automatically strip symbols from the binary.
opt-level = "z" # Optimize for size.
lto = true
codegen-units = 1
panic = "abort"
三、基本概念与使用
bevy中采用的是”实体组件系统“这一概念,英文为:Entity Component System,通常被简写为ECS
。
简单来说,bevy中只有三个东西:实体、组件、系统。
其中多个组件可以构成一个实体,该实体通过系统去知道自己后续应该如何运作。
所以你可以理解为:实体是核心,组件是零部件、系统就是实体的动作。
如果要和rust中的类型相对应,那么实体就是普通的结构体,比如:
struct Entity(u64);
但要注意,从我目前看到的情况,各种代码中并没有直接使用到实体,而是通过用元组的方式组合组件形成一个实体:
(组件1,组件2)
而组件就是添加了特定Component宏的结构体:
#[derive(Component)]
struct Position {
x: f32,
y: f32,
}
系统,则是普通的rust函数:
fn print_position_system(query: Query<&Position>) {
for position in &query {
println!("position: {} {}", position.x, position.y);
}
}
只不过这个函数的参数可能会看起来比较奇怪,这个我们后面会介绍,它是系统概念的核心实现。
一个简单的示例代码如下,我们来拆解一下逻辑:
use bevy::prelude::*;
#[derive(Component)]
struct Name(String);
#[derive(Component)]
struct People;
fn main() {
App::new()
.add_systems(Startup, setup)
.add_systems(Update, update)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn((People, Name("test".to_string())));
}
fn update(query: Query<&Name, With<People>>) {
for name in query.iter() {
println!("Hello, {}!", name.0);
}
}
首先为了使用bevy中提供的各种工具,第一步就将所有常用的东西全部导入了: