新手入门: 基于bevy打造一款小球按键移动的游戏
前言
bevy是一款基于纯rust的游戏库, 即使你没有任何rust基础, 但只要你有一点编程的基础知识, 便能看懂如何基于bevy开发简单的小球移动游戏.
想了解bevy游戏详情的同学们, 欢迎点击github开源库查看
相较与其他游戏库, bevy诞生的最晚, 2020年才开发出来, 但是它的star数量已经高达32k多, 这足以说明该游戏库已经取得广大码农的认可及支持. 好, 废话不多说, 让我们开始bevy小游戏旅程吧!
准备工作
毫无疑问, 你需要在你电脑上安装rust, 安装详情不在这里多加赘述. 安装好了之后, 执行rustc --version
, 控制台输出版本信息即可.
在本地新建文件夹bevy-learn
, 进入该文件夹内, 执行cargo new first-bevy
命令之后, 你会发现在bevy-learn
中, 新增了first-bevy
文件夹, 并且该文件夹内已有如下图的红框文件
Cargo.toml
相当于前端npm的包管理依赖文件
main.rs
程序的主入口函数, 里面有main
方法
进入first-bevy
文件夹, 执行cargo run
, 控制台会打印hello world
一切准备就绪, 话不多说, 我们正式开始吧!
正文
完整可运行的游戏代码如下所示
use bevy::{
// 由于是*, 所以会引入非常多bevy常用的东西
prelude::*,
// 导入bevy库的sprite模块中的Mesh2dHandle和MaterialMesh2dBundle结构体, 用于渲染小球
sprite::{MaterialMesh2dBundle, Mesh2dHandle},
};
// 小球的颜色
const BALL_COLOR: Color = Color::rgb(0.5, 0.5, 1.0);
// 小球每次移动的步长(像素)
const MOVE_STEP: f32 = 5.0;
// 定义一个名为Player的组件结构体,也就是我们操作的球体.
// 这种没有内容的结构体Component, 在bevy中被称为Marker Component, 通常用于标记一个Entity
#[derive(Component)]
struct Player;
fn main() {
// App是bevy引擎程序的总入口
App::new()
// 添加默认插件
.add_plugins(DefaultPlugins)
// add_systems向App中添加一个系统System
// setup函数会在App初始化时被调度一次, 后续都不会再被调度
// 类似Startup的调度类型在bevy中被称为Schedule
.add_systems(Startup, setup)
// 添加更新时的player_move
.add_systems(Update, player_move)
.run();
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
// 在场景中生成一个2d相机
commands.spawn(Camera2dBundle::default());
// 创建一个圆形的网格, 并获取其句柄
let mesh = Mesh2dHandle(meshes.add(Circle {radius: 50.0}));
// 在场景中生成一个小球实体, 使用MaterialMeshe2dBundle包装网格和材质
commands.spawn((
MaterialMesh2dBundle{
mesh: mesh,
material: materials.add(BALL_COLOR),
..default()
},
Player,
));
}
fn player_move(
key_input: Res<ButtonInput<KeyCode>>,
mut query: Query<(&Player, &mut Transform)>,
) {
// 获取玩家实体的Player组件和Transform组件的可变引用.
// Transform用来存储小球的形态, 位置等数据的bevy原生Component
let (_, mut transform) = query.single_mut();
// 如果按下W键, 向上移动小球
if key_input.pressed(KeyCode::KeyW) {
transform.translation.y += MOVE_STEP;
println!("Up translation: {:?}", transform.translation);
}
// 向下移动
if key_input.pressed(KeyCode::KeyS) {
transform.translation.y -= MOVE_STEP;
println!("Down translation: {:?}", transform.translation);
}
// 向右移动
if key_input.pressed(KeyCode::KeyD) {
transform.translation.x += MOVE_STEP;
println!("Right translation: {:?}", transform.translation);
}
// 向左移动
if key_input.pressed(KeyCode::KeyA) {
transform.translation.x -= MOVE_STEP;
println!("Left translation: {:?}", transform.translation);
}
}
// fn hello_world_system() {
// // ! 符号用于调用宏(Macro),它是 Rust 中用于调用宏的语法
// println!("hello world")
// }
fn setup
函数只会在游戏初始化(Startup
)时调用, 后续都不会再调用它. 该函数内有三个参数:
-
mut commands: Commands
: 这是一个 Commands 类型的可变引用,用于执行一系列的命令来创建、修改或删除 ECS(Entity-Component-System)中的实体、组件等. ECS做游戏的小伙伴们肯定很熟悉, 它与MVC类似, 是种架构模式, 但是它是面向数据的编程. 举个简单的例子, 张三是个Entity, 他有姓名、性别、从事的工作..., 这些都是他的数据, 我们将这些数据存放于Component中, 若哪天某企业需要做张三的背景调查, 则需要使用System查询到张三的数据信息. -
mut meshes: ResMut<Assets<Mesh>>
: 这是一个 ResMut<Assets> 类型的可变引用,用于管理和访问 Mesh 类型的资源。在 Rust 中,ResMut 用于表示可变引用,Assets 表示一种资源类型,用于存储和管理 Mesh 实例 -
mut materials: ResMut<Assets<ColorMaterial>>
: 这是一个 ResMut<Assets> 类型的可变引用,用于管理和访问 ColorMaterial 类型的资源。类似地,Assets 表示一种资源类型,用于存储和管理 ColorMaterial 实例
fn setup
使用command
创建了小球实体, 使用 meshes
来加载和管理网格资源,使用 materials
来加载和管理材质资源
效果图
我们可以按WASD控制它的上左右下移动, 感兴趣的小伙伴们赶紧动手试试吧!
转载自:https://juejin.cn/post/7372135071980077071