add multi turtle support

This commit is contained in:
2025-10-17 08:59:29 +02:00
parent bbb9348497
commit 3509060390
19 changed files with 624 additions and 628 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ async fn main() {
println!("Building and executing turtle plan...");
// Execute the plan
let mut app = TurtleApp::new().with_commands(0, turtle.build());
let mut app = TurtleApp::new().with_commands(turtle.build());
loop {
clear_background(Color::new(0.95, 0.95, 0.98, 1.0));
+2
View File
@@ -13,11 +13,13 @@ fn draw(turtle: &mut TurtlePlan) {
turtle.set_speed(999);
turtle.circle_left(100.0, 540.0, 72); // partial circle to the left
turtle.begin_fill();
turtle.forward(150.0);
turtle.set_speed(100);
turtle.set_pen_color(BLUE);
turtle.circle_right(50.0, 270.0, 72); // partial circle to the right
// Set animation speed
turtle.end_fill();
turtle.set_speed(20);
turtle.forward(150.0);
turtle.circle_left(50.0, 180.0, 12);
+1 -1
View File
@@ -40,7 +40,7 @@ use turtle_lib::*;
#[turtle_main("Dragon Curve")]
fn draw_dragon(turtle: &mut TurtlePlan) {
// Fast drawing
turtle.set_speed(1200);
turtle.set_speed(1020);
// Start position
turtle.pen_up();
+1 -1
View File
@@ -111,7 +111,7 @@ async fn main() {
// Set animation speed
t.set_speed(500);
let mut app = TurtleApp::new().with_commands(0, t.build());
let mut app = TurtleApp::new().with_commands(t.build());
let target_fps = 1.0; // 1 frame per second for debugging
let frame_time = 1.0 / target_fps;
+1 -1
View File
@@ -4,7 +4,7 @@
use turtle_lib::*;
#[turtle_main("Hello Turtle")]
#[turtle_main]
fn hello() {
turtle.set_pen_color(BLUE);
for _ in 0..4 {
+2 -2
View File
@@ -31,7 +31,7 @@ async fn main() {
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
// Default to showing info-level logs if RUST_LOG is not set
tracing_subscriber::EnvFilter::new("turtle_lib=info")
tracing_subscriber::EnvFilter::new("turtle_lib=trace")
}),
)
.with_target(true) // Show which module the log came from
@@ -75,7 +75,7 @@ async fn main() {
t.set_speed(100); // Slow animation to see the logs in real-time
// Create turtle app
let mut app = TurtleApp::new().with_commands(0, t.build());
let mut app = TurtleApp::new().with_commands(t.build());
// Main loop
loop {
-17
View File
@@ -1,17 +0,0 @@
//! Demo of the turtle_main macro with inline code
//!
//! This example shows that you can write your turtle code directly
//! in the function body without taking a turtle parameter.
use turtle_lib::*;
#[turtle_main("Macro Demo - Inline Spiral")]
fn draw_spiral() {
turtle.set_pen_color(RED);
turtle.set_pen_width(2.0);
for i in 0..36 {
turtle.forward(i as f32 * 3.0);
turtle.right(25.0);
}
}
+125
View File
@@ -0,0 +1,125 @@
//! Multi-turtle example demonstrating multiple independent turtles drawing simultaneously
//!
//! This example shows how to:
//! - Create multiple turtle instances using `add_turtle()`
//! - Control each turtle independently with separate command queues
//! - Position turtles at different locations using `go_to()`
//! - Use different colors and pen widths for each turtle
//! - Combine all turtle animations in a single rendering loop
use macroquad::{miniquad::window::set_window_size, prelude::*};
use turtle_lib::*;
#[macroquad::main("Multi-Turtle Example")]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
// Default to showing info-level logs if RUST_LOG is not set
tracing_subscriber::EnvFilter::new("turtle_lib=error")
}),
)
.with_target(true) // Show which module the log came from
.with_thread_ids(false)
.with_line_number(true) // Show line numbers
.with_file(false)
.without_time()
.init();
let mut app = TurtleApp::new();
set_window_size(1900, 1000);
// Turtle 0 (default turtle) - Draw a spiral (red)
let mut turtle0 = create_turtle();
turtle0.right(45.0);
turtle0.set_speed(1900.0);
turtle0.set_pen_color(RED);
turtle0.set_fill_color(RED);
turtle0.set_pen_width(2.0);
turtle0.begin_fill();
for i in 0..36 {
turtle0.forward(5.0 + i as f32 * 2.0).right(10.0);
}
turtle0.pen_up();
turtle0.go_to(vec2(-200.0, -200.0));
turtle0.pen_down();
turtle0.circle_left(30.0, 360.0, 36);
turtle0.end_fill();
// Turtle 1 - Draw a square (blue)
let turtle1_id = app.add_turtle();
let mut turtle1 = create_turtle();
turtle1.set_speed(1900.0);
turtle1.pen_up();
turtle1.go_to(vec2(-200.0, 0.0));
turtle1.pen_down();
turtle1.set_pen_color(BLUE);
turtle1.set_fill_color(BLUE);
turtle1.set_pen_width(3.0);
turtle1.begin_fill();
for _ in 0..4 {
turtle1.forward(100.0).right(90.0);
}
turtle1.end_fill();
// Turtle 2 - Draw a hexagon (green)
let turtle2_id = app.add_turtle();
let mut turtle2 = create_turtle();
turtle2.set_speed(150.0);
turtle2.pen_up();
turtle2.go_to(vec2(200.0, 0.0));
turtle2.pen_down();
turtle2.set_pen_color(GREEN);
turtle2.set_pen_width(3.0);
for _ in 0..6 {
turtle2.forward(80.0).right(60.0);
}
// Turtle 3 - Draw a star (yellow)
let turtle3_id = app.add_turtle();
let mut turtle3 = create_turtle();
turtle3.set_fill_color(ORANGE);
turtle3.begin_fill();
turtle3.set_speed(150.0);
turtle3.pen_up();
turtle3.go_to(vec2(0.0, 150.0));
turtle3.pen_down();
turtle3.set_pen_color(YELLOW);
turtle3.set_pen_width(3.0);
for _ in 0..5 {
turtle3.forward(120.0).right(144.0);
}
turtle3.end_fill();
// Turtle 4 - Draw a filled circle (purple)
let turtle4_id = app.add_turtle();
let mut turtle4 = create_turtle();
turtle4.set_speed(150.0);
turtle4.pen_up();
turtle4.go_to(vec2(0.0, -150.0));
turtle4.pen_down();
turtle4.set_pen_color(PURPLE);
turtle4.set_fill_color(Color::new(0.5, 0.0, 0.5, 0.5));
turtle4.begin_fill();
turtle4.circle_left(60.0, 360.0, 36);
turtle4.end_fill();
// Add all commands to the app
app = app.with_commands(turtle0.build());
app = app.with_commands_for_turtle(turtle1_id, turtle1.build());
app = app.with_commands_for_turtle(turtle2_id, turtle2.build());
app = app.with_commands_for_turtle(turtle3_id, turtle3.build());
app = app.with_commands_for_turtle(turtle4_id, turtle4.build());
// Main loop
loop {
clear_background(WHITE);
app.update();
app.render();
if is_key_pressed(KeyCode::Escape) || is_key_pressed(KeyCode::Q) {
break;
}
next_frame().await;
}
}
+1 -1
View File
@@ -49,7 +49,7 @@ fn draw(turtle: &mut TurtlePlan) {
turtle.pen_up();
turtle.backward(80.0);
turtle.left(90.0);
turtle.forward(50.0);
turtle.backward(50.0);
turtle.right(90.0);
turtle.pen_down();
-126
View File
@@ -1,126 +0,0 @@
//! Celebrates the 1.0.0 release of the original sunjay/turtle library.
//!
//! This example draws "1.0.0" with decorative background lines and filled shapes.
//! Ported from the original sunjay/turtle example.
use turtle_lib::*;
#[turtle_main("Version 1.0.0")]
fn draw_version(turtle: &mut TurtlePlan) {
turtle.set_pen_width(10.0);
turtle.set_speed(999); // instant
turtle.pen_up();
turtle.go_to(vec2(350.0, 178.0));
turtle.pen_down();
bg_lines(turtle);
turtle.pen_up();
turtle.go_to(vec2(-270.0, -200.0));
turtle.set_heading(90.0);
turtle.pen_down();
turtle.set_speed(100); // normal
turtle.set_pen_color(BLUE);
// Cyan with alpha - using RGB values for Color::from("#00E5FF")
turtle.set_fill_color([0.0, 0.898, 1.0, 0.75]);
one(turtle);
turtle.set_speed(200); // faster
turtle.pen_up();
turtle.left(90.0);
turtle.backward(50.0);
turtle.pen_down();
small_circle(turtle);
turtle.pen_up();
turtle.backward(150.0);
turtle.pen_down();
zero(turtle);
turtle.pen_up();
turtle.backward(150.0);
turtle.pen_down();
small_circle(turtle);
turtle.pen_up();
turtle.backward(150.0);
turtle.pen_down();
zero(turtle);
}
fn bg_lines(turtle: &mut TurtlePlan) {
// Light green color for background lines (#76FF03)
turtle.set_pen_color([0.463, 1.0, 0.012, 1.0].into());
turtle.set_heading(165.0);
turtle.forward(280.0);
turtle.left(147.0);
turtle.forward(347.0);
turtle.right(158.0);
turtle.forward(547.0);
turtle.left(138.0);
turtle.forward(539.0);
turtle.right(168.0);
turtle.forward(477.0);
turtle.left(154.0);
turtle.forward(377.0);
turtle.right(158.0);
turtle.forward(329.0);
}
fn small_circle(turtle: &mut TurtlePlan) {
turtle.begin_fill();
for _ in 0..90 {
turtle.forward(1.0);
turtle.right(4.0);
}
turtle.end_fill();
}
fn one(turtle: &mut TurtlePlan) {
turtle.begin_fill();
for _ in 0..2 {
turtle.forward(420.0);
turtle.left(90.0);
turtle.forward(50.0);
turtle.left(90.0);
}
turtle.end_fill();
}
fn zero(turtle: &mut TurtlePlan) {
turtle.begin_fill();
for _ in 0..2 {
arc_right(turtle);
arc_forward(turtle);
}
turtle.end_fill();
}
fn arc_right(turtle: &mut TurtlePlan) {
// Draw an arc that moves right faster than it moves forward
for i in 0..90 {
turtle.forward(3.0);
turtle.right((90.0 - i as f32) / 45.0);
}
}
fn arc_forward(turtle: &mut TurtlePlan) {
// Draw an arc that moves forward faster than it moves right
for i in 0..90 {
turtle.forward(3.0);
turtle.right(i as f32 / 45.0);
}
}
-3
View File
@@ -24,7 +24,4 @@ fn draw(turtle: &mut TurtlePlan) {
turtle.pen_down();
turtle.circle_right(8.0, 360.0, 12);
turtle.end_fill();
// Set animation speed
turtle.set_speed(1000);
}