error[E0277]: the trait bound `for<'a, 'b, 'c> fn(...) {system}: IntoSystem<(), (), _>` is not satisfied
--> src/main.rs:5:21
|
5 | .add_system(my_system)
| ---------- ^^^^^^^^^ the trait `IntoSystem<(), (), _>` is not implemented for fn item `for<'a, 'b, 'c> fn(...) {system}`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `IntoSystemConfigs`:
= ...
该错误(令人困惑地)指向代码中尝试添加系统的位置,但实际上,问题实际上出在fn函数定义中!
这是由于您的函数具有无效参数造成的。Bevy 只能接受特殊类型作为系统参数!
格式错误的查询出错
您还可能会出现如下错误:
error[E0277]: the trait bound `Transform: WorldQuery` is not satisfied
--> src/main.rs:10:12
|
10 | query: Query,
| ^^^^^^^^^^^^^^^ the trait `WorldQuery` is not implemented for `Transform`
|
= help: the following other types implement trait `WorldQuery`:
&'__w mut T
&T
()
(F0, F1)
(F0, F1, F2)
(F0, F1, F2, F3)
(F0, F1, F2, F3, F4)
(F0, F1, F2, F3, F4, F5)
and 54 others
note: required by a bound in `bevy::prelude::Query`
--> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.10.0/src/system/query.rs:276:37
|
276 | pub struct Query<'world, 'state, Q: WorldQuery, F: ReadOnlyWorldQuery = ()> {
| ^^^^^^^^^^ required by this bound in `Query`
要访问您的组件,您需要使用引用语法(& 或 &mut)。
error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied
--> src/main.rs:10:12
|
10 | query: Query<&Transform, &Camera, &GlobalTransform>,
| ^^^^^ ---------------- help: remove this generic argument
| |
| expected at most 2 generic arguments
|
note: struct defined here, with at most 2 generic parameters: `Q`, `F`
--> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.10.0/src/system/query.rs:276:12
|
276 | pub struct Query<'world, 'state, Q: WorldQuery, F: ReadOnlyWorldQuery = ()> {
| ^^^^^ - --------------------------
Borrow multiple fields from struct - Unofficial Bevy Cheat Book
非官方 Bevy 作弊书
4.5 从结构体中借用多个字段
当您有一个组件或资源(即具有多个字段的较大结构)时,有时您希望同时借用多个字段(可能是可变的)。
struct MyThing {
a: Foo,
b: Bar,
}
fn my_system(mut q: Query<&mut MyThing>) {
for thing in q.iter_mut() {
helper_func(&thing.a, &mut thing.b); // ERROR!
}
}
fn helper_func(foo: &Foo, bar: &mut Bar) {
// do something
}
这可能会导致有关借用冲突的编译器错误:
error[E0502]: cannot borrow `thing` as mutable because it is also borrowed as immutable
|
| helper_func(&thing.a, &mut thing.b); // ERROR!
| ----------- ----- ^^^^^ mutable borrow occurs here
| | |
| | immutable borrow occurs here
| immutable borrow later used by call
解决方案是使用“reborrow”习惯用法,这是 Rust 编程中常见但不明显的技巧:
// add this at the start of the for loop, before using `thing`:
// 在for循环的开头,在使用' thing '之前添加以下代码:
let thing = &mut *thing;
// or, alternatively, Bevy provides a method, which does the same:
// 或者,Bevy提供了一个方法,做同样的事情:
let thing = thing.into_inner();
// To simply position something at specific coordinates
// 简单地将某些东西定位到特定的坐标
let xf_pos567 = Transform::from_xyz(5.0, 6.0, 7.0);
// To scale an object, making it twice as big in all dimensions
// 缩放对象,使其在所有维度上都是原来的两倍大
let xf_scale = Transform::from_scale(Vec3::splat(2.0));
// To rotate an object in 2D (Z-axis rotation) by 30°
// 在2D (z轴旋转)中旋转对象30°
// (angles are in radians! must convert from degrees!)
// (角度是以弧度表示的!必须从度转换!)
let xf_rot2d = Transform::from_rotation(Quat::from_rotation_z((30.0_f32).to_radians()));
// 3D rotations can be complicated; explore the methods available on `Quat`
// 3D旋转可能很复杂;探索`Quat`上可用的方法
// Simple 3D rotation by Euler-angles (X, Y, Z)
// 简单的三维欧拉角旋转(X, Y, Z)
let xf_rot2d = Transform::from_rotation(Quat::from_euler(
EulerRot::XYZ,
(20.0_f32).to_radians(),
(10.0_f32).to_radians(),
(30.0_f32).to_radians(),
));
// Everything:
// 所有的:
let xf = Transform::from_xyz(1.0, 2.0, 3.0)
.with_scale(Vec3::new(0.5, 0.5, 1.0))
.with_rotation(Quat::from_rotation_y(0.125 * std::f32::consts::PI));
变换组件
在 Bevy 中,变换由两个 组件表示: Transform和GlobalTransform。
任何代表游戏世界中对象的实体都需要两者兼而有之。Bevy 的所有内置捆绑类型都 包含它们。
如果您在不使用这些捆绑包的情况下创建自定义实体,则可以使用以下方法之一来确保您不会错过它们:
SpatialBundle用于变换+可见性
TransformBundle仅用于变换
fn spawn_special_entity(
mut commands: Commands,
) {
// create an entity that does not use one of the common Bevy bundles,
// 创建一个不使用普通Bevy bundle的实体,
// but still needs transforms and visibility
// 但仍然需要转换和可见性
commands.spawn((
ComponentA,
ComponentB,
SpatialBundle {
transform: Transform::from_scale(Vec3::splat(3.0)),
visibility: Visibility::Hidden,
..Default::default()
},
));
}
fn inflate_balloons(
mut query: Query<&mut Transform, With>,
keyboard: Res>,
) {
// every time the Spacebar is pressed,
// 每次按空格键时,
// make all the balloons in the game bigger by 25%
// 让游戏中的所有气球变大25%
if keyboard.just_pressed(KeyCode::Space) {
for mut transform in &mut query {
transform.scale *= 1.25;
}
}
}
fn throwable_fly(
time: Res
/// Print the up-to-date global coordinates of the player
/// 打印玩家最新的全局坐标
fn debug_globaltransform(
query: Query<&GlobalTransform, With>,
) {
let gxf = query.single();
debug!("Player at: {:?}", gxf.translation());
}
// the label to use for ordering
// 用于排序的标签
use bevy::transform::TransformSystem;
app.add_systems(PostUpdate,
debug_globaltransform
// we want to read the GlobalTransform after
// 之后我们要读取GlobalTransform
// it has been updated by Bevy for this frame
// 这个帧已经被Bevy更新了
.after(TransformSystem::TransformPropagate)
);
fn camera_look_follow(
q_target: Query>,
mut transform_params: ParamSet<(
TransformHelper,
Query<&mut Transform, With>,
)>,
) {
// get the Entity ID we want to target
// 获取我们想要定位的实体ID
let e_target = q_target.single();
// compute its actual current GlobalTransform
// 计算它实际的当前GlobalTransform
// (could be Err if entity doesn't have transforms)
// (如果实体没有变形,可能会出错)
let Ok(global) = transform_params.p0().compute_global_transform(e_target) else {
return;
};
// get camera transform and make it look at the global translation
// 获取相机变换并使其查看全局转换
transform_params.p1().single_mut().look_at(global.translation(), Vec3::Y);
}
/// Prepare the game map, but do not display it until later
/// 准备游戏地图,但稍后再显示它
fn setup_map_hidden(
mut commands: Commands,
) {
commands.spawn((
GameMapEntity,
SceneBundle {
scene: todo!(),
visibility: Visibility::Hidden,
..Default::default()
},
));
}
/// When everything is ready, un-hide the game map
/// 当一切准备就绪,取消隐藏游戏地图
fn reveal_map(
mut query: Query<&mut Visibility, With>,
) {
let mut vis_map = query.single_mut();
*vis_map = Visibility::Visible;
}
可见性组件
在 Bevy 中,可见性由多个 组件表示:
Visibility:面向用户的切换开关(您可以在此处设置所需的内容)
InheritedVisibility:Bevy 使用它来跟踪任何父实体的状态
ViewVisibility:Bevy 使用它来跟踪实体是否应该实际显示
任何代表游戏世界中可渲染对象的实体都需要拥有它们。Bevy 的所有内置捆绑类型都包含它们。
如果您在不使用这些捆绑包的情况下创建自定义实体,则可以使用以下方法之一来确保您不会错过它们:
SpatialBundle用于变换+可见性
VisibilityBundle只是为了可见性
fn spawn_special_entity(
mut commands: Commands,
) {
// create an entity that does not use one of the common Bevy bundles,
// 创建一个不使用普通Bevy bundle的实体,
// but still needs transforms and visibility
// 但仍然需要转换和可见性
commands.spawn((
ComponentA,
ComponentB,
SpatialBundle {
transform: Transform::from_scale(Vec3::splat(3.0)),
visibility: Visibility::Hidden,
..Default::default()
},
));
}
/// Check if a specific UI button is visible
/// 检查特定的UI按钮是否可见
/// (could be hidden if the whole menu is hidden?)
/// (如果整个菜单都隐藏了,也可以隐藏吗?)
fn debug_player_visibility(
query: Query<&InheritedVisibility, With>,
) {
let vis = query.single();
debug!("Button visibility: {:?}", vis.get());
}
use bevy::render::view::VisibilitySystems;
app.add_systems(PostUpdate,
debug_player_visibility
.after(VisibilitySystems::VisibilityPropagate)
);
/// Check if balloons are seen by any Camera, Light, etc… (not culled)
/// 检查气球是否被任何相机、灯光等看到…(未剔除)
fn debug_balloon_visibility(
query: Query<&ViewVisibility, With>,
) {
for vis in query.iter() {
if vis.get() {
debug!("Balloon will be rendered.");
}
}
}
use bevy::render::view::VisibilitySystems;
app.add_systems(PostUpdate,
debug_balloon_visibility
.after(VisibilitySystems::CheckVisibility)
);
use std::time::Instant;
/// Say, for whatever reason, we want to keep track
/// 不管出于什么原因,我们想要跟踪数据
/// of when exactly some specific entities were spawned.
/// 特定实体何时生成。
#[derive(Component)]
struct SpawnedTime(Instant);
fn spawn_my_stuff(
mut commands: Commands,
time: Res
use bevy::time::Stopwatch;
#[derive(Component)]
struct JumpDuration {
time: Stopwatch,
}
fn jump_duration(
time: Res,
mut q_player: Query<&mut JumpDuration, With>,
kbd: Res>,
) {
// assume we have exactly one player that jumps with Spacebar
// 假设我们只有一个玩家使用空格键跳跃
let mut jump = q_player.single_mut();
if kbd.just_pressed(KeyCode::Space) {
jump.time.reset();
}
if kbd.pressed(KeyCode::Space) {
println!("Jumping for {} seconds.", jump.time.elapsed_secs());
// stopwatch has to be ticked to progress
// 秒表必须被计时才能继续
jump.time.tick(time.delta());
}
}
Logging, Console Messages - Unofficial Bevy Cheat Book
非官方 Bevy 作弊书
5.5 日志记录、控制台消息
相关官方例子: logs.
您可能已经注意到,当您运行 Bevy 项目时,您会在控制台窗口中收到消息。例如:
2022-06-12T13:28:25.445644Z WARN wgpu_hal::vulkan::instance: Unable to find layer: VK_LAYER_KHRONOS_validation
2022-06-12T13:28:25.565795Z INFO bevy_render::renderer: AdapterInfo { name: "AMD Radeon RX 6600 XT", vendor: 4098, device: 29695, device_type: DiscreteGpu, backend: Vulkan }
2022-06-12T13:28:25.565795Z INFO mygame: Entered new map area.
use bevy::log::LogPlugin;
// this code is compiled only if debug assertions are enabled (debug mode)
// 仅当启用调试断言时(调试模式),此代码才会编译
#[cfg(debug_assertions)]
app.add_plugins(DefaultPlugins.set(LogPlugin {
level: bevy::log::Level::DEBUG,
filter: "debug,wgpu_core=warn,wgpu_hal=warn,mygame=debug".into(),
}));
// this code is compiled only if debug assertions are disabled (release mode)
// 只有在禁用调试断言(release模式)时,此代码才会被编译
#[cfg(not(debug_assertions))]
app.add_plugins(DefaultPlugins.set(LogPlugin {
level: bevy::log::Level::INFO,
filter: "info,wgpu_core=warn,wgpu_hal=warn".into(),
}));
这是您不应仅出于性能原因在开发期间使用发布模式的一个很好的理由。
在 Microsoft Windows 上,您的游戏 EXE 还将启动一个控制台窗口,默认显示日志消息。您可能不希望在发布版本中出现这种情况。 看这里。
// spawn the parent and get its Entity id
// 生成父元素并获取其实体id
let parent = commands.spawn(MyParentBundle::default()).id();
// do the same for the child
// 对child做同样的操作
let child = commands.spawn(MyChildBundle::default()).id();
// add the child to the parent
// 将子元素添加到父元素
commands.entity(parent).push_children(&[child]);
// you can also use `with_children`:
// 你也可以使用`with_children`:
commands.spawn(MyParentBundle::default())
.with_children(|parent| {
parent.spawn(MyChildBundle::default());
});
fn close_menu(
mut commands: Commands,
query: Query>,
) {
for entity in query.iter() {
// despawn the entity and its children
// 移除实体和它的子实体
commands.entity(entity).despawn_recursive();
}
}
访问父母或孩子
要创建一个适用于层次结构的系统,您通常需要两个查询:
包含您需要从子实体中获取的组件
包含您需要从父实体获得的组件
两个查询之一应包含适当的组件,以获取与另一个查询一起使用的实体 ID:
在子查询中的Parent查询,如果您想迭代实体并查找其父级,或者
在父查询中Children查询,如果您想迭代实体并查找其子实体
例如,如果我们想得到有一个父元素的相机变换(Camera) ,以及它们的父元素的全局变换:
fn camera_with_parent(
q_child: Query<(&Parent, &Transform), With>,
q_parent: Query<&GlobalTransform>,
) {
for (parent, child_transform) in q_child.iter() {
// `parent` contains the Entity ID we can use
// `parent`包含我们可以使用的实体ID
// to query components from the parent:
// 从父组件中查询组件:
let parent_global_transform = q_parent.get(parent.get());
// do something with the components
}
}
fn process_squad_damage(
q_parent: Query<(&MySquadDamage, &Children)>,
q_child: Query<&MyUnitHealth>,
) {
// get the properties of each squad
// 获取每个小队的属性
for (squad_dmg, children) in q_parent.iter() {
// `children` is a collection of Entity IDs
// `children`是实体id的集合
for &child in children.iter() {
// get the health of each child unit
// 获取每个子单元的健康度
let health = q_child.get(child);
// do something
}
}
}
如果您需要以固定的时间间隔发生某些事情(常见的用例是物理更新),您可以使用 Bevy 的FixedTimestep Run Criteria将相应的系统添加到您的应用程序中。
use bevy::time::FixedTimestep;
// The timestep says how many times to run the SystemSet every second
// timestep表示每秒运行SystemSet的次数
// For TIMESTEP_1, it's once every second
// 对于TIMESTEP_1,它是每秒执行一次
// For TIMESTEP_2, it's twice every second
// 对于TIMESTEP_2,它是每秒两次
const TIMESTEP_1_PER_SECOND: f64 = 60.0 / 60.0;
const TIMESTEP_2_PER_SECOND: f64 = 30.0 / 60.0;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_system_set(
SystemSet::new()
// This prints out "hello world" once every second
// 这个函数每秒钟打印一次"hello world
.with_run_criteria(FixedTimestep::step(TIMESTEP_1_PER_SECOND))
.with_system(slow_timestep)
)
.add_system_set(
SystemSet::new()
// This prints out "goodbye world" twice every second
// 这个函数每秒钟打印两次"goodbye world
.with_run_criteria(FixedTimestep::step(TIMESTEP_2_PER_SECOND))
.with_system(fast_timestep)
)
.run();
}
fn slow_timestep() {
println!("hello world");
}
fn fast_timestep() {
println!("goodbye world");
}
use bevy::render::camera::RenderTarget;
fn debug_render_targets(
q: Query<&Camera>,
) {
for camera in &q {
match &camera.target {
RenderTarget::Window(wid) => {
eprintln!("Camera renders to window with id: {:?}", wid);
}
RenderTarget::Image(handle) => {
eprintln!("Camera renders to image asset with id: {:?}", handle);
}
RenderTarget::TextureView(_) => {
eprintln!("This is a special camera that outputs to something outside of Bevy.");
}
}
}
}
use bevy::render::camera::Viewport;
fn setup_minimap(mut commands: Commands) {
commands.spawn((
Camera2dBundle {
camera: Camera {
// renders after / on top of other cameras
// 渲染后/在其他相机之上
order: 2,
// set the viewport to a 256x256 square in the top left corner
// 将视口设置为左上角的256x256正方形
viewport: Some(Viewport {
physical_position: UVec2::new(0, 0),
physical_size: UVec2::new(256, 256),
..default()
}),
..default()
},
..default()
},
MyMinimapCamera,
));
}
如果您需要找出相机渲染到的区域(视口,如果配置,或整个窗口,如果没有):
fn debug_viewports(
q: Query<&Camera, With>,
) {
let camera = q.single();
// the size of the area being rendered to
// 渲染区域的大小
let view_dimensions = camera.logical_viewport_size().unwrap();
// the coordinates of the rectangle covered by the viewport
// 视口覆盖的矩形的坐标
let rect = camera.logical_viewport_rect().unwrap();
}
use bevy::render::view::visibility::RenderLayers;
// This camera renders everything in layers 0, 1
// 这个相机在0,1层渲染所有内容
commands.spawn((
Camera2dBundle::default(),
RenderLayers::from_layers(&[0, 1])
));
// This camera renders everything in layers 1, 2
// 这个相机在1、2层渲染所有内容
commands.spawn((
Camera2dBundle::default(),
RenderLayers::from_layers(&[1, 2])
));
// This sprite will only be seen by the first camera
// 这个精灵只会被第一个摄像头看到
commands.spawn((
SpriteBundle::default(),
RenderLayers::layer(0),
));
// This sprite will be seen by both cameras
// 这个精灵会被两个摄像头看到
commands.spawn((
SpriteBundle::default(),
RenderLayers::layer(1),
));
// This sprite will only be seen by the second camera
// 这个精灵只会被第二个摄像头看到
commands.spawn((
SpriteBundle::default(),
RenderLayers::layer(2),
));
// This sprite will also be seen by both cameras
// 这个精灵也会被两个摄像头看到
commands.spawn((
SpriteBundle::default(),
RenderLayers::from_layers(&[0, 2]),
));
use bevy::core_pipeline::clear_color::ClearColorConfig;
commands.spawn((
Camera2dBundle {
camera_2d: Camera2d {
// no "background color", we need to see the main camera's output
// 没有“背景色”,我们需要查看主摄像头的输出
clear_color: ClearColorConfig::None,
..default()
},
camera: Camera {
// renders after / on top of the main camera
// 渲染后/在主摄像机顶部
order: 1,
..default()
},
..default()
},
MyOverlayCamera,
));
androi中提到了布尔数组;
布尔数组默认的是false, 并且只会打印false或者是true
布尔数组的例子; 根据字符数组创建布尔数组
char[] c = {'p','u','b','l','i','c'};
//根据字符数组的长度创建布尔数组的个数
boolean[] b = new bool
文章摘自:http://blog.csdn.net/yangwawa19870921/article/details/7553181
在编写HQL时,可能会出现这种代码:
select a.name,b.age from TableA a left join TableB b on a.id=b.id
如果这是HQL,那么这段代码就是错误的,因为HQL不支持
1. 简单的for循环
public static void main(String[] args) {
for (int i = 1, y = i + 10; i < 5 && y < 12; i++, y = i * 2) {
System.err.println("i=" + i + " y="
异常信息本地化
Spring Security支持将展现给终端用户看的异常信息本地化,这些信息包括认证失败、访问被拒绝等。而对于展现给开发者看的异常信息和日志信息(如配置错误)则是不能够进行本地化的,它们是以英文硬编码在Spring Security的代码中的。在Spring-Security-core-x
近来工作中遇到这样的两个需求
1. 给个Date对象,找出该时间所在月的第一天和最后一天
2. 给个Date对象,找出该时间所在周的第一天和最后一天
需求1中的找月第一天很简单,我记得api中有setDate方法可以使用
使用setDate方法前,先看看getDate
var date = new Date();
console.log(date);
// Sat J
MyBatis的update元素的用法与insert元素基本相同,因此本篇不打算重复了。本篇仅记录批量update操作的
sql语句,懂得SQL语句,那么MyBatis部分的操作就简单了。 注意:下列批量更新语句都是作为一个事务整体执行,要不全部成功,要不全部回滚。
MSSQL的SQL语句
WITH R AS(
SELECT 'John' as name, 18 as