1 /** 2 * Simple turtle graphics API 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <vladimir@thecybershadow.net> 12 */ 13 14 module ae.demo.turtle.turtle; 15 16 import std.math; 17 18 import ae.utils.graphics.draw; 19 import ae.utils.graphics.view; 20 21 struct Turtle(View) 22 if (isWritableView!View) 23 { 24 alias Color = ViewColor!View; 25 26 /// View to draw on. This will usually be a reference. 27 View view; 28 29 /// How many pixels is one unit (as used by `forward`). 30 float scale; 31 32 /// Current turtle coordinates. 33 float x = 0, y = 0; 34 35 /// Current turtle orientation (in degrees). 36 /// Initially, the turtle is facing upwards. 37 float orientation = 270; 38 39 /// Current turtle color. 40 Color color; 41 42 /// Is the pen currently down? 43 bool penActive = false; 44 45 /// Put the pen up or down. 46 void penUp () { penActive = false; } 47 void penDown() { penActive = true; } /// ditto 48 49 /// Change the turtle orientation by the given number of degrees. 50 void turnLeft (float deg) { orientation -= deg; } 51 void turnRight(float deg) { orientation += deg; } /// ditto 52 void turnAround() { orientation += 180; } 53 54 /// Move the turtle forward by the given number of units. 55 /// If the pen is down, draw a line with the configured color. 56 void forward(float distance) 57 { 58 // Angle in radians. 59 float rad = orientation / 180 * PI; 60 61 // Convert distance from units to pixels. 62 distance *= scale; 63 64 // Endpoint coordinates. 65 float x0 = this.x; 66 float y0 = this.y; 67 float x1 = x0 + distance * cos(rad); 68 float y1 = y0 + distance * sin(rad); 69 70 // Draw a line if needed. 71 if (penActive) 72 view.aaLine(x0, y0, x1, y1, color); 73 74 // Update coordinates. 75 this.x = x1; 76 this.y = y1; 77 } 78 } 79 80 auto turtle(View)(ref View view) 81 if (isWritableView!View) 82 { 83 import std.typecons; 84 alias R = NullableRef!View; 85 R r = R(&view); 86 return Turtle!R(r); 87 }