bevyjam/src/editor.rs

175 lines
3.8 KiB
Rust

use crate::{levels::stored::*, AppState};
use bevy::{
input::{keyboard::KeyCode, Input},
prelude::{
shape::{Circle, Quad},
*,
},
};
use bevy_mod_picking::*;
pub struct EditorPlugin;
impl Plugin for EditorPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(DefaultPickingPlugins)
.add_system_set(SystemSet::on_enter(AppState::Editor).with_system(setup))
.add_system_set(
SystemSet::on_update(AppState::Editor).with_system(keyboard_input_system),
);
}
}
#[derive(Component)]
struct Platform;
#[derive(Component)]
struct Draggable;
#[derive(Component)]
struct End;
#[derive(Bundle)]
struct PlatformBundle {
#[bundle]
mesh: ColorMesh2dBundle,
platform: Platform,
}
#[derive(Bundle)]
struct PlatformEndBundle {
#[bundle]
mesh: ColorMesh2dBundle,
#[bundle]
pickable: PickableBundle,
draggable: Draggable,
end: End,
}
fn spawn_platform(
commands: &mut Commands,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<ColorMaterial>>,
transform: Transform,
size: Vec2,
) {
commands
.spawn_bundle(PlatformBundle {
mesh: ColorMesh2dBundle {
mesh: meshes.add(Mesh::from(Quad { size, flip: false })).into(),
material: materials.add(ColorMaterial::from(Color::GRAY)),
transform,
..default()
},
platform: Platform,
})
.with_children(|c| {
c.spawn_bundle(PlatformEndBundle {
mesh: ColorMesh2dBundle {
mesh: meshes
.add(Mesh::from(Circle {
radius: 8.,
vertices: 12,
}))
.into(),
material: materials.add(ColorMaterial::from(Color::rgba(1., 1., 0., 0.7))),
transform: Transform::from_xyz(-size.x / 2., -size.y / 2., 0.5),
..default()
},
pickable: PickableBundle::default(),
draggable: Draggable,
end: End,
});
c.spawn_bundle(PlatformEndBundle {
mesh: ColorMesh2dBundle {
mesh: meshes
.add(Mesh::from(Circle {
radius: 8.,
vertices: 12,
}))
.into(),
material: materials.add(ColorMaterial::from(Color::rgba(1., 1., 0., 0.7))),
transform: Transform::from_xyz(size.x / 2., size.y / 2., 0.5),
..default()
},
pickable: PickableBundle::default(),
draggable: Draggable,
end: End,
});
});
}
pub fn spawn_stored_level(
commands: &mut Commands,
meshes: &mut ResMut<Assets<Mesh>>,
materials: &mut ResMut<Assets<ColorMaterial>>,
asset_server: &Res<AssetServer>,
stored_level: &StoredLevel,
) {
let _font = asset_server.get_handle::<Font, _>("UacariLegacy-Thin.ttf");
for platform in stored_level.platforms.iter() {
spawn_platform(
commands,
meshes,
materials,
Transform::from_xyz(platform.pos.x, platform.pos.y, 0.),
platform.size,
);
}
}
fn setup(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
camera_query: Query<Entity, With<Camera>>,
level_id: Res<crate::game::FirstLevel>,
stored_levels_assets: Res<Assets<StoredLevels>>,
stored_levels_handle: Res<Handle<StoredLevels>>,
asset_server: Res<AssetServer>,
) {
commands
.entity(camera_query.single())
.insert_bundle(PickingCameraBundle::default());
if let Some(stored_level) = stored_levels_assets
.get(&stored_levels_handle)
.unwrap()
.levels
.get(level_id.0 .0 as usize)
{
spawn_stored_level(
&mut commands,
&mut meshes,
&mut materials,
&asset_server,
stored_level,
);
}
}
fn keyboard_input_system(
keyboard_input: Res<Input<KeyCode>>,
mut drag_query: Query<(&mut Transform, &Selection), With<Draggable>>,
) {
let drag = 8.
* Vec3 {
x: (keyboard_input.pressed(KeyCode::Right) as i8
- keyboard_input.pressed(KeyCode::Left) as i8) as _,
y: (keyboard_input.pressed(KeyCode::Up) as i8
- keyboard_input.pressed(KeyCode::Down) as i8) as _,
z: 0.,
};
if drag != Vec3::ZERO {
for (mut transform, selection) in drag_query.iter_mut() {
if selection.selected() {
transform.translation += drag;
}
}
}
}