forward backward left right working
This commit is contained in:
parent
2836b2926d
commit
92458b55e5
@ -1,5 +1,6 @@
|
||||
mod debug;
|
||||
mod turtle;
|
||||
mod turtle_movement;
|
||||
mod turtle_shapes;
|
||||
use bevy::{prelude::*, window::close_on_esc};
|
||||
|
||||
|
193
src/turtle.rs
193
src/turtle.rs
@ -1,14 +1,14 @@
|
||||
use std::{f32::consts::PI, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_inspector_egui::{Inspectable, RegisterInspectable};
|
||||
use bevy_prototype_lyon::prelude::*;
|
||||
use bevy_prototype_lyon::{prelude::*, shapes::Line};
|
||||
use bevy_tweening::{
|
||||
lens::{TransformPositionLens, TransformRotateZLens},
|
||||
Animator, EaseFunction, Sequence, Tween, TweeningPlugin, TweeningType,
|
||||
lens::TransformPositionLens, Animator, EaseFunction, Sequence, Tween, TweenCompleted,
|
||||
TweeningPlugin, TweeningType,
|
||||
};
|
||||
|
||||
use crate::turtle_shapes;
|
||||
use crate::{turtle_movement::turtle_move, turtle_shapes};
|
||||
|
||||
pub struct TurtlePlugin;
|
||||
|
||||
@ -17,6 +17,7 @@ impl Plugin for TurtlePlugin {
|
||||
app.add_plugin(TweeningPlugin)
|
||||
.add_startup_system(setup)
|
||||
.add_system(keypresses)
|
||||
.add_system(draw_lines)
|
||||
.register_inspectable::<Colors>()
|
||||
.register_inspectable::<TurtleCommands>();
|
||||
}
|
||||
@ -34,24 +35,29 @@ impl Default for Turtle {
|
||||
color: Color::DARK_GRAY,
|
||||
fill_color: Color::BLACK,
|
||||
},
|
||||
commands: TurtleCommands(vec![
|
||||
commands: TurtleCommands::new(vec![
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(90.)),
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Backward(Length(100.)),
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(90.)),
|
||||
TurtleCommand::Right(Angle(45.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(90.)),
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Forward(Length(50.)),
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(90.)),
|
||||
]), /*
|
||||
shape: TurtleShape(GeometryBuilder::build_as(
|
||||
&turtle_shapes::turtle(),
|
||||
DrawMode::Outlined {
|
||||
fill_mode: FillMode::color(Color::MIDNIGHT_BLUE),
|
||||
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
|
||||
},
|
||||
Default::default(),
|
||||
)), */
|
||||
TurtleCommand::Right(Angle(90.)),
|
||||
TurtleCommand::Forward(Length(50.)),
|
||||
TurtleCommand::Right(Angle(45.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(120.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Left(Angle(120.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
TurtleCommand::Right(Angle(150.)),
|
||||
TurtleCommand::Forward(Length(100.)),
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,61 +73,60 @@ impl Turtle {
|
||||
&self.colors
|
||||
}
|
||||
pub fn forward(&mut self) -> &mut Self {
|
||||
self.commands.0.push(TurtleCommand::Forward(Length(100.0)));
|
||||
self.commands
|
||||
.commands
|
||||
.push(TurtleCommand::Forward(Length(100.0)));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Component, Inspectable)]
|
||||
pub struct TurtleCommands(Vec<TurtleCommand>);
|
||||
pub struct TurtleCommands {
|
||||
commands: Vec<TurtleCommand>,
|
||||
lines: Vec<TurtleGraphElement>,
|
||||
}
|
||||
|
||||
impl TurtleCommands {
|
||||
fn generate_tweenable(&self) -> Sequence<Transform> {
|
||||
let mut seq = Sequence::with_capacity(self.0.len());
|
||||
fn new(commands: Vec<TurtleCommand>) -> Self {
|
||||
Self {
|
||||
commands,
|
||||
lines: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TurtleCommands {
|
||||
fn generate_tweenable(&mut self) -> Sequence<Transform> {
|
||||
self.lines.clear();
|
||||
let mut seq = Sequence::with_capacity(self.commands.len());
|
||||
let mut pos = Vec2::ZERO;
|
||||
let mut ori: f32 = 0.;
|
||||
for op in &self.0 {
|
||||
for (index, op) in self.commands.iter().enumerate() {
|
||||
match op {
|
||||
TurtleCommand::Forward(Length(x)) => {
|
||||
println!("Adding Forward");
|
||||
let start = pos;
|
||||
let end = pos + (Vec2::from_angle(ori) * *x as f32);
|
||||
seq = seq.then(Tween::new(
|
||||
// accelerate and decelerate
|
||||
EaseFunction::QuadraticInOut,
|
||||
// Loop animation back and forth.
|
||||
TweeningType::Once,
|
||||
// later to be controlled by speed
|
||||
Duration::from_secs(1),
|
||||
// set the start and end of the animation
|
||||
TransformPositionLens {
|
||||
start: start.extend(0.),
|
||||
end: end.extend(0.),
|
||||
},
|
||||
));
|
||||
pos = end;
|
||||
let (target, animation, line) = turtle_move(pos, ori, *x as f32, index as f32);
|
||||
self.lines.push(line);
|
||||
seq = seq.then(animation);
|
||||
pos = target;
|
||||
}
|
||||
TurtleCommand::Backward(Length(x)) => {
|
||||
let (target, animation, line) = turtle_move(pos, ori, -*x as f32, index as f32);
|
||||
self.lines.push(line);
|
||||
seq = seq.then(animation);
|
||||
pos = target;
|
||||
}
|
||||
TurtleCommand::Backward(_) => todo!(),
|
||||
TurtleCommand::Left(Angle(x)) => {
|
||||
println!("Adding Left");
|
||||
let start = ori;
|
||||
let end = ori + (*x as f32 * PI / 180.);
|
||||
seq = seq.then(Tween::new(
|
||||
// Use a quadratic easing on both endpoints.
|
||||
EaseFunction::QuadraticInOut,
|
||||
// Loop animation back and forth.
|
||||
TweeningType::Once,
|
||||
// Animation time (one way only; for ping-pong it takes 2 seconds
|
||||
// to come back to start).
|
||||
Duration::from_secs(1),
|
||||
// The lens gives access to the Transform component of the Entity,
|
||||
// for the Animator to animate it. It also contains the start and
|
||||
// end values respectively associated with the progress ratios 0. and 1.
|
||||
TransformRotateZLens { start, end },
|
||||
));
|
||||
ori = end % (2. * PI);
|
||||
let (nori, tween, line) = crate::turtle_movement::turtle_turn(ori, *x as f32);
|
||||
ori = nori;
|
||||
seq = seq.then(tween);
|
||||
self.lines.push(line);
|
||||
}
|
||||
TurtleCommand::Right(Angle(x)) => {
|
||||
let (nori, tween, line) = crate::turtle_movement::turtle_turn(ori, -*x as f32);
|
||||
ori = nori;
|
||||
seq = seq.then(tween);
|
||||
self.lines.push(line);
|
||||
}
|
||||
TurtleCommand::Right(_) => todo!(),
|
||||
TurtleCommand::PenUp => todo!(),
|
||||
TurtleCommand::PenDown => todo!(),
|
||||
TurtleCommand::Circle => todo!(),
|
||||
@ -132,6 +137,16 @@ impl TurtleCommands {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Inspectable, Default)]
|
||||
pub enum TurtleGraphElement {
|
||||
TurtleLine {
|
||||
start: Vec2,
|
||||
end: Vec2,
|
||||
},
|
||||
#[default]
|
||||
Noop,
|
||||
}
|
||||
|
||||
#[derive(Clone, Component, Inspectable)]
|
||||
pub struct TurtleShape;
|
||||
|
||||
@ -147,7 +162,7 @@ pub struct Length(f64);
|
||||
pub struct Angle(f64);
|
||||
|
||||
#[derive(Component, Inspectable, Default)]
|
||||
enum TurtleCommand {
|
||||
pub enum TurtleCommand {
|
||||
Forward(Length),
|
||||
Backward(Length),
|
||||
Left(Angle),
|
||||
@ -190,45 +205,43 @@ fn setup(mut commands: Commands) {
|
||||
.insert(animator);
|
||||
}
|
||||
|
||||
fn draw_lines(
|
||||
mut commands: Commands,
|
||||
tcmd: Query<&TurtleCommands>,
|
||||
mut query_event: EventReader<TweenCompleted>,
|
||||
) {
|
||||
for ev in query_event.iter() {
|
||||
let index = ev.user_data;
|
||||
let tcmd = tcmd.get_single().unwrap();
|
||||
let t = tcmd.lines.get(index as usize).unwrap();
|
||||
match t {
|
||||
TurtleGraphElement::TurtleLine { start, end } => {
|
||||
commands.spawn_bundle(GeometryBuilder::build_as(
|
||||
&Line(*start, *end),
|
||||
DrawMode::Outlined {
|
||||
fill_mode: FillMode::color(Color::MIDNIGHT_BLUE),
|
||||
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
|
||||
},
|
||||
Transform::identity(),
|
||||
));
|
||||
}
|
||||
TurtleGraphElement::Noop => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The sprite is animated by changing its translation depending on the time that has passed since
|
||||
/// the last frame.
|
||||
fn keypresses(
|
||||
//time: Res<Time>,
|
||||
keys: Res<Input<KeyCode>>,
|
||||
mut commands: Commands,
|
||||
mut qry: Query<&mut Animator<Transform>>,
|
||||
tcmd: Query<&TurtleCommands>,
|
||||
mut tcmd: Query<&mut TurtleCommands>,
|
||||
) {
|
||||
if keys.just_pressed(KeyCode::W) {
|
||||
let tcmd = tcmd.single();
|
||||
let mut tcmd = tcmd.single_mut();
|
||||
let c = tcmd.generate_tweenable();
|
||||
let mut shap = qry.single_mut();
|
||||
shap.set_tweenable(c);
|
||||
/* commands
|
||||
.spawn_bundle(Turtle::default())
|
||||
.insert_bundle(GeometryBuilder::build_as(
|
||||
&turtle_shapes::turtle(),
|
||||
DrawMode::Outlined {
|
||||
fill_mode: FillMode::color(Color::RED),
|
||||
outline_mode: StrokeMode::new(Color::BLACK, 1.0),
|
||||
},
|
||||
Transform::from_translation(Vec3::new(-100., 0., 0.)),
|
||||
))
|
||||
.insert(Animator::new(Tween::new(
|
||||
// Use a quadratic easing on both endpoints.
|
||||
EaseFunction::QuadraticInOut,
|
||||
// Loop animation back and forth.
|
||||
TweeningType::PingPong,
|
||||
// Animation time (one way only; for ping-pong it takes 2 seconds
|
||||
// to come back to start).
|
||||
Duration::from_secs(1),
|
||||
// The lens gives access to the Transform component of the Entity,
|
||||
// for the Animator to animate it. It also contains the start and
|
||||
// end values respectively associated with the progress ratios 0. and 1.
|
||||
TransformPositionLens {
|
||||
start: Vec3::new(-100., 0., 0.),
|
||||
end: Vec3::new(-140., 40., 0.),
|
||||
},
|
||||
))); */
|
||||
}
|
||||
}
|
||||
|
60
src/turtle_movement.rs
Normal file
60
src/turtle_movement.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use std::{f32::consts::PI, time::Duration};
|
||||
|
||||
use bevy::prelude::{Transform, Vec2};
|
||||
use bevy_tweening::{
|
||||
lens::{TransformPositionLens, TransformRotateZLens},
|
||||
EaseFunction, Tween, TweeningType,
|
||||
};
|
||||
|
||||
use crate::turtle::TurtleGraphElement;
|
||||
|
||||
pub fn turtle_turn(
|
||||
orientation: f32,
|
||||
angle_to_turn: f32,
|
||||
) -> (f32, Tween<Transform>, TurtleGraphElement) {
|
||||
let start = orientation;
|
||||
let end = orientation + (angle_to_turn * PI / 180.);
|
||||
let animation = Tween::new(
|
||||
// Use a quadratic easing on both endpoints.
|
||||
EaseFunction::QuadraticInOut,
|
||||
// Loop animation back and forth.
|
||||
TweeningType::Once,
|
||||
// Animation time (one way only; for ping-pong it takes 2 seconds
|
||||
// to come back to start).
|
||||
Duration::from_millis(500),
|
||||
// The lens gives access to the Transform component of the Entity,
|
||||
// for the Animator to animate it. It also contains the start and
|
||||
// end values respectively associated with the progress ratios 0. and 1.
|
||||
TransformRotateZLens { start, end },
|
||||
);
|
||||
let line = TurtleGraphElement::Noop;
|
||||
let orientation = end % (2. * PI);
|
||||
(orientation, animation, line)
|
||||
}
|
||||
|
||||
pub fn turtle_move(
|
||||
position: Vec2,
|
||||
orientation: f32,
|
||||
length: f32,
|
||||
index: f32,
|
||||
) -> (Vec2, Tween<Transform>, TurtleGraphElement) {
|
||||
let start = position;
|
||||
let end = position + (Vec2::from_angle(orientation) * length);
|
||||
let turtle_movement_animation = Tween::new(
|
||||
// accelerate and decelerate
|
||||
EaseFunction::QuadraticInOut,
|
||||
// Loop animation back and forth.
|
||||
TweeningType::Once,
|
||||
// later to be controlled by speed
|
||||
Duration::from_millis(500),
|
||||
// set the start and end of the animation
|
||||
TransformPositionLens {
|
||||
start: start.extend(0.),
|
||||
end: end.extend(0.),
|
||||
},
|
||||
)
|
||||
.with_completed_event(index as u64);
|
||||
let line = TurtleGraphElement::TurtleLine { start, end };
|
||||
|
||||
(end, turtle_movement_animation, line)
|
||||
}
|
Loading…
Reference in New Issue
Block a user