- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在尝试Bevy时,我需要拖放 Sprite 。
不幸的是,这似乎尚未准备就绪,或者我没有在文档中找到它。
实现这个目标的最惯用的方式是什么?
到目前为止,我尝试过的是in my answer,但是我很乐意接受另一个更好/更快/更惯用的解决方案。
最佳答案
不幸的是,我没有足够的经验来了解什么是惯用的,但是,这是我如何在应用程序中实现 Sprite 拖动的概述,这对我来说是一种好方法:
Cursor
组件),我在系统中每帧将其更新到光标的位置。 Hoverable
和Draggable
组件。我在一个系统中遍历那些对象,每个对象都在其中向实体添加/删除Hovered
和Dragged
组件,以指示它们是悬停还是拖动。 Dropped
组件。 Added<C>
过滤器)时运行,该系统将父对象设置为“光标位置”实体。 #![allow(clippy::type_complexity)]
use bevy::{prelude::*, render::camera::Camera};
fn main() {
App::build()
.init_resource::<State>()
.add_resource(WindowDescriptor {
title: "Bevy".to_string(),
width: 1024.0,
height: 768.0,
vsync: true,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_plugin(MyPlugin)
.run();
}
pub struct MyPlugin;
impl Plugin for MyPlugin {
fn build(&self, app: &mut AppBuilder) {
app.add_startup_system(setup.system())
.add_system_to_stage(stage::PRE_UPDATE, cursor_state.system())
.add_system_to_stage(stage::UPDATE, cursor_transform.system())
.add_system_to_stage(stage::UPDATE, draggable.system())
.add_system_to_stage(stage::UPDATE, hoverable.system())
.add_system_to_stage(stage::POST_UPDATE, drag.system())
.add_system_to_stage(stage::POST_UPDATE, drop.system())
.add_system_to_stage(stage::POST_UPDATE, material.system());
}
}
const SPRITE_SIZE: f32 = 55.0;
fn setup(
commands: &mut Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
let bevy_texture = asset_server.load("sprites/bevy-icon.png");
commands
.spawn(Camera2dBundle::default())
.spawn(())
.with(CursorState::default())
.spawn((Transform::default(), GlobalTransform::default(), Cursor));
for _ in 0..4 {
commands
.spawn(SpriteBundle {
material: materials.add(bevy_texture.clone().into()),
sprite: Sprite::new(Vec2::new(SPRITE_SIZE, SPRITE_SIZE)),
..Default::default()
})
.with(Hoverable)
.with(Draggable);
}
}
#[derive(Default)]
struct CursorState {
cursor_world: Vec2,
cursor_moved: bool,
}
struct Cursor;
struct Draggable;
struct Dragged;
struct Dropped;
struct Hoverable;
struct Hovered;
fn cursor_state(
mut state: ResMut<State>,
e_cursor_moved: Res<Events<CursorMoved>>,
windows: Res<Windows>,
mut q_cursor_state: Query<&mut CursorState>,
q_camera: Query<&Transform, With<Camera>>,
) {
let event_cursor_screen = state.er_cursor_moved.latest(&e_cursor_moved);
for mut cursor_state in q_cursor_state.iter_mut() {
if let Some(event_cursor_screen) = event_cursor_screen {
let window = windows.get_primary().unwrap();
let cam_transform = q_camera.iter().last().unwrap();
cursor_state.cursor_world =
cursor_to_world(window, cam_transform, event_cursor_screen.position);
cursor_state.cursor_moved = true;
} else {
cursor_state.cursor_moved = false;
}
}
}
fn cursor_transform(
commands: &mut Commands,
q_cursor_state: Query<&CursorState>,
mut q_cursor: Query<(Entity, &mut Transform), With<Cursor>>,
) {
let cursor_state = q_cursor_state.iter().next().unwrap();
for (cursor_e, mut transform) in q_cursor.iter_mut() {
transform.translation.x = cursor_state.cursor_world.x;
transform.translation.y = cursor_state.cursor_world.y;
commands.remove_one::<Parent>(cursor_e);
}
}
fn hoverable(
commands: &mut Commands,
q_cursor_state: Query<&CursorState>,
q_hoverable: Query<(Entity, &Transform, &Sprite), (With<Hoverable>, Without<Dragged>)>,
) {
let cursor_state = q_cursor_state.iter().next().unwrap();
if cursor_state.cursor_moved {
for (entity, transform, sprite) in q_hoverable.iter() {
let half_width = sprite.size.x / 2.0;
let half_height = sprite.size.y / 2.0;
if transform.translation.x - half_width < cursor_state.cursor_world.x
&& transform.translation.x + half_width > cursor_state.cursor_world.x
&& transform.translation.y - half_height < cursor_state.cursor_world.y
&& transform.translation.y + half_height > cursor_state.cursor_world.y
{
commands.insert_one(entity, Hovered);
} else {
commands.remove_one::<Hovered>(entity);
}
}
}
}
fn material(
mut materials: ResMut<Assets<ColorMaterial>>,
q_hoverable: Query<
(&Handle<ColorMaterial>, Option<&Hovered>, Option<&Dragged>),
With<Hoverable>,
>,
) {
let mut first = true;
for (material, hovered, dragged) in q_hoverable.iter() {
let (red, green, alpha) = if dragged.is_some() {
(0.0, 1.0, 1.0)
} else if first && hovered.is_some() {
first = false;
(1.0, 0.0, 1.0)
} else if hovered.is_some() {
(1.0, 1.0, 0.5)
} else {
(1.0, 1.0, 1.0)
};
materials.get_mut(material).unwrap().color.set_r(red);
materials.get_mut(material).unwrap().color.set_g(green);
materials.get_mut(material).unwrap().color.set_a(alpha);
}
}
fn cursor_to_world(window: &Window, cam_transform: &Transform, cursor_pos: Vec2) -> Vec2 {
// get the size of the window
let size = Vec2::new(window.width() as f32, window.height() as f32);
// the default orthographic projection is in pixels from the center;
// just undo the translation
let screen_pos = cursor_pos - size / 2.0;
// apply the camera transform
let out = cam_transform.compute_matrix() * screen_pos.extend(0.0).extend(1.0);
Vec2::new(out.x, out.y)
}
fn draggable(
commands: &mut Commands,
i_mouse_button: Res<Input<MouseButton>>,
q_pressed: Query<Entity, (With<Hovered>, With<Draggable>)>,
q_released: Query<Entity, With<Dragged>>,
) {
if i_mouse_button.just_pressed(MouseButton::Left) {
if let Some(entity) = q_pressed.iter().next() {
commands.insert_one(entity, Dragged);
}
} else if i_mouse_button.just_released(MouseButton::Left) {
for entity in q_released.iter() {
commands.remove_one::<Dragged>(entity);
commands.insert_one(entity, Dropped);
}
}
}
fn drag(
commands: &mut Commands,
mut q_dragged: Query<(Entity, &mut Transform, &GlobalTransform), Added<Dragged>>,
q_cursor: Query<(Entity, &GlobalTransform), With<Cursor>>,
) {
if let Some((cursor_e, cursor_transform)) = q_cursor.iter().next() {
for (entity, mut transform, global_transform) in q_dragged.iter_mut() {
let global_pos = global_transform.translation - cursor_transform.translation;
commands.insert_one(entity, Parent(cursor_e));
transform.translation.x = global_pos.x;
transform.translation.y = global_pos.y;
}
}
}
fn drop(
commands: &mut Commands,
mut q_dropped: Query<(Entity, &mut Transform, &GlobalTransform), Added<Dropped>>,
) {
for (entity, mut transform, global_transform) in q_dropped.iter_mut() {
let global_pos = global_transform.translation;
transform.translation.x = global_pos.x;
transform.translation.y = global_pos.y;
commands.remove_one::<Parent>(entity);
commands.remove_one::<Dropped>(entity);
}
}
#[derive(Default)]
struct State {
er_cursor_moved: EventReader<CursorMoved>,
}
此代码适用于bevy 0.4。
关于rust - 用Bevy 0.4拖动 Sprite 可以接受的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65396065/
我对 Bevy 和 Rust 还很陌生。我想加载一个 png 图像并获取它的宽度和高度。下面的代码不会打印“found resource ...”。 fn setup( mut commands: C
我正在和 Bevy 一起制作一个小 boids 玩具,每个 boid 的速度/加速度取决于它周围 boid 的位置和速度值。这意味着对于每个 boid,我想运行一些依赖于其他 boid 的某个子集的逻
这是一个非常简单的问题。 我已经重写了我的代码以处理新版本 bevy 附带的语法和其他更改。 编译时似乎一切正常,除了实体的消失。 我在上述实体中生成,例如: commands.spawn_bundl
我正在尝试取消绘制我使用Commands.spawn()函数生成的一些实体,但它需要为Commands.Entity().despawn函数提供不同类型的参数。以下是我的代码:。此代码给出错误:Exp
我正在尝试取消绘制我使用Commands.spawn()函数生成的一些实体,但它需要为Commands.Entity().despawn函数提供不同类型的参数。以下是我的代码:。此代码给出错误:Exp
是否可以通过在 bevy rust 中包含实体来获取组件列表?例如用于调试目的。 use bevy::prelude::*; fn main() { App::build()
我想创建一个第一人称相机。 我已经研究了其他几个实现的源代码,比如 https://github.com/mcpar-land/bevy_fly_camera https://github.com/s
我想将我的对象旋转给定的量并将其向前平移以创建一个可操纵的坦克。 我找不到解决方法,所有的矩阵、向量和四元数让我很难找到解决方案。 这是我想要做的 Unity 等价物: transform.Rotat
Bevy ,一个新的 Rust 游戏引擎和 ECS,有一个特性,它根据参数的类型“范围”它的系统。来自 its docs : The parameters we pass in to a "syste
我目前正在尝试使用事件在我的 Bevy 游戏中角色跳跃时发出信号。我希望处理玩家输入的系统发送一个 JumpedEvent然后可以被其他系统接收以执行适当的操作(设置正确的玩家动画、速度、声音等),但
我试图查看按下鼠标的位置,以便我可以选择我的角色。 我已经尝试了以下 #[derive(Default)] struct State { // Set up from example mous
在 bevy 示例 breakout 中只使用矩形,有加载 Sprite 的示例,有加载 3d 网格的示例。在 2d 中,我想绘制一个三角形(或其他多边形),但我无法通过文档弄明白。 最佳答案 目前不
以下程序是大量 SpriteComponents 的一个非常简约的示例。在此示例中,使用 FPS 计数器,您可以看到 SpriteComponents 的成本似乎是多么高。 我确实注意到,如果我重用
我在 empty 借了一笔钱变量,我想延长它的生命周期。在注释的代码块中,我尝试解决它,但引用不再可用。我必须再次遍历循环才能找到匹配项才能对其采取行动。 如何遍历查询以寻找最佳匹配,然后在我知道它是
我试图根据玩家是在屏幕上向左还是向右移动来翻转 Sprite 。我目前修改 SpriteSheetComponents 变换的方法如下,似乎根本没有改变 Sprite : fn player_di
我想创建一个 portal-like effect使用 Bevy . Unity 似乎有一个 render texture实现这一目标。 有没有办法在 Bevy 中做同样的事情?如果没有, futur
我不太确定我是否完全理解实体组件系统方法,这可能是出现此问题的原因之一。仍在与 OOP 思维方式作斗争! 我正在尝试创建一个类似于网络的数据结构,例如,类似于电路的东西: 因此,例如,实体 4 连接到
使用 Res>我可以在屏幕空间坐标(左下角为零)中获得鼠标位置的变化,例如 #[derive(Default)] struct State { cursor_moved_reader: Eve
当我尝试在character.ars文件中定义此常量时,出现错误:。错误是:
在 Amethyst 或许多其他游戏引擎中,update 之间存在区别。对于逻辑和fixed_update用于渲染。 Bevy 0.4 引入了状态,但只有 enter , update和 exit生命
我是一名优秀的程序员,十分优秀!