당신의 접근 방식의 문제는 단위 시간당 이동 양이 모양 사이의 거리에 비례한다는 것입니다 및 마우스 클릭 위치. 마우스 위치에서 필요한 것은 방향이고 방향을 얻는 표준 방법은 관심있는 점 사이에 형성된 벡터를 표준화하는 것입니다.
관심 지점 사이에 형성된 선분의 크기로 나누면 원하는 방향으로 길이가 1px 인 단위 벡터가 생성됩니다. 이 값은 모션 증분을 생성하기 위해 속도에 의해 조절되어야합니다.
당신의 단위가 각 단계에서 반올림해야하기 때문에이 정수와 함께 할 서투른이지만, 다음과 같이 수행 할 수 있습니다 :
procedure TForm1.Timer1Timer(Sender: TObject);
const
SPEED = 5;
var
dx, dy : integer;
mag : double;
begin
dx := mx - Shape1.Left; {vector x}
dy := my - Shape1.Top; {vector y}
mag := Sqrt(dx*dx + dy*dy); {vector magnitude}
if (Abs(dx) > SPEED) or (Abs(dy) > SPEED) then
begin
{ use Ceil to move at least 1px. }
Shape1.Left := Shape1.Left
+ Sign(dx)*Ceil(SPEED*Abs(dx)/mag); {divide by mag}
Shape1.Top := Shape1.Top {to give a unit}
+ Sign(dy)*Ceil(SPEED*Abs(dy)/mag); {vector in the}
end else begin {required direction}
Shape1.Left := mx; {snap to mx/my if close enough}
Shape1.Top := my; {deals with rounding issues...}
end;
end;
그렇지 않으면, 더 우아하게, 당신은 부동에서 도형의 위치를 저장할 수 있습니다 point 쌍을 지정하고 컨트롤의 위치를 설정할 때만 정수로 반올림합니다. 이렇게하면 각 단계마다 정수 정밀도 문제가 발생하지 않습니다.
내가 가지고있는 코드를 포함하도록 질문을 편집 해보십시오. –
수정 해 주셔서 감사합니다. 하나의 질문이 더 많습니다. 특정 거리는 얼마입니까? –
그러면 마우스 클릭으로 정의 된 일정한 속도로이 모양을 이동해야합니까? 그런 다음 마우스를 클릭하면 속도, vx 및 vy (x 및 y 구성 요소)를 계산하여 저장합니다. 각 타이머 이벤트에서 do do1.lft : = shape1.left + vx; shape1.top : = shape1.top + vy; –