add a macro for simpler first examples.
This commit is contained in:
@@ -9,6 +9,7 @@ macroquad = "0.4"
|
||||
tween = "2.1.0"
|
||||
lyon = "1.0"
|
||||
tracing = { version = "0.1", features = ["log"], default-features = false }
|
||||
turtle-lib-macroquad-macros = { path = "../turtle-lib-macroquad-macros" }
|
||||
|
||||
[dev-dependencies]
|
||||
# For examples and testing
|
||||
|
||||
@@ -22,17 +22,74 @@ The main turtle graphics library built on Macroquad with Lyon tessellation.
|
||||
- Frame-rate independent animation
|
||||
- Live fill preview during circle/arc drawing
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using the `turtle_main` Macro (Recommended for Beginners)
|
||||
|
||||
The easiest way to create turtle programs is with the `turtle_main` macro:
|
||||
|
||||
```rust
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[turtle_main("My First Drawing")]
|
||||
fn my_drawing(turtle: &mut TurtlePlan) {
|
||||
turtle.set_pen_color(RED);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
turtle.forward(100.0);
|
||||
}
|
||||
```
|
||||
|
||||
The macro automatically handles:
|
||||
- Window creation and setup
|
||||
- Turtle initialization
|
||||
- Rendering loop
|
||||
- Quit handling (ESC or Q keys)
|
||||
|
||||
### Manual Setup (For Advanced Use)
|
||||
|
||||
For more control over the application loop:
|
||||
|
||||
```rust
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Turtle")]
|
||||
async fn main() {
|
||||
let mut turtle = create_turtle();
|
||||
turtle.forward(100.0).right(90.0);
|
||||
|
||||
let mut app = TurtleApp::new().with_commands(turtle.build());
|
||||
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
app.update();
|
||||
app.render();
|
||||
next_frame().await;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Quick Examples
|
||||
|
||||
All examples now use the `turtle_main` macro for simplicity:
|
||||
|
||||
```bash
|
||||
# Run from this directory
|
||||
cargo run --example square # Basic square drawing
|
||||
cargo run --example yinyang # Multi-contour fills with holes
|
||||
cargo run --example fill_advanced # Self-intersecting fills
|
||||
cargo run --example koch # Recursive fractals
|
||||
cargo run --example fill_demo # Multiple independent fills
|
||||
cargo run --example hello_turtle # Minimal 10-line example
|
||||
cargo run --example macro_demo # Simple square with macro
|
||||
cargo run --example square # Basic square drawing
|
||||
cargo run --example shapes # Different turtle shapes
|
||||
cargo run --example yinyang # Multi-contour fills with holes
|
||||
cargo run --example koch # Recursive fractals
|
||||
cargo run --example fill_demo # Fill with holes (donut)
|
||||
cargo run --example cheese_macro # Cheese example using macro
|
||||
cargo run --example fill_advanced # Complex shapes (manual setup)
|
||||
```
|
||||
|
||||
Most examples use `turtle_main` for simplicity. A few keep manual setup for custom UI or logging.
|
||||
|
||||
## Architecture Highlights
|
||||
|
||||
### Rendering Pipeline
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//! Cheese example using the turtle_main macro
|
||||
//!
|
||||
//! This is a simplified version of cheese.rs that demonstrates how the
|
||||
//! turtle_main macro reduces boilerplate code.
|
||||
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[turtle_main("Cheese with Holes - Using Macro")]
|
||||
fn draw_cheese(turtle: &mut TurtlePlan) {
|
||||
// Set fill color to yellow (cheese color!)
|
||||
turtle.set_pen_color(ORANGE);
|
||||
turtle.set_pen_width(3.0);
|
||||
turtle.set_fill_color(YELLOW);
|
||||
|
||||
println!("=== Starting cheese fill ===");
|
||||
turtle.begin_fill();
|
||||
|
||||
// Draw outer boundary (large square)
|
||||
println!("Drawing outer square boundary...");
|
||||
for _ in 0..4 {
|
||||
turtle.forward(400.0);
|
||||
turtle.right(90.0);
|
||||
}
|
||||
|
||||
// Close outer contour and start drawing holes
|
||||
println!("Closing outer contour with pen_up");
|
||||
turtle.pen_up();
|
||||
|
||||
// Draw triangular hole in the middle
|
||||
println!("Drawing triangular hole...");
|
||||
turtle.go_to(vec2(200.0, 120.0));
|
||||
turtle.pen_down(); // Start new contour for hole
|
||||
|
||||
for _ in 0..3 {
|
||||
turtle.forward(160.0);
|
||||
turtle.right(120.0);
|
||||
}
|
||||
|
||||
println!("Closing triangle contour with pen_up");
|
||||
turtle.pen_up(); // Close triangle hole contour
|
||||
|
||||
// Draw circular hole (top-left) using circle_left
|
||||
println!("Drawing circular hole (top-left) with circle_left...");
|
||||
turtle.go_to(vec2(100.0, 100.0));
|
||||
turtle.pen_down(); // Start new contour for hole
|
||||
turtle.circle_left(30.0, 360.0, 36); // radius=30, full circle, 36 steps
|
||||
println!("Closing circle contour with pen_up");
|
||||
turtle.pen_up(); // Close circle hole contour
|
||||
|
||||
// Draw circular hole (bottom-right) using circle_right
|
||||
println!("Drawing circular hole (bottom-right) with circle_right...");
|
||||
turtle.go_to(vec2(280.0, 280.0));
|
||||
turtle.pen_down(); // Start new contour for hole
|
||||
turtle.circle_right(40.0, 360.0, 36); // radius=40, full circle, 36 steps
|
||||
println!("Closing circle contour with pen_up");
|
||||
turtle.pen_up(); // Close circle hole contour
|
||||
|
||||
// End fill - Lyon will automatically create holes!
|
||||
println!("Calling end_fill - Lyon should create holes now!");
|
||||
turtle.end_fill();
|
||||
|
||||
// Set animation speed
|
||||
turtle.set_speed(300);
|
||||
|
||||
println!("Building and executing turtle plan...");
|
||||
}
|
||||
@@ -1,46 +1,29 @@
|
||||
//! Test circle_left and circle_right commands
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Circle Test")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut plan = create_turtle();
|
||||
plan.shape(ShapeType::Turtle);
|
||||
#[turtle_main("Circle Test")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.shape(ShapeType::Turtle);
|
||||
|
||||
// Draw some circles
|
||||
plan.set_pen_color(RED);
|
||||
plan.set_pen_width(0.5);
|
||||
plan.left(90.0);
|
||||
plan.set_speed(999);
|
||||
plan.circle_left(100.0, 540.0, 72); // partial circle to the left
|
||||
turtle.set_pen_color(RED);
|
||||
turtle.set_pen_width(0.5);
|
||||
turtle.left(90.0);
|
||||
turtle.set_speed(999);
|
||||
turtle.circle_left(100.0, 540.0, 72); // partial circle to the left
|
||||
|
||||
plan.forward(150.0);
|
||||
plan.set_speed(100);
|
||||
plan.set_pen_color(BLUE);
|
||||
plan.circle_right(50.0, 270.0, 72); // partial circle to the right
|
||||
// Set animation speed
|
||||
plan.set_speed(20);
|
||||
plan.forward(150.0);
|
||||
plan.circle_left(50.0, 180.0, 12);
|
||||
plan.circle_right(50.0, 180.0, 12);
|
||||
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.set_speed(20);
|
||||
turtle.forward(150.0);
|
||||
turtle.circle_left(50.0, 180.0, 12);
|
||||
turtle.circle_right(50.0, 180.0, 12);
|
||||
|
||||
plan.set_speed(700);
|
||||
plan.set_pen_color(GREEN);
|
||||
plan.circle_left(50.0, 180.0, 36); // Half circle to the left
|
||||
|
||||
// Create turtle app with animation (speed = 100 pixels/sec)
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(700);
|
||||
turtle.set_pen_color(GREEN);
|
||||
turtle.circle_left(50.0, 180.0, 36); // Half circle to the left
|
||||
}
|
||||
|
||||
@@ -1,31 +1,13 @@
|
||||
//! Test circle_left and circle_right commands
|
||||
//! Test direction and movement commands
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Circle Test")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut plan = create_turtle();
|
||||
|
||||
#[turtle_main("Direction Test")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
// Set animation speed
|
||||
plan.set_speed(50);
|
||||
plan.right(45.0);
|
||||
plan.forward(100.0);
|
||||
plan.right(45.0);
|
||||
plan.forward(100.0);
|
||||
|
||||
// Create turtle app with animation (speed = 100 pixels/sec)
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(50);
|
||||
turtle.right(45.0);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(45.0);
|
||||
turtle.forward(100.0);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Advanced fill example with multiple holes and complex shapes
|
||||
//!
|
||||
//! This example uses manual setup to demonstrate custom window size and UI elements.
|
||||
|
||||
use macroquad::{miniquad::window::set_window_size, prelude::*};
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
@@ -1,55 +1,43 @@
|
||||
//! Fill demonstration with holes
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Fill Demo")]
|
||||
async fn main() {
|
||||
let mut t = create_turtle();
|
||||
|
||||
#[turtle_main("Fill Demo")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
// Example from requirements: circle with hole (like a donut)
|
||||
t.set_pen_color(BLUE);
|
||||
t.set_pen_width(3.0);
|
||||
t.right(90.0);
|
||||
turtle.set_pen_color(BLUE);
|
||||
turtle.set_pen_width(3.0);
|
||||
turtle.right(90.0);
|
||||
|
||||
// Set fill color and begin fill
|
||||
t.set_fill_color(RED);
|
||||
t.begin_fill();
|
||||
turtle.set_fill_color(RED);
|
||||
turtle.begin_fill();
|
||||
|
||||
// Outer circle
|
||||
t.circle_right(150.0, 360.0, 72);
|
||||
turtle.circle_right(150.0, 360.0, 72);
|
||||
|
||||
// Move to start of inner circle (hole)
|
||||
// pen_up doesn't matter for fill - vertices still recorded!
|
||||
t.pen_up();
|
||||
t.forward(50.0);
|
||||
t.pen_down();
|
||||
turtle.pen_up();
|
||||
turtle.forward(50.0);
|
||||
turtle.pen_down();
|
||||
|
||||
// Inner circle (creates a hole)
|
||||
t.circle_right(150.0, 360.0, 72);
|
||||
turtle.circle_right(150.0, 360.0, 72);
|
||||
|
||||
t.end_fill();
|
||||
turtle.end_fill();
|
||||
|
||||
// Draw a square with no fill
|
||||
t.pen_up();
|
||||
t.forward(100.0);
|
||||
t.pen_down();
|
||||
t.set_pen_color(GREEN);
|
||||
turtle.pen_up();
|
||||
turtle.forward(100.0);
|
||||
turtle.pen_down();
|
||||
turtle.set_pen_color(GREEN);
|
||||
|
||||
for _ in 0..4 {
|
||||
t.forward(100.0);
|
||||
t.right(90.0);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
}
|
||||
|
||||
// Set animation speed
|
||||
t.set_speed(100);
|
||||
|
||||
let mut app = TurtleApp::new().with_commands(t.build());
|
||||
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
app.update();
|
||||
app.render();
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(100);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
//! Example matching the original requirements exactly
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Fill Example - Original Requirements")]
|
||||
async fn main() {
|
||||
let mut turtle = create_turtle();
|
||||
|
||||
#[turtle_main("Fill Example - Original Requirements")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.right(90.0);
|
||||
turtle.set_pen_width(3.0);
|
||||
turtle.set_speed(900);
|
||||
@@ -37,30 +34,4 @@ async fn main() {
|
||||
|
||||
// Set speed for animation
|
||||
turtle.set_speed(200);
|
||||
|
||||
let mut app = TurtleApp::new().with_commands(turtle.build());
|
||||
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
// Instructions
|
||||
draw_text(
|
||||
"Fill Example - Circle filled with red, square not filled",
|
||||
10.0,
|
||||
20.0,
|
||||
20.0,
|
||||
BLACK,
|
||||
);
|
||||
draw_text(
|
||||
"Mouse: drag to pan, scroll to zoom",
|
||||
10.0,
|
||||
40.0,
|
||||
16.0,
|
||||
DARKGRAY,
|
||||
);
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//! Minimal turtle example - just 10 lines!
|
||||
//!
|
||||
//! This is the simplest possible turtle program using the macro.
|
||||
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[turtle_main("Hello Turtle")]
|
||||
fn hello() {
|
||||
turtle.set_pen_color(BLUE);
|
||||
for _ in 0..4 {
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +1,37 @@
|
||||
//! Koch snowflake fractal example
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
fn koch(depth: u32, plan: &mut TurtlePlan, distance: f32) {
|
||||
fn koch(depth: u32, turtle: &mut TurtlePlan, distance: f32) {
|
||||
if depth == 0 {
|
||||
plan.forward(distance);
|
||||
turtle.forward(distance);
|
||||
} else {
|
||||
let new_distance = distance / 3.0;
|
||||
koch(depth - 1, plan, new_distance);
|
||||
plan.left(60.0);
|
||||
koch(depth - 1, plan, new_distance);
|
||||
plan.right(120.0);
|
||||
koch(depth - 1, plan, new_distance);
|
||||
plan.left(60.0);
|
||||
koch(depth - 1, plan, new_distance);
|
||||
koch(depth - 1, turtle, new_distance);
|
||||
turtle.left(60.0);
|
||||
koch(depth - 1, turtle, new_distance);
|
||||
turtle.right(120.0);
|
||||
koch(depth - 1, turtle, new_distance);
|
||||
turtle.left(60.0);
|
||||
koch(depth - 1, turtle, new_distance);
|
||||
}
|
||||
}
|
||||
|
||||
#[macroquad::main("Koch Snowflake")]
|
||||
async fn main() {
|
||||
let mut plan = create_turtle();
|
||||
|
||||
#[turtle_main("Koch Snowflake")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
// Position turtle
|
||||
plan.set_speed(1001);
|
||||
plan.pen_up();
|
||||
plan.backward(150.0);
|
||||
turtle.set_speed(1001);
|
||||
turtle.pen_up();
|
||||
turtle.backward(150.0);
|
||||
|
||||
plan.pen_down();
|
||||
turtle.pen_down();
|
||||
|
||||
// Draw Koch snowflake (triangle of Koch curves)
|
||||
for _ in 0..3 {
|
||||
koch(4, &mut plan, 300.0);
|
||||
plan.right(120.0);
|
||||
plan.set_speed(1200);
|
||||
koch(4, turtle, 300.0);
|
||||
turtle.right(120.0);
|
||||
turtle.set_speed(1200);
|
||||
}
|
||||
|
||||
plan.hide(); // Hide turtle when done
|
||||
|
||||
// Create app with animation
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
app.update();
|
||||
app.render();
|
||||
next_frame().await
|
||||
}
|
||||
turtle.hide(); // Hide turtle when done
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
//! RUST_LOG=turtle_lib_macroquad::tessellation=debug cargo run --example logging_example
|
||||
//! RUST_LOG=turtle_lib_macroquad::execution=debug cargo run --example logging_example
|
||||
//! ```
|
||||
//!
|
||||
//! Note: This example uses manual setup to demonstrate custom initialization logic.
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
@@ -27,11 +29,10 @@ async fn main() {
|
||||
// This will respect the RUST_LOG environment variable
|
||||
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_macroquad=info")
|
||||
}),
|
||||
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_macroquad=info")
|
||||
}),
|
||||
)
|
||||
.with_target(true) // Show which module the log came from
|
||||
.with_thread_ids(false)
|
||||
@@ -40,7 +41,9 @@ async fn main() {
|
||||
.init();
|
||||
|
||||
tracing::info!("Starting turtle graphics example with logging enabled");
|
||||
tracing::info!("Try running with: RUST_LOG=turtle_lib_macroquad=debug cargo run --example logging_example");
|
||||
tracing::info!(
|
||||
"Try running with: RUST_LOG=turtle_lib_macroquad=debug cargo run --example logging_example"
|
||||
);
|
||||
|
||||
// Create a turtle plan with fill operations to see detailed logging
|
||||
let mut t = create_turtle();
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//! Simple demo of the turtle_main macro
|
||||
//!
|
||||
//! This example shows how the turtle_main macro simplifies turtle programs
|
||||
//! by automatically handling window setup, turtle creation, and the render loop.
|
||||
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[turtle_main("Macro Demo - Simple Square")]
|
||||
fn draw_square(turtle: &mut TurtlePlan) {
|
||||
turtle.set_pen_color(BLUE);
|
||||
turtle.set_pen_width(3.0);
|
||||
|
||||
for _ in 0..4 {
|
||||
turtle.forward(150.0);
|
||||
turtle.right(90.0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//! 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_macroquad::*;
|
||||
|
||||
#[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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//! Comprehensive macro example showing various turtle features
|
||||
//!
|
||||
//! This example demonstrates:
|
||||
//! - Colors and pen settings
|
||||
//! - Fills
|
||||
//! - Circles
|
||||
//! - Animation speed
|
||||
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[turtle_main("Turtle Macro - Full Demo")]
|
||||
fn full_demo(turtle: &mut TurtlePlan) {
|
||||
// Draw a colorful flower
|
||||
turtle.set_speed(200);
|
||||
|
||||
// Center the drawing
|
||||
turtle.pen_up();
|
||||
turtle.go_to(vec2(200.0, 300.0));
|
||||
turtle.pen_down();
|
||||
|
||||
// Draw petals
|
||||
for i in 0..8 {
|
||||
let hue = i as f32 / 8.0;
|
||||
let color = Color::from_rgba(
|
||||
((hue * 360.0).to_radians().sin() * 127.0 + 128.0) as u8,
|
||||
((hue * 360.0 + 120.0).to_radians().sin() * 127.0 + 128.0) as u8,
|
||||
((hue * 360.0 + 240.0).to_radians().sin() * 127.0 + 128.0) as u8,
|
||||
255,
|
||||
);
|
||||
|
||||
turtle.set_fill_color(color);
|
||||
turtle.set_pen_color(color);
|
||||
turtle.begin_fill();
|
||||
|
||||
// Draw a petal using circles
|
||||
turtle.circle_left(50.0, 180.0, 20);
|
||||
turtle.left(90.0);
|
||||
turtle.circle_left(50.0, 180.0, 20);
|
||||
turtle.left(90.0);
|
||||
|
||||
turtle.end_fill();
|
||||
|
||||
// Move to next petal position
|
||||
turtle.right(45.0);
|
||||
}
|
||||
|
||||
// Draw center circle
|
||||
turtle.pen_up();
|
||||
turtle.go_to(vec2(200.0, 300.0));
|
||||
turtle.pen_down();
|
||||
turtle.set_fill_color(YELLOW);
|
||||
turtle.set_pen_color(ORANGE);
|
||||
turtle.set_pen_width(2.0);
|
||||
turtle.begin_fill();
|
||||
turtle.circle_left(20.0, 360.0, 36);
|
||||
turtle.end_fill();
|
||||
}
|
||||
@@ -1,74 +1,57 @@
|
||||
//! Nikolaus example - draws a house-like figure
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
fn nikolausquadrat(plan: &mut TurtlePlan, groesse: f32) {
|
||||
plan.forward(groesse);
|
||||
plan.left(90.0);
|
||||
plan.forward(groesse);
|
||||
plan.left(90.0);
|
||||
plan.forward(groesse);
|
||||
plan.left(90.0);
|
||||
plan.forward(groesse);
|
||||
plan.left(90.0);
|
||||
fn nikolausquadrat(turtle: &mut TurtlePlan, groesse: f32) {
|
||||
turtle.forward(groesse);
|
||||
turtle.left(90.0);
|
||||
turtle.forward(groesse);
|
||||
turtle.left(90.0);
|
||||
turtle.forward(groesse);
|
||||
turtle.left(90.0);
|
||||
turtle.forward(groesse);
|
||||
turtle.left(90.0);
|
||||
}
|
||||
|
||||
fn nikolausdiag(plan: &mut TurtlePlan, groesse: f32) {
|
||||
fn nikolausdiag(turtle: &mut TurtlePlan, groesse: f32) {
|
||||
let quadrat = groesse * groesse;
|
||||
let diag = (quadrat + quadrat).sqrt();
|
||||
|
||||
plan.left(45.0);
|
||||
plan.forward(diag);
|
||||
plan.left(45.0);
|
||||
nikolausdach2(plan, groesse);
|
||||
plan.left(45.0);
|
||||
plan.forward(diag);
|
||||
plan.left(45.0);
|
||||
turtle.left(45.0);
|
||||
turtle.forward(diag);
|
||||
turtle.left(45.0);
|
||||
nikolausdach2(turtle, groesse);
|
||||
turtle.left(45.0);
|
||||
turtle.forward(diag);
|
||||
turtle.left(45.0);
|
||||
}
|
||||
|
||||
fn nikolausdach2(plan: &mut TurtlePlan, groesse: f32) {
|
||||
fn nikolausdach2(turtle: &mut TurtlePlan, groesse: f32) {
|
||||
let quadrat = groesse * groesse;
|
||||
let diag = (quadrat + quadrat).sqrt();
|
||||
plan.left(45.0);
|
||||
plan.forward(diag / 2.0);
|
||||
plan.left(90.0);
|
||||
plan.forward(diag / 2.0);
|
||||
plan.left(45.0);
|
||||
turtle.left(45.0);
|
||||
turtle.forward(diag / 2.0);
|
||||
turtle.left(90.0);
|
||||
turtle.forward(diag / 2.0);
|
||||
turtle.left(45.0);
|
||||
}
|
||||
|
||||
fn nikolaus(plan: &mut TurtlePlan, groesse: f32) {
|
||||
nikolausquadrat(plan, groesse);
|
||||
nikolausdiag(plan, groesse);
|
||||
fn nikolaus(turtle: &mut TurtlePlan, groesse: f32) {
|
||||
nikolausquadrat(turtle, groesse);
|
||||
nikolausdiag(turtle, groesse);
|
||||
}
|
||||
|
||||
#[macroquad::main("Nikolaus")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut plan = create_turtle();
|
||||
plan.shape(ShapeType::Turtle);
|
||||
#[turtle_main("Nikolaus")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.shape(ShapeType::Turtle);
|
||||
|
||||
// Position the turtle (pen up, move, pen down)
|
||||
plan.pen_up();
|
||||
plan.backward(80.0);
|
||||
plan.left(90.0);
|
||||
plan.forward(50.0);
|
||||
plan.right(90.0);
|
||||
plan.pen_down();
|
||||
turtle.pen_up();
|
||||
turtle.backward(80.0);
|
||||
turtle.left(90.0);
|
||||
turtle.forward(50.0);
|
||||
turtle.right(90.0);
|
||||
turtle.pen_down();
|
||||
|
||||
nikolaus(&mut plan, 100.0);
|
||||
|
||||
// Create turtle app with animation
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
nikolaus(turtle, 100.0);
|
||||
}
|
||||
|
||||
@@ -1,50 +1,32 @@
|
||||
//! Example demonstrating different turtle shapes
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Turtle Shapes")]
|
||||
async fn main() {
|
||||
// Create a turtle plan that demonstrates different shapes
|
||||
let mut plan = create_turtle();
|
||||
|
||||
#[turtle_main("Turtle Shapes")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
// Start with triangle (default)
|
||||
plan.forward(100.0);
|
||||
plan.right(90.0);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
|
||||
// Change to turtle shape
|
||||
plan.shape(ShapeType::Turtle);
|
||||
plan.forward(100.0);
|
||||
plan.right(90.0);
|
||||
turtle.shape(ShapeType::Turtle);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
|
||||
// Change to circle
|
||||
plan.shape(ShapeType::Circle);
|
||||
plan.forward(100.0);
|
||||
plan.right(90.0);
|
||||
turtle.shape(ShapeType::Circle);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
|
||||
// Change to square
|
||||
plan.shape(ShapeType::Square);
|
||||
plan.forward(100.0);
|
||||
plan.right(90.0);
|
||||
turtle.shape(ShapeType::Square);
|
||||
turtle.forward(100.0);
|
||||
turtle.right(90.0);
|
||||
|
||||
// Change to arrow
|
||||
plan.shape(ShapeType::Arrow);
|
||||
plan.forward(100.0);
|
||||
turtle.shape(ShapeType::Arrow);
|
||||
turtle.forward(100.0);
|
||||
|
||||
// Set animation speed
|
||||
plan.set_speed(50);
|
||||
|
||||
// Create turtle app with animation (speed = 100 pixels/sec for slower animation)
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(50);
|
||||
}
|
||||
|
||||
@@ -1,33 +1,16 @@
|
||||
//! Simple square example demonstrating basic turtle graphics
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Turtle Square")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut plan = create_turtle();
|
||||
plan.shape(ShapeType::Turtle);
|
||||
#[turtle_main("Turtle Square")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.shape(ShapeType::Turtle);
|
||||
|
||||
// Draw a square
|
||||
for _ in 0..4 {
|
||||
plan.forward(100.0).right(90.0);
|
||||
turtle.forward(100.0).right(90.0);
|
||||
}
|
||||
|
||||
// Set animation speed
|
||||
plan.set_speed(50);
|
||||
|
||||
// Create turtle app with animation
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(50);
|
||||
}
|
||||
|
||||
@@ -1,38 +1,21 @@
|
||||
//! Simple square example demonstrating basic turtle graphics
|
||||
//! Star pattern example demonstrating complex turtle patterns
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Turtle Square")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut plan = create_turtle();
|
||||
plan.shape(ShapeType::Turtle);
|
||||
plan.set_speed(1500);
|
||||
plan.set_pen_width(0.5);
|
||||
#[turtle_main("Star Pattern")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.shape(ShapeType::Turtle);
|
||||
turtle.set_speed(1500);
|
||||
turtle.set_pen_width(0.5);
|
||||
|
||||
// Draw a 5-pointed star pattern repeatedly
|
||||
for _i in 0..50000 {
|
||||
plan.forward(200.0);
|
||||
plan.circle_left(10.0, 72.0, 1000);
|
||||
plan.circle_right(5.0, 360.0, 1000);
|
||||
plan.circle_left(10.0, 72.0, 1000);
|
||||
turtle.forward(200.0);
|
||||
turtle.circle_left(10.0, 72.0, 1000);
|
||||
turtle.circle_right(5.0, 360.0, 1000);
|
||||
turtle.circle_left(10.0, 72.0, 1000);
|
||||
}
|
||||
|
||||
// Set animation speed
|
||||
plan.set_speed(300);
|
||||
|
||||
// Create turtle app with animation (speed = 100 pixels/sec)
|
||||
let mut app = TurtleApp::new().with_commands(plan.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(300);
|
||||
}
|
||||
|
||||
@@ -1,47 +1,30 @@
|
||||
//! Simple square example demonstrating basic turtle graphics
|
||||
//! Yin-Yang symbol example demonstrating multi-contour fills
|
||||
|
||||
use macroquad::prelude::*;
|
||||
use turtle_lib_macroquad::*;
|
||||
|
||||
#[macroquad::main("Turtle Square")]
|
||||
async fn main() {
|
||||
// Create a turtle plan
|
||||
let mut t = create_turtle();
|
||||
t.set_speed(900);
|
||||
#[turtle_main("Yin-Yang")]
|
||||
fn draw(turtle: &mut TurtlePlan) {
|
||||
turtle.set_speed(900);
|
||||
|
||||
t.circle_left(90.0, 180.0, 36);
|
||||
t.begin_fill();
|
||||
t.circle_left(90.0, 180.0, 36);
|
||||
t.circle_left(45.0, 180.0, 26);
|
||||
t.circle_right(45.0, 180.0, 26);
|
||||
t.pen_up();
|
||||
t.right(90.0);
|
||||
t.forward(37.0);
|
||||
t.left(90.0);
|
||||
t.pen_down();
|
||||
t.circle_right(8.0, 360.0, 12);
|
||||
t.pen_up();
|
||||
t.right(90.0);
|
||||
t.forward(90.0);
|
||||
t.left(90.0);
|
||||
t.pen_down();
|
||||
t.circle_right(8.0, 360.0, 12);
|
||||
t.end_fill();
|
||||
turtle.circle_left(90.0, 180.0, 36);
|
||||
turtle.begin_fill();
|
||||
turtle.circle_left(90.0, 180.0, 36);
|
||||
turtle.circle_left(45.0, 180.0, 26);
|
||||
turtle.circle_right(45.0, 180.0, 26);
|
||||
turtle.pen_up();
|
||||
turtle.right(90.0);
|
||||
turtle.forward(37.0);
|
||||
turtle.left(90.0);
|
||||
turtle.pen_down();
|
||||
turtle.circle_right(8.0, 360.0, 12);
|
||||
turtle.pen_up();
|
||||
turtle.right(90.0);
|
||||
turtle.forward(90.0);
|
||||
turtle.left(90.0);
|
||||
turtle.pen_down();
|
||||
turtle.circle_right(8.0, 360.0, 12);
|
||||
turtle.end_fill();
|
||||
|
||||
// Set animation speed
|
||||
t.set_speed(1000);
|
||||
|
||||
// Create turtle app with animation (speed = 100 pixels/sec)
|
||||
let mut app = TurtleApp::new().with_commands(t.build());
|
||||
|
||||
// Main loop
|
||||
loop {
|
||||
clear_background(WHITE);
|
||||
|
||||
// Update and render
|
||||
app.update();
|
||||
app.render();
|
||||
|
||||
next_frame().await
|
||||
}
|
||||
turtle.set_speed(1000);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,29 @@
|
||||
//! This library provides a turtle graphics API for creating drawings and animations
|
||||
//! using the Macroquad game framework.
|
||||
//!
|
||||
//! # Example
|
||||
//! # Quick Start with `turtle_main` Macro
|
||||
//!
|
||||
//! The easiest way to create a turtle program is using the `turtle_main` macro:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use macroquad::prelude::*;
|
||||
//! use turtle_lib_macroquad::*;
|
||||
//!
|
||||
//! #[turtle_main("My Drawing")]
|
||||
//! fn draw(turtle: &mut TurtlePlan) {
|
||||
//! turtle.set_pen_color(RED);
|
||||
//! turtle.forward(100.0);
|
||||
//! turtle.right(90.0);
|
||||
//! turtle.forward(100.0);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! The macro automatically handles window setup, rendering loop, and quit handling.
|
||||
//!
|
||||
//! # Manual Setup Example
|
||||
//!
|
||||
//! For more control, you can set up the application manually:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use macroquad::prelude::*;
|
||||
//! use turtle_lib_macroquad::*;
|
||||
@@ -43,6 +65,14 @@ pub use shapes::{ShapeType, TurtleShape};
|
||||
pub use state::{DrawCommand, TurtleState, TurtleWorld};
|
||||
pub use tweening::TweenController;
|
||||
|
||||
// Re-export the turtle_main macro
|
||||
pub use turtle_lib_macroquad_macros::turtle_main;
|
||||
|
||||
// Re-export common macroquad types and colors for convenience
|
||||
pub use macroquad::prelude::{
|
||||
vec2, BLACK, BLUE, DARKGRAY, GOLD, GREEN, ORANGE, PURPLE, RED, WHITE, YELLOW,
|
||||
};
|
||||
|
||||
use macroquad::prelude::*;
|
||||
|
||||
/// Main turtle application struct
|
||||
|
||||
Reference in New Issue
Block a user