2023-02-03 10:49:53 +03:00
|
|
|
|
unit TurtleWPF;
|
|
|
|
|
|
|
2023-02-09 10:52:06 +03:00
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
|
|
uses GraphWPF;
|
|
|
|
|
|
|
|
|
|
|
|
/// Передвигает Черепаху вперёд на расстояние r
|
|
|
|
|
|
procedure Forw(r: real);
|
|
|
|
|
|
|
|
|
|
|
|
/// Передвигает Черепаху назад на расстояние r
|
|
|
|
|
|
procedure Back(r: real);
|
|
|
|
|
|
|
|
|
|
|
|
/// Поворачивает Черепаху на угол da по часовой стрелке
|
|
|
|
|
|
procedure Turn(da: real);
|
|
|
|
|
|
|
2023-06-27 21:06:24 +03:00
|
|
|
|
/// Поворачивает Черепаху на угол da влево
|
2023-02-09 10:52:06 +03:00
|
|
|
|
procedure TurnLeft(da: real);
|
|
|
|
|
|
|
2023-06-27 21:06:24 +03:00
|
|
|
|
/// Поворачивает Черепаху на угол da вправо
|
2023-02-09 10:52:06 +03:00
|
|
|
|
procedure TurnRight(da: real);
|
|
|
|
|
|
|
|
|
|
|
|
/// Возвращает случайный цвет
|
|
|
|
|
|
function RandomColor: Color;
|
|
|
|
|
|
|
|
|
|
|
|
/// Возвращает цвет по красной, зеленой и синей составляющей (в диапазоне 0..255)
|
|
|
|
|
|
function RGB(r,g,b: byte): Color;
|
|
|
|
|
|
|
|
|
|
|
|
/// Устанавливает скорость черепашки (от 1 до 10)
|
|
|
|
|
|
procedure SetSpeed(sp: integer);
|
|
|
|
|
|
|
|
|
|
|
|
/// Прячет Черепаху
|
|
|
|
|
|
procedure Hide;
|
|
|
|
|
|
|
|
|
|
|
|
/// Показывает Черепаху
|
|
|
|
|
|
procedure Show;
|
|
|
|
|
|
|
|
|
|
|
|
/// Опускает перо Черепахи
|
|
|
|
|
|
procedure Down;
|
|
|
|
|
|
|
|
|
|
|
|
/// Поднимает перо Черепахи
|
|
|
|
|
|
procedure Up;
|
|
|
|
|
|
|
|
|
|
|
|
/// Устанавливает ширину линии
|
|
|
|
|
|
procedure SetWidth(w: real);
|
|
|
|
|
|
|
|
|
|
|
|
/// Устанавливает цвет линии
|
|
|
|
|
|
procedure SetColor(c: GColor);
|
|
|
|
|
|
|
|
|
|
|
|
/// Перемещает Черепаху в точку (x,y)
|
|
|
|
|
|
procedure MoveTo(x,y: real);
|
|
|
|
|
|
|
|
|
|
|
|
/// Сохраняет изображение, нарисованное Черепахой, в файл fname (например, 'a.png')
|
|
|
|
|
|
procedure Save(fname: string);
|
|
|
|
|
|
|
|
|
|
|
|
type Colors = GraphWPF.Colors;
|
|
|
|
|
|
|
|
|
|
|
|
{type turtle = static class
|
|
|
|
|
|
/// Передвигает Черепаху вперёд на расстояние r
|
|
|
|
|
|
static procedure Forw(r: real) := TurtleWPF.Forw(r);
|
|
|
|
|
|
/// Поворачивает Черепаху на угол da по часовой стрелке
|
|
|
|
|
|
static procedure Turn(da: real) := TurtleWPF.Turn(da);
|
|
|
|
|
|
/// Возвращает случайный цвет
|
|
|
|
|
|
static function RandomColor: Color := TurtleWPF.RandomColor;
|
|
|
|
|
|
/// Возвращает цвет по красной, зеленой и синей составляющей (в диапазоне 0..255)
|
|
|
|
|
|
static function RGB(r,g,b: byte): Color := TurtleWPF.RGB(r,g,b);
|
|
|
|
|
|
/// Устанавливает скорость черепашки (от 1 до 10)
|
|
|
|
|
|
static procedure SetSpeed(sp: integer) := TurtleWPF.SetSpeed(sp);
|
|
|
|
|
|
/// Прячет Черепаху
|
|
|
|
|
|
static procedure Hide := TurtleWPF.Hide;
|
|
|
|
|
|
/// Показывает Черепаху
|
|
|
|
|
|
static procedure Show := TurtleWPF.Show;
|
|
|
|
|
|
/// Опускает перо Черепахи
|
|
|
|
|
|
static procedure Down := TurtleWPF.Down;
|
|
|
|
|
|
/// Поднимает перо Черепахи
|
|
|
|
|
|
static procedure Up := TurtleWPF.Up;
|
|
|
|
|
|
/// Устанавливает ширину линии
|
|
|
|
|
|
static procedure SetWidth(w: real) := TurtleWPF.SetWidth(w);
|
|
|
|
|
|
/// Устанавливает цвет линии
|
|
|
|
|
|
static procedure SetColor(c: GColor) := TurtleWPF.SetColor(c);
|
|
|
|
|
|
/// Перемещает Черепаху в точку (x,y)
|
|
|
|
|
|
static procedure MoveTo(x,y: real) := TurtleWPF.MoveTo(x,y);
|
|
|
|
|
|
/// Сохраняет изображение, нарисованное Черепахой, в файл fname (например, 'a.png')
|
|
|
|
|
|
static procedure Save(fname: string) := TurtleWPF.Save(fname);
|
|
|
|
|
|
end;}
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
2023-02-03 10:49:53 +03:00
|
|
|
|
{$resource 'turtle.png'}
|
|
|
|
|
|
|
2023-02-09 10:52:06 +03:00
|
|
|
|
uses WPFObjects,GraphWPFBase;
|
2023-02-03 10:49:53 +03:00
|
|
|
|
uses System.Windows.Media.Animation;
|
|
|
|
|
|
uses System.Windows.Media;
|
|
|
|
|
|
uses System.Windows.Media.Imaging;
|
|
|
|
|
|
|
|
|
|
|
|
var
|
|
|
|
|
|
TurtleX: real := 400;
|
|
|
|
|
|
TurtleY: real := 300;
|
|
|
|
|
|
w := 24; // размер изображения Черепахи
|
|
|
|
|
|
|
|
|
|
|
|
type
|
|
|
|
|
|
TurtleHelper = class(PictureWPF)
|
|
|
|
|
|
private
|
|
|
|
|
|
function CreateBitmapImageFromResource(resourcename: string): BitmapImage;
|
|
|
|
|
|
begin
|
|
|
|
|
|
var bi := new BitmapImage();
|
|
|
|
|
|
bi.BeginInit();
|
|
|
|
|
|
bi.StreamSource := GetResourceStream(resourcename);
|
|
|
|
|
|
bi.EndInit();
|
|
|
|
|
|
Result := bi;
|
|
|
|
|
|
end;
|
|
|
|
|
|
procedure InitObFromResource(x,y,w,h: real; fname: string);
|
|
|
|
|
|
begin
|
|
|
|
|
|
var b := CreateBitmapImageFromResource(fname);
|
|
|
|
|
|
Rest(x,y,w,h,b);
|
|
|
|
|
|
end;
|
|
|
|
|
|
procedure AnimMoveByPE(a,b,sec: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
var v := CreateVisual;
|
|
|
|
|
|
var p := Center;
|
|
|
|
|
|
var (x,y) := (transl.X,transl.Y);
|
2023-02-09 10:52:06 +03:00
|
|
|
|
var ax := new DoubleAnimation(a + x, System.TimeSpan.FromSeconds(sec));
|
|
|
|
|
|
var ay := new DoubleAnimation(b + y, System.TimeSpan.FromSeconds(sec));
|
2023-02-03 10:49:53 +03:00
|
|
|
|
ax.FillBehavior := FillBehavior.Stop;
|
|
|
|
|
|
ay.FillBehavior := FillBehavior.Stop;
|
|
|
|
|
|
var transl1 := transl;
|
|
|
|
|
|
ax.Completed += (o,e) -> begin
|
|
|
|
|
|
DrawOnVisual(v,dc->dc.DrawLine(GraphWPF.Pen.PenConstruct,p,Pnt(p.X + a,p.Y + b)));
|
|
|
|
|
|
transl1.X := x + a; // transl - ошибка с лямбдами!
|
|
|
|
|
|
end;
|
|
|
|
|
|
ay.Completed += (o,e) -> begin
|
|
|
|
|
|
transl1.Y := y + b;
|
|
|
|
|
|
end;
|
|
|
|
|
|
ax.CurrentTimeInvalidated += (o,e) ->
|
|
|
|
|
|
DrawOnVisual(v,dc->dc.DrawLine(GraphWPF.Pen.PenConstruct,p,Pnt(Center.X,Center.Y)));
|
|
|
|
|
|
transl.BeginAnimation(TranslateTransform.XProperty, ax, HandoffBehavior.Compose);
|
|
|
|
|
|
transl.BeginAnimation(TranslateTransform.YProperty, ay, HandoffBehavior.Compose);
|
|
|
|
|
|
end;
|
|
|
|
|
|
public
|
|
|
|
|
|
constructor (x,y,w,h: real; fname: string) := Invoke(InitObFromResource,x,y,w,h,fname);
|
|
|
|
|
|
procedure AnimMoveByE(a,b,sec: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
Invoke(AnimMoveByPE,a,b,sec);
|
|
|
|
|
|
Sleep(Round(sec*1000 + 50)); // 50 мс - За это время анимация должна закончиться
|
|
|
|
|
|
end;
|
|
|
|
|
|
procedure AnimRotateE(a,sec: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
AnimRotate(a,sec);
|
|
|
|
|
|
Sleep(Round(sec*1000 + 50));
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
var t: TurtleHelper;
|
|
|
|
|
|
|
|
|
|
|
|
var
|
|
|
|
|
|
a: real := 0;
|
|
|
|
|
|
dr := False;
|
|
|
|
|
|
speed := 10;
|
2023-02-09 10:52:06 +03:00
|
|
|
|
Window := GraphWPF.Window;
|
|
|
|
|
|
|
|
|
|
|
|
function RandomColor := GraphWPF.RandomColor;
|
|
|
|
|
|
function RGB(r,g,b: byte) := GraphWPF.RGB(r, g, b);
|
|
|
|
|
|
|
|
|
|
|
|
var sl := 30;
|
2023-02-03 10:49:53 +03:00
|
|
|
|
|
|
|
|
|
|
procedure SetSpeed(sp: integer);
|
|
|
|
|
|
begin
|
2023-02-09 10:52:06 +03:00
|
|
|
|
speed := sp.Clamp(1,10);
|
|
|
|
|
|
if sp > 10 then
|
|
|
|
|
|
sl := 0
|
|
|
|
|
|
else sl := 30;
|
2023-02-03 10:49:53 +03:00
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure Hide;
|
|
|
|
|
|
begin
|
|
|
|
|
|
t.Visible := False;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
procedure Show;
|
|
|
|
|
|
begin
|
|
|
|
|
|
t.Visible := True;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
/// Поворачивает Черепаху на угол da по часовой стрелке
|
|
|
|
|
|
procedure Turn(da: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
a += da;
|
|
|
|
|
|
if speed = 10 then
|
|
|
|
|
|
begin
|
|
|
|
|
|
t.Rotate(da);
|
|
|
|
|
|
Sleep(sl);
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
|
|
|
|
|
begin
|
|
|
|
|
|
if dr then
|
|
|
|
|
|
t.AnimRotateE(da,Abs(da/(60*speed)))
|
|
|
|
|
|
else
|
|
|
|
|
|
begin
|
|
|
|
|
|
t.AnimRotate(da,Abs(da/(60*speed)));
|
|
|
|
|
|
Sleep(Round(Abs(da/(60*speed))*1000)+50);
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2023-06-27 21:06:24 +03:00
|
|
|
|
procedure TurnLeft(da: real) := Turn(-da);
|
2023-02-09 10:52:06 +03:00
|
|
|
|
|
2023-06-27 21:06:24 +03:00
|
|
|
|
procedure TurnRight(da: real) := Turn(da);
|
2023-02-09 10:52:06 +03:00
|
|
|
|
|
2023-02-03 10:49:53 +03:00
|
|
|
|
/// Продвигает Черепаху вперёд на расстояние r
|
|
|
|
|
|
procedure Forw(r: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
var v := r * Vect(Cos(DegToRad(a)),Sin(DegToRad(a)));
|
2023-02-09 10:52:06 +03:00
|
|
|
|
var (a,b) := (v.X,v.Y);
|
|
|
|
|
|
TurtleX += a;
|
|
|
|
|
|
TurtleY += b;
|
2023-02-03 10:49:53 +03:00
|
|
|
|
if (speed = 10) or (r < 20) then
|
|
|
|
|
|
begin
|
|
|
|
|
|
if dr then
|
2023-02-09 10:52:06 +03:00
|
|
|
|
GraphWPF.LineTo(TurtleX,TurtleY)
|
|
|
|
|
|
else GraphWPF.MoveTo(TurtleX,TurtleY);
|
|
|
|
|
|
t.MoveBy(a,b);
|
2023-02-03 10:49:53 +03:00
|
|
|
|
Sleep(sl);
|
|
|
|
|
|
end
|
|
|
|
|
|
else
|
|
|
|
|
|
begin
|
|
|
|
|
|
if dr then
|
2023-02-09 10:52:06 +03:00
|
|
|
|
begin
|
|
|
|
|
|
t.AnimMoveByE(a,b,r/(50*speed)); // 450 в секунду при скорости 9
|
|
|
|
|
|
GraphWPF.MoveTo(TurtleX,TurtleY);
|
|
|
|
|
|
end
|
2023-02-03 10:49:53 +03:00
|
|
|
|
else
|
|
|
|
|
|
begin
|
2023-02-09 10:52:06 +03:00
|
|
|
|
t.AnimMoveBy(a,b,r/(50*speed));
|
2023-02-03 10:49:53 +03:00
|
|
|
|
Sleep(Round(r/(50*speed)*1000)+50);
|
2023-02-09 10:52:06 +03:00
|
|
|
|
GraphWPF.MoveTo(TurtleX,TurtleY);
|
2023-02-03 10:49:53 +03:00
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
2023-02-09 10:52:06 +03:00
|
|
|
|
procedure Back(r: real) := Forw(-r);
|
|
|
|
|
|
|
2023-02-03 10:49:53 +03:00
|
|
|
|
/// Опускает хвост Черепахи
|
|
|
|
|
|
procedure Down := dr := True;
|
|
|
|
|
|
|
|
|
|
|
|
/// Поднимает хвост Черепахи
|
|
|
|
|
|
procedure Up := dr := False;
|
|
|
|
|
|
|
|
|
|
|
|
/// Устанавливает ширину линии
|
|
|
|
|
|
procedure SetWidth(w: real) := GraphWPF.Pen.Width := w;
|
|
|
|
|
|
|
|
|
|
|
|
/// Устанавливает цвет линии
|
|
|
|
|
|
procedure SetColor(c: GColor) := GraphWPF.Pen.Color := c;
|
|
|
|
|
|
|
|
|
|
|
|
/// Перемещает Черепаху в точку (x,y)
|
|
|
|
|
|
procedure MoveTo(x,y: real);
|
|
|
|
|
|
begin
|
|
|
|
|
|
TurtleX := x;
|
|
|
|
|
|
TurtleY := y;
|
|
|
|
|
|
GraphWPF.MoveTo(x,y);
|
|
|
|
|
|
t.Center := Pnt(x,y);
|
|
|
|
|
|
end;
|
2023-02-09 10:52:06 +03:00
|
|
|
|
|
|
|
|
|
|
procedure Save(fname: string) := Window.Save(fname);
|
|
|
|
|
|
|
2023-02-03 10:49:53 +03:00
|
|
|
|
|
|
|
|
|
|
begin
|
|
|
|
|
|
Window.Title := 'Исполнитель Черепаха WPF';
|
|
|
|
|
|
|
|
|
|
|
|
t := new TurtleHelper(TurtleX-w/2,TurtleY-w/2,w,w,'turtle.png');
|
|
|
|
|
|
//Pen.RoundCap := True;
|
|
|
|
|
|
MoveTo(TurtleX,TurtleY);
|
|
|
|
|
|
a -= 90;
|
|
|
|
|
|
end.
|