创建并移动实体
将对象放到屏幕上。
创建并移动实体 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。
命令:延迟生成
系统并行运行时,您不能直接修改 World。相反,应当通过 Commands 将结构变化加入队列。
生成实体、销毁实体以及添加组件的操作都会先被记录,并在调度阶段结束时应用,从而保证访问安全。
fn setup(mut commands: Commands) {
commands.spawn_empty();
}使用 Bundle 生成实体
Bundle 是一组同时插入的组件。最简单的 Bundle 就是一个组件元组。
Bevy 会将元组中的每个元素视为要附加的组件,因此一次生成调用就能为实体提供全部初始数据。
fn setup(mut commands: Commands) {
commands.spawn((
Position { x: 0.0, y: 0.0 },
Velocity { x: 1.5, y: 0.0 },
Player,
));
}用于观察世界的摄像机
没有摄像机就不会渲染任何内容。对于 2D 游戏,请在启动系统中生成一个 Camera2d。
摄像机本身也是一个带有摄像机组件的实体,这是 ECS 统一性的又一个例子。场景中的一切都是实体。
fn setup(mut commands: Commands) {
commands.spawn(Camera2d::default());
}生成精灵
要绘制某个对象,请为实体添加 Sprite 和 Transform。Transform 保存世界空间中的位置、旋转和缩放。
有颜色的精灵不需要图像资源,这对于在导入美术资源之前制作移动原型非常方便。
commands.spawn((
Sprite::from_color(Color::srgb(0.2, 0.7, 1.0), Vec2::new(40.0, 40.0)),
Transform::from_xyz(0.0, 0.0, 0.0),
Velocity { x: 80.0, y: 0.0 },
));Transform 与自定义 Position
在真实的 Bevy 游戏中,您通常会移动内置的 Transform,而不是自定义的 Position,因为渲染系统会直接读取 Transform。
平移量是一个 Vec3。对于 2D,您需要修改 x 和 y,并保留 z 用于控制绘制顺序。
#[derive(Component)]
struct Velocity { x: f32, y: f32 }
fn apply_velocity(mut q: Query<(&mut Transform, &Velocity)>) {
for (mut tf, vel) in &mut q {
tf.translation.x += vel.x;
tf.translation.y += vel.y;
}
}以可变方式迭代查询
要修改组件数据,请请求 &mut T,并遍历 &mut query。每个元素都会提供可变引用。
Bevy 保证不会同时让两个系统持有互相冲突的可变访问,因此即使其他系统正在运行,这个循环也是安全的。
fn move_all(mut q: Query<&mut Transform, With<Player>>) {
for mut tf in &mut q {
tf.translation.x += 1.0;
}
}生成多个实体
循环可以让您填充关卡。在 Rust 的 for 循环中调用 spawn,即可创建障碍物网格或敌人群。
每次迭代都会将自己的命令加入队列,所有命令会在阶段边界统一应用。
fn spawn_row(mut commands: Commands) {
for i in 0..5 {
commands.spawn((
Sprite::from_color(Color::WHITE, Vec2::splat(20.0)),
Transform::from_xyz(i as f32 * 30.0, 0.0, 0.0),
));
}
}销毁实体
使用 commands.entity(id).despawn() 可以彻底移除实体。这会释放其组件,并回收实体索引。
通常,您会在查询到实体 Entity ID 的系统中销毁实体,例如销毁已经离开屏幕的子弹。
fn cleanup(mut commands: Commands, q: Query<(Entity, &Transform)>) {
for (e, tf) in &q {
if tf.translation.y > 600.0 {
commands.entity(e).despawn();
}
}
}稍后添加组件
运行时可以通过 insert 为现有实体附加新组件。这就是为获得强化的玩家添加 Shield 标签的方式。
移除组件的方式类似,只需使用 remove::<T>()。两者都是结构变化,因此都要通过 Commands 执行。
commands.entity(player).insert(Shield { hits: 3 });
// later
commands.entity(player).remove::<Shield>();使用 Z 进行分层
在 2D 中,变换平移量的 z 值决定绘制顺序。z 越高,渲染结果越靠上层。
请为背景设置较低的 z,为玩家设置较高的 z,这样精灵就不会消失在场景后面。
// background behind, player in front
commands.spawn((bg_sprite, Transform::from_xyz(0.0, 0.0, 0.0)));
commands.spawn((player_sprite, Transform::from_xyz(0.0, 0.0, 10.0)));连接各部分
在 Startup 中生成实体,在 Update 中移动实体。启动系统只创建一次摄像机和实体;更新系统则每帧推进它们的状态。
这种分离方式可以避免初始化逻辑进入每帧执行的关键路径。
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, apply_velocity)
.run();快速检查
思考结构变化是如何应用的。
回顾:生成与移动
您可以通过 Commands 使用 Bundle 生成实体,使用 Sprite 和 Transform 渲染实体,并在 Update 系统中修改变换来移动实体。
销毁实体和插入组件也都是命令。接下来,我们将让移动响应键盘输入和实际经过的时间。
常见问题解答
「创建并移动实体」课时是免费的吗?
是的 — 「创建并移动实体」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。
「创建并移动实体」这节课中我会学到什么?
将对象放到屏幕上。 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn Rust Coding 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「创建并移动实体」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn Rust Coding 课中编写并运行代码吗?
能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。