-
Notifications
You must be signed in to change notification settings - Fork 15
/
turtle.ts
173 lines (157 loc) · 4.46 KB
/
turtle.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
enum TurtlePenMode {
//% block="down"
Down,
//% block="up"
Up
}
/**
* Turtle graphics blocks
*/
//% weight=100 color=#0f9c11 icon="\uf188"
namespace turtle {
let _x: number;
let _y: number;
let _direction: number; // 0 right, 1 down, 2 left, 3 top
let _brightness: number;
let _penMode: TurtlePenMode = TurtlePenMode.Up;
let _img: Image;
let _delay = 250;
function init() {
if (!_img) {
led.setBrightness(255);
led.setDisplayMode(DisplayMode.Greyscale);
_x = 2;
_y = 2;
_direction = 3;
_brightness = 128;
_img = images.createImage(`
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
`)
basic.clearScreen();
}
}
function paint() {
// plot background
_img.plotImage();
// plot turtle
led.plotBrightness(_x, _y, 255);
// slow down
basic.pause(_delay);
}
/**
* Moves the turtle for the given amount of pixels
* @param steps number of steps, eg: 1
*/
//% blockId=turtleForward block="forward %steps|steps"
//% weight=99 blockGap=8
export function forward(steps: number): void {
init();
if (!steps) return;
const sign = steps > 0 ? 1 : -1;
const dx = _direction == 0 ? sign : _direction == 2 ? -sign : 0;
const dy = _direction == 1 ? sign : _direction == 3 ? -sign : 0;
const n = Math.abs(steps);
for (let i = 0; i < n; ++i) {
// paint if pen down
if (_penMode == TurtlePenMode.Down)
_img.setPixelBrightness(_x, _y, _brightness);
// paint and update
setPosition(_x + dx, _y + dy);
}
}
/**
* Moves back by the given number of steps
* @param steps number of steps to move, eg: 1
*/
//% blockId=turtleBack block="back %steps|steps"
//% weight=98 blockGap=8
export function back(steps: number): void {
forward(-steps);
}
function turn(quadrants: number): void {
init();
_direction = (_direction + quadrants) % 4; if (_direction < 0) _direction += 4;
}
/**
* Turns left by 90 degrees
*/
//% blockId=turtleTurnLeft block="turn left"
//% weight=89 blockGap=8
export function turnLeft(): void {
turn(-1);
}
/**
* Turns right by 90 degrees
*/
//% blockId=turtleTurnRight block="turn right"
//% weight=88 blockGap=8
export function turnRight(): void {
turn(1);
}
/**
* Sets the turtle position
* @param x the horizontal position from 0 (left) to 4 (right), eg: 2
* @param y the vertical position from 0 (top) to 4 (bottom), eg: 2
*/
//% x.min=0 x.max=4
//% y.min=0 y.max=4
//% blockId=turtleSetPosition block="set position x: %x|y: %y"
//% weight=87
export function setPosition(x: number, y: number): void {
init();
_x = x % 5; if (_x < 0) _x += 5;
_y = y % 5; if (_y < 0) _y += 5;
paint();
}
/**
* Puts the pen down or up
*/
//% blockGap=8
//% blockId=turtlePen block="pen %mode"
//% weight=65
export function pen(mode: TurtlePenMode): void {
init();
_penMode = mode;
paint();
}
/**
* Moves the turtle to the center of the screen
*/
//% blockGap=8
//% blockId=turtleHome block="home"
export function home(): void {
setPosition(2, 2);
_direction = 3;
}
/**
* Sets the brightness
* @param brightness the brightness of the trail left by the turtle, eg: 128
*/
//% blockGap=8
//% brightness.min=0 brightness.max=255
//% blockId=turtleSetBrightness block="set brightess %brightness"
export function setBrightness(brightness: number): void {
init();
_brightness = Math.max(0, Math.min(255, brightness));
paint();
}
/**
* Define the steps per second
* @param stepsPerSecond steps per second, eg: 25
*/
//% blockGap=8
//% blockId=turtleSetSpeed block="set speed %speed"
//% stepsPerSecond.min=1 stepsPerSecond.max=50
//% weight=10
export function setSpeed(stepsPerSecond: number): void {
if (stepsPerSecond <= 0) return;
_delay = Math.max(1, Math.min(50, Math.idiv(1000, stepsPerSecond)));
}
// auto-initialize
init()
paint()
}