Initial experimental WIP
This commit is contained in:
		
						commit
						ca690c2864
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
/target
 | 
			
		||||
							
								
								
									
										3690
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										3690
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "turtlers"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
default-run = "turtlers"
 | 
			
		||||
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
bevy = { version = "0.8", features = ["dynamic"] }
 | 
			
		||||
bevy-inspector-egui = "0.12.1"
 | 
			
		||||
bevy_prototype_lyon = "0.6"
 | 
			
		||||
bevy_tweening = "0.5.0"
 | 
			
		||||
 | 
			
		||||
# Enable a small amount of optimization in debug mode
 | 
			
		||||
[profile.dev]
 | 
			
		||||
opt-level = 1
 | 
			
		||||
 | 
			
		||||
# Enable high optimizations for dependencies (incl. Bevy), but not for our code:
 | 
			
		||||
[profile.dev.package."*"]
 | 
			
		||||
opt-level = 3
 | 
			
		||||
							
								
								
									
										143
									
								
								src/bin/animation.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/bin/animation.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
//! Create and play an animation defined by code that operates on the `Transform` component.
 | 
			
		||||
 | 
			
		||||
use std::f32::consts::{FRAC_PI_2, PI};
 | 
			
		||||
 | 
			
		||||
use bevy::prelude::*;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::new()
 | 
			
		||||
        .add_plugins(DefaultPlugins)
 | 
			
		||||
        .insert_resource(AmbientLight {
 | 
			
		||||
            color: Color::WHITE,
 | 
			
		||||
            brightness: 1.0,
 | 
			
		||||
        })
 | 
			
		||||
        .add_startup_system(setup)
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn setup(
 | 
			
		||||
    mut commands: Commands,
 | 
			
		||||
    mut meshes: ResMut<Assets<Mesh>>,
 | 
			
		||||
    mut materials: ResMut<Assets<StandardMaterial>>,
 | 
			
		||||
    mut animations: ResMut<Assets<AnimationClip>>,
 | 
			
		||||
) {
 | 
			
		||||
    // Camera
 | 
			
		||||
    commands.spawn_bundle(Camera3dBundle {
 | 
			
		||||
        transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
 | 
			
		||||
        ..default()
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // The animation API uses the `Name` component to target entities
 | 
			
		||||
    let planet = Name::new("planet");
 | 
			
		||||
    let orbit_controller = Name::new("orbit_controller");
 | 
			
		||||
    let satellite = Name::new("satellite");
 | 
			
		||||
 | 
			
		||||
    // Creating the animation
 | 
			
		||||
    let mut animation = AnimationClip::default();
 | 
			
		||||
    // A curve can modify a single part of a transform, here the translation
 | 
			
		||||
    animation.add_curve_to_path(
 | 
			
		||||
        EntityPath {
 | 
			
		||||
            parts: vec![planet.clone()],
 | 
			
		||||
        },
 | 
			
		||||
        VariableCurve {
 | 
			
		||||
            keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
 | 
			
		||||
            keyframes: Keyframes::Translation(vec![
 | 
			
		||||
                Vec3::new(1.0, 0.0, 1.0),
 | 
			
		||||
                Vec3::new(-1.0, 0.0, 1.0),
 | 
			
		||||
                Vec3::new(-1.0, 0.0, -1.0),
 | 
			
		||||
                Vec3::new(1.0, 0.0, -1.0),
 | 
			
		||||
                // in case seamless looping is wanted, the last keyframe should
 | 
			
		||||
                // be the same as the first one
 | 
			
		||||
                Vec3::new(1.0, 0.0, 1.0),
 | 
			
		||||
            ]),
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
    // Or it can modify the rotation of the transform.
 | 
			
		||||
    // To find the entity to modify, the hierarchy  will be traversed looking for
 | 
			
		||||
    // an entity with the right name at each level
 | 
			
		||||
    animation.add_curve_to_path(
 | 
			
		||||
        EntityPath {
 | 
			
		||||
            parts: vec![planet.clone(), orbit_controller.clone()],
 | 
			
		||||
        },
 | 
			
		||||
        VariableCurve {
 | 
			
		||||
            keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
 | 
			
		||||
            keyframes: Keyframes::Rotation(vec![
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 0.0),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, FRAC_PI_2),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, PI),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 3.0 * FRAC_PI_2),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 0.0),
 | 
			
		||||
            ]),
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
    // If a curve in an animation is shorter than the other, it will not repeat
 | 
			
		||||
    // until all other curves are finished. In that case, another animation should
 | 
			
		||||
    // be created for each part that would have a different duration / period
 | 
			
		||||
    animation.add_curve_to_path(
 | 
			
		||||
        EntityPath {
 | 
			
		||||
            parts: vec![planet.clone(), orbit_controller.clone(), satellite.clone()],
 | 
			
		||||
        },
 | 
			
		||||
        VariableCurve {
 | 
			
		||||
            keyframe_timestamps: vec![0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0],
 | 
			
		||||
            keyframes: Keyframes::Scale(vec![
 | 
			
		||||
                Vec3::splat(0.8),
 | 
			
		||||
                Vec3::splat(1.2),
 | 
			
		||||
                Vec3::splat(0.8),
 | 
			
		||||
                Vec3::splat(1.2),
 | 
			
		||||
                Vec3::splat(0.8),
 | 
			
		||||
                Vec3::splat(1.2),
 | 
			
		||||
                Vec3::splat(0.8),
 | 
			
		||||
                Vec3::splat(1.2),
 | 
			
		||||
                Vec3::splat(0.8),
 | 
			
		||||
            ]),
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
    // There can be more than one curve targeting the same entity path
 | 
			
		||||
    animation.add_curve_to_path(
 | 
			
		||||
        EntityPath {
 | 
			
		||||
            parts: vec![planet.clone(), orbit_controller.clone(), satellite.clone()],
 | 
			
		||||
        },
 | 
			
		||||
        VariableCurve {
 | 
			
		||||
            keyframe_timestamps: vec![0.0, 1.0, 2.0, 3.0, 4.0],
 | 
			
		||||
            keyframes: Keyframes::Rotation(vec![
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 0.0),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, FRAC_PI_2),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, PI),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 3.0 * FRAC_PI_2),
 | 
			
		||||
                Quat::from_axis_angle(Vec3::Y, 0.0),
 | 
			
		||||
            ]),
 | 
			
		||||
        },
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Create the animation player, and set it to repeat
 | 
			
		||||
    let mut player = AnimationPlayer::default();
 | 
			
		||||
    player.play(animations.add(animation)).repeat();
 | 
			
		||||
 | 
			
		||||
    // Create the scene that will be animated
 | 
			
		||||
    // First entity is the planet
 | 
			
		||||
    commands
 | 
			
		||||
        .spawn_bundle(PbrBundle {
 | 
			
		||||
            mesh: meshes.add(Mesh::from(shape::Icosphere::default())),
 | 
			
		||||
            material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()),
 | 
			
		||||
            ..default()
 | 
			
		||||
        })
 | 
			
		||||
        // Add the Name component, and the animation player
 | 
			
		||||
        .insert_bundle((planet, player))
 | 
			
		||||
        .with_children(|p| {
 | 
			
		||||
            // This entity is just used for animation, but doesn't display anything
 | 
			
		||||
            p.spawn_bundle(SpatialBundle::default())
 | 
			
		||||
                // Add the Name component
 | 
			
		||||
                .insert(orbit_controller)
 | 
			
		||||
                .with_children(|p| {
 | 
			
		||||
                    // The satellite, placed at a distance of the planet
 | 
			
		||||
                    p.spawn_bundle(PbrBundle {
 | 
			
		||||
                        transform: Transform::from_xyz(1.5, 0.0, 0.0),
 | 
			
		||||
                        mesh: meshes.add(Mesh::from(shape::Cube { size: 0.5 })),
 | 
			
		||||
                        material: materials.add(Color::rgb(0.3, 0.9, 0.3).into()),
 | 
			
		||||
                        ..default()
 | 
			
		||||
                    })
 | 
			
		||||
                    // Add the Name component
 | 
			
		||||
                    .insert(satellite);
 | 
			
		||||
                });
 | 
			
		||||
        });
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/debug.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/debug.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
use bevy::prelude::Plugin;
 | 
			
		||||
use bevy_inspector_egui::WorldInspectorPlugin;
 | 
			
		||||
 | 
			
		||||
pub struct DebugPlugin;
 | 
			
		||||
 | 
			
		||||
impl Plugin for DebugPlugin {
 | 
			
		||||
    fn build(&self, app: &mut bevy::prelude::App) {
 | 
			
		||||
        if cfg!(debug_assertions) {
 | 
			
		||||
            app.add_plugin(WorldInspectorPlugin::new());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
mod debug;
 | 
			
		||||
mod turtle;
 | 
			
		||||
mod turtle_shapes;
 | 
			
		||||
use bevy::{prelude::*, window::close_on_esc};
 | 
			
		||||
 | 
			
		||||
use bevy_prototype_lyon::prelude::*;
 | 
			
		||||
use turtle::TurtlePlugin;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    App::new()
 | 
			
		||||
        .insert_resource(Msaa { samples: 4 })
 | 
			
		||||
        .insert_resource(ClearColor(Color::BEIGE))
 | 
			
		||||
        .insert_resource(WindowDescriptor {
 | 
			
		||||
            width: 400.0,
 | 
			
		||||
            height: 400.0,
 | 
			
		||||
            title: "Turtle Window".to_string(),
 | 
			
		||||
            present_mode: bevy::window::PresentMode::AutoVsync,
 | 
			
		||||
            ..default()
 | 
			
		||||
        })
 | 
			
		||||
        .add_plugins(DefaultPlugins)
 | 
			
		||||
        .add_plugin(ShapePlugin)
 | 
			
		||||
        .add_plugin(debug::DebugPlugin)
 | 
			
		||||
        .add_plugin(TurtlePlugin)
 | 
			
		||||
        .add_system(close_on_esc)
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										222
									
								
								src/turtle.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/turtle.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,222 @@
 | 
			
		||||
use std::{f32::consts::PI, time::Duration};
 | 
			
		||||
 | 
			
		||||
use bevy::prelude::*;
 | 
			
		||||
use bevy_prototype_lyon::{entity::ShapeBundle, prelude::*};
 | 
			
		||||
use bevy_tweening::{
 | 
			
		||||
    lens::{TransformPositionLens, TransformRotateXLens, TransformRotateZLens, TransformScaleLens},
 | 
			
		||||
    Animator, EaseFunction, Lens, Sequence, Tween, Tweenable, TweeningPlugin, TweeningType,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::turtle_shapes;
 | 
			
		||||
 | 
			
		||||
pub struct TurtlePlugin;
 | 
			
		||||
 | 
			
		||||
impl Plugin for TurtlePlugin {
 | 
			
		||||
    fn build(&self, app: &mut bevy::prelude::App) {
 | 
			
		||||
        app.add_plugin(TweeningPlugin)
 | 
			
		||||
            .add_startup_system(setup)
 | 
			
		||||
            .add_system(keypresses);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#[derive(Bundle)]
 | 
			
		||||
pub struct Turtle {
 | 
			
		||||
    colors: Colors,
 | 
			
		||||
    commands: TurtleCommands,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Turtle {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            colors: Colors {
 | 
			
		||||
                color: Color::DARK_GRAY,
 | 
			
		||||
                fill_color: Color::BLACK,
 | 
			
		||||
            },
 | 
			
		||||
            commands: TurtleCommands(vec![
 | 
			
		||||
                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(),
 | 
			
		||||
                )), */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Turtle {
 | 
			
		||||
    pub fn set_color(&mut self, color: Color) {
 | 
			
		||||
        self.colors.color = color;
 | 
			
		||||
    }
 | 
			
		||||
    pub fn set_fill_color(&mut self, color: Color) {
 | 
			
		||||
        self.colors.fill_color = color;
 | 
			
		||||
    }
 | 
			
		||||
    pub fn get_colors(&self) -> &Colors {
 | 
			
		||||
        &self.colors
 | 
			
		||||
    }
 | 
			
		||||
    pub fn forward(&mut self) -> &mut Self {
 | 
			
		||||
        self.commands.0.push(TurtleCommand::Forward(Length(100.0)));
 | 
			
		||||
        self
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Component)]
 | 
			
		||||
pub struct TurtleCommands(Vec<TurtleCommand>);
 | 
			
		||||
 | 
			
		||||
impl TurtleCommands {
 | 
			
		||||
    fn generate_tweenable(&self) -> Sequence<Transform> {
 | 
			
		||||
        let mut seq = Sequence::with_capacity(self.0.len());
 | 
			
		||||
        for op in &self.0 {
 | 
			
		||||
            match op {
 | 
			
		||||
                TurtleCommand::Forward(Length(x)) => {
 | 
			
		||||
                    println!("Adding Forward");
 | 
			
		||||
                    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.
 | 
			
		||||
                        TransformPositionLens {
 | 
			
		||||
                            start: Vec3::ZERO,
 | 
			
		||||
                            end: Vec3::new(*x as f32, 40., 0.),
 | 
			
		||||
                        },
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
                TurtleCommand::Backward(_) => todo!(),
 | 
			
		||||
                TurtleCommand::Left(Angle(x)) => {
 | 
			
		||||
                    println!("Adding Left");
 | 
			
		||||
                    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: *x as f32 * (PI / 180.),
 | 
			
		||||
                            end: -*x as f32 * (PI / 180.),
 | 
			
		||||
                        },
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
                TurtleCommand::Right(_) => todo!(),
 | 
			
		||||
                TurtleCommand::PenUp => todo!(),
 | 
			
		||||
                TurtleCommand::PenDown => todo!(),
 | 
			
		||||
                TurtleCommand::Circle => todo!(),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        seq
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Component)]
 | 
			
		||||
pub struct TurtleShape;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Component)]
 | 
			
		||||
pub struct Colors {
 | 
			
		||||
    color: Color,
 | 
			
		||||
    fill_color: Color,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Length(f64);
 | 
			
		||||
pub struct Angle(f64);
 | 
			
		||||
 | 
			
		||||
#[derive(Component)]
 | 
			
		||||
enum TurtleCommand {
 | 
			
		||||
    Forward(Length),
 | 
			
		||||
    Backward(Length),
 | 
			
		||||
    Left(Angle),
 | 
			
		||||
    Right(Angle),
 | 
			
		||||
    PenUp,
 | 
			
		||||
    PenDown,
 | 
			
		||||
    Circle,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct TurtleMoveLens {
 | 
			
		||||
    start: Vec3,
 | 
			
		||||
    end: Vec3,
 | 
			
		||||
}
 | 
			
		||||
fn setup(mut commands: Commands) {
 | 
			
		||||
    let animator = 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::ZERO,
 | 
			
		||||
            end: Vec3::new(40., 40., 0.),
 | 
			
		||||
        },
 | 
			
		||||
    ));
 | 
			
		||||
    commands.spawn_bundle(Camera2dBundle::default());
 | 
			
		||||
    commands
 | 
			
		||||
        .spawn_bundle(Turtle::default())
 | 
			
		||||
        .insert_bundle(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(),
 | 
			
		||||
        ))
 | 
			
		||||
        .insert(animator);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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>,
 | 
			
		||||
) {
 | 
			
		||||
    if keys.just_pressed(KeyCode::W) {
 | 
			
		||||
        let tcmd = tcmd.single();
 | 
			
		||||
        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.),
 | 
			
		||||
            },
 | 
			
		||||
        ))); */
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/turtle_shapes.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/turtle_shapes.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
use bevy::prelude::Vec2;
 | 
			
		||||
use bevy_prototype_lyon::prelude::{Path, PathBuilder};
 | 
			
		||||
 | 
			
		||||
pub fn turtle() -> Path {
 | 
			
		||||
    let polygon = &[
 | 
			
		||||
        [-2.5f32, 14.0f32],
 | 
			
		||||
        [-1.25f32, 10.0f32],
 | 
			
		||||
        [-4.0f32, 7.0f32],
 | 
			
		||||
        [-7.0f32, 9.0f32],
 | 
			
		||||
        [-9.0f32, 8.0f32],
 | 
			
		||||
        [-6.0f32, 5.0f32],
 | 
			
		||||
        [-7.0f32, 1.0f32],
 | 
			
		||||
        [-5.0f32, -3.0f32],
 | 
			
		||||
        [-8.0f32, -6.0f32],
 | 
			
		||||
        [-6.0f32, -8.0f32],
 | 
			
		||||
        [-4.0f32, -5.0f32],
 | 
			
		||||
        [0.0f32, -7.0f32],
 | 
			
		||||
        [4.0f32, -5.0f32],
 | 
			
		||||
        [6.0f32, -8.0f32],
 | 
			
		||||
        [8.0f32, -6.0f32],
 | 
			
		||||
        [5.0f32, -3.0f32],
 | 
			
		||||
        [7.0f32, 1.0f32],
 | 
			
		||||
        [6.0f32, 5.0f32],
 | 
			
		||||
        [9.0f32, 8.0f32],
 | 
			
		||||
        [7.0f32, 9.0f32],
 | 
			
		||||
        [4.0f32, 7.0f32],
 | 
			
		||||
        [1.25f32, 10.0f32],
 | 
			
		||||
        [2.5f32, 14.0f32],
 | 
			
		||||
    ];
 | 
			
		||||
    let mut turtle_path = PathBuilder::new();
 | 
			
		||||
    turtle_path.line_to(Vec2::new(1.0, 1.0));
 | 
			
		||||
    turtle_path.line_to(Vec2::new(-1.0, 1.0));
 | 
			
		||||
    turtle_path.line_to(Vec2::new(-1.0, -1.0));
 | 
			
		||||
    turtle_path.line_to(Vec2::new(1.0, -1.0));
 | 
			
		||||
    turtle_path.close();
 | 
			
		||||
    turtle_path.move_to(Vec2::new(0.0, 16.0));
 | 
			
		||||
    for coord in polygon {
 | 
			
		||||
        turtle_path.line_to(Vec2::from_array(*coord));
 | 
			
		||||
    }
 | 
			
		||||
    turtle_path.close();
 | 
			
		||||
    turtle_path.build()
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user