Blame lazarus/magic-marker/unit1.pas

Ivan Mahonin 7d0db5
unit Unit1;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
{$mode objfpc}{$H+}
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
interface
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
uses
Ivan Mahonin 7d0db5
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
type
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  { TForm1 }
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  TForm1 = class(TForm)
Ivan Mahonin 7d0db5
    Timer1: TTimer;
Ivan Mahonin 7d0db5
    Timer2: TTimer;
Ivan Mahonin 7d0db5
    procedure FormCreate(Sender: TObject);
Ivan Mahonin 7d0db5
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
Ivan Mahonin 7d0db5
    procedure FormPaint(Sender: TObject);
Ivan Mahonin 7d0db5
    procedure Timer1Timer(Sender: TObject);
Ivan Mahonin 7d0db5
    procedure Timer2Timer(Sender: TObject);
Ivan Mahonin 7d0db5
  private
Ivan Mahonin 7d0db5
    { private declarations }
Ivan Mahonin 7d0db5
  public
Ivan Mahonin 7d0db5
    { public declarations }
Ivan Mahonin 7d0db5
  end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
const
Ivan Mahonin 7d0db5
  pointR = 5;
Ivan Mahonin 7d0db5
  ballR = 40;
Ivan Mahonin 7d0db5
  g = 0.002;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
var
Ivan Mahonin 7d0db5
  Form1: TForm1;
Ivan Mahonin 7d0db5
  maxPoints: integer = 100;
Ivan Mahonin 7d0db5
  points: array of TPoint;
Ivan Mahonin 7d0db5
  bx, by, vx, vy: single;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
implementation
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
{$R *.lfm}
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure addPoint(x, y: integer);
Ivan Mahonin 7d0db5
var
Ivan Mahonin 7d0db5
  i, l: integer;
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  if maxPoints <= 0 then exit;
Ivan Mahonin 7d0db5
  l := Length(points);
Ivan Mahonin 7d0db5
  if l < maxPoints then begin
Ivan Mahonin 7d0db5
    SetLength(points, l+1);
Ivan Mahonin 7d0db5
    points[l].X := x;
Ivan Mahonin 7d0db5
    points[l].Y := y;
Ivan Mahonin 7d0db5
  end else begin
Ivan Mahonin 7d0db5
    for i:=1 to l-1 do begin
Ivan Mahonin 7d0db5
      points[i-1] := points[i];
Ivan Mahonin 7d0db5
    end;
Ivan Mahonin 7d0db5
    points[l-1].X := x;
Ivan Mahonin 7d0db5
    points[l-1].Y := y;
Ivan Mahonin 7d0db5
  end;
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure TForm1.FormCreate(Sender: TObject);
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  bx := 200;
Ivan Mahonin 7d0db5
  by := 100;
Ivan Mahonin 7d0db5
  vx := 0.1;
Ivan Mahonin 7d0db5
  vy := 0;
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Ivan Mahonin 7d0db5
  Y: Integer);
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  if ssLeft in Shift then begin
Ivan Mahonin 7d0db5
    addPoint(x, y);
Ivan Mahonin 7d0db5
    // todo: addPointChain
Ivan Mahonin 7d0db5
  end;
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure TForm1.FormPaint(Sender: TObject);
Ivan Mahonin 7d0db5
var
Ivan Mahonin 7d0db5
  i: integer;
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  Canvas.Pen.Color := clBlack;
Ivan Mahonin 7d0db5
  Canvas.Pen.Width := pointR * 2;
Ivan Mahonin 7d0db5
  for i:=0 to length(points)-1 do begin
Ivan Mahonin 7d0db5
    Canvas.MoveTo(points[i].x, points[i].y);
Ivan Mahonin 7d0db5
    Canvas.LineTo(points[i].x, points[i].y);
Ivan Mahonin 7d0db5
  end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  Canvas.Pen.Color := clBlue;
Ivan Mahonin 7d0db5
  Canvas.Pen.Width := ballR * 2;
Ivan Mahonin 7d0db5
  Canvas.MoveTo(round(bx), round(by));
Ivan Mahonin 7d0db5
  Canvas.LineTo(round(bx), round(by));
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure TForm1.Timer1Timer(Sender: TObject);
Ivan Mahonin 7d0db5
var
Ivan Mahonin 7d0db5
  i: integer;
Ivan Mahonin 7d0db5
  dx, dy, sqlen, minSqlen, dv: single;
Ivan Mahonin 7d0db5
  collision: boolean;
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  collision := false;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  bx := bx + vx;
Ivan Mahonin 7d0db5
  by := by + vy;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  if bx > ClientWidth  - ballR then begin vx := -abs(vx); collision := true; end;
Ivan Mahonin 7d0db5
  if by > ClientHeight - ballR then begin vy := -abs(vy); collision := true; end;
Ivan Mahonin 7d0db5
  if bx < ballR                then begin vx :=  abs(vx); collision := true; end;
Ivan Mahonin 7d0db5
  if by < ballR                then begin vy :=  abs(vy); collision := true; end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  minSqlen := sqr(ballR + pointR);
Ivan Mahonin 7d0db5
  for i := 0 to length(points)-1 do begin
Ivan Mahonin 7d0db5
    dx := points[i].X-bx;
Ivan Mahonin 7d0db5
    dy := points[i].Y-by;
Ivan Mahonin 7d0db5
    sqlen := sqr(dx) + sqr(dy);
Ivan Mahonin 7d0db5
    if (sqlen > 0.1*minSqlen) and (minSqlen > sqlen) then begin
Ivan Mahonin 7d0db5
      dv := -2*(dx*vx + dy*vy)/sqlen;
Ivan Mahonin 7d0db5
      if dv < 0 then begin
Ivan Mahonin 7d0db5
        vx := vx + dv*dx;
Ivan Mahonin 7d0db5
        vy := vy + dv*dy;
Ivan Mahonin 7d0db5
        collision := true;
Ivan Mahonin 7d0db5
      end;
Ivan Mahonin 7d0db5
    end;
Ivan Mahonin 7d0db5
  end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
  if not collision then vy := vy + g;
Ivan Mahonin 7d0db5
  if collision then refresh;
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
procedure TForm1.Timer2Timer(Sender: TObject);
Ivan Mahonin 7d0db5
begin
Ivan Mahonin 7d0db5
  Refresh;
Ivan Mahonin 7d0db5
end;
Ivan Mahonin 7d0db5
Ivan Mahonin 7d0db5
end.
Ivan Mahonin 7d0db5