2013-04-21 1 views
-3

2 셰이프와 2 타이머를 사용하여 onother로 셰이프 이동을 시도하고 있지만 정말 보이지 않습니다. 나는 생각하고 있었다 :델피, 셰이프 이동을 멈추게하는 방법

처음에 모양 1을 만들고 모양 2의 거리를 계산 한 다음 그쪽으로 움직인다. 이것은 내가 한 일이다. 코드를 이해할 수 있도록 주석을 추가했다. 인 혼란을 조금 :

procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
timer1.Interval:=100;   //set interval=200 
          //begin 
if shape1.Left=shape2.Left then 
begin 
shape1.Left:=shape1.left   //If shape's 1 coordinates = shape's 2 then 
end else      //shape1.left:=stop moving else do 
begin       //find if shape 2 is right or left from shape 1 
if shape1.left>shape2.Left then 
begin 
shape1.Left:=shape1.Left-5; 
end else shape1.Left:=shape1.Left+5; 
//Moving to shape2.left until shape1.left:=shape2.left 



end; 
end; 


procedure TForm1.Timer2Timer(Sender: TObject); 
begin 
timer2.Interval:=100;  //the same method as timer1 

if shape1.top=shape2.top then 
begin 
shape1.top:=shape1.top 
end else 
begin 
if shape1.top>shape2.top then 
begin 
shape1.top:=shape1.top-5; 
end else shape1.top:=shape1.top+5; 

end; 
end; 

end. 
, 지금은 모양이 방향으로 이동하는 것입니다 않지만, 내가 그것을 2 모양을 스틱 의미, 이동 중지하지 않습니다,하지만 여전히 거꾸로 이동 무엇 shape1

하지만, 모양 2에서 왼쪽 - 오른쪽이 아닙니다. 타이머의 2 코드를 확인했는데 잘못이 없습니다.

+0

프로그램에서 모든 단계를 수행하도록 요청한 것처럼 보입니다. 오늘 밤 잘 자면 내일 문제를 해결할 수 있을까요? –

+3

아무튼 : (1) 하나의 타이머 만 사용하십시오. (2)'shape1.Left : = shape1.left'는 간단히 노 연산입니다. (3) 디자인 타임에 타이머의 간격을 설정하거나 * once *. 1 초에 10 번! (4)'shape1.top : = shape1.top'도 no-op입니다. (5) Delphi로 구현 된 애니메이션은 구현하기 전에 논리를 통해서만 생각하면 어렵지 않습니다. –

+0

문제는 없습니다. P. 타이머 2의 프로그램을 확인하십시오. 타이머 1과 동일합니다. SHAPE1.TOP:=SHAPE2.TOP 그 다음 SHAPE1.TOP:=SHAPE1.TOP ... 말하듯이 : Hey Shape1, shape2로 이동하면 움직이지 않게되고, 하지만 그렇지 않습니다. – user2296565

답변

0

다음 코드를보십시오 (OnCreate 양식의 OnPaint을 할당하고 30 개 밀리 초 간격으로 타이머를 설정) :

unit Unit5; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ExtCtrls; 

type 
    TVector = record 
    X, Y: real; 
    end; 

    TForm5 = class(TForm) 
    Timer1: TTimer; 
    procedure FormPaint(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure Timer1Timer(Sender: TObject); 
    private 
    { Private declarations } 
    FPosA, FPosB: TVector; 
    v: TVector; 
    public 
    { Public declarations } 
    end; 

var 
    Form5: TForm5; 

implementation 

uses Math; 

{$R *.dfm} 

const RADIUS = 16; 

function RealPoint(X, Y: real): TVector; 
begin 
    result.X := X; 
    result.Y := Y; 
end; 

function RoundPoint(P: TVector): TPoint; 
begin 
    result.X := round(P.X); 
    result.Y := round(P.Y); 
end; 

procedure TForm5.FormCreate(Sender: TObject); 
var 
    DX, DY: real; 
begin 
    FPosA := RealPoint(32, 32); 
    FPosB := RealPoint(500, 200); 

    DX := FPosB.X - FPosA.X; 
    DY := FPosB.Y - FPosA.Y; 

    v.X := DX/100; 
    v.Y := DY/100; 
end; 

function EllipseRectFromPoint(P: TVector): TRect; 
var 
    ScreenPoint: TPoint; 
begin 
    ScreenPoint := RoundPoint(P); 
    result.Left := ScreenPoint.X - RADIUS; 
    result.Right := ScreenPoint.X + RADIUS; 
    result.Top := ScreenPoint.Y - RADIUS; 
    result.Bottom := ScreenPoint.Y + RADIUS; 
end; 

procedure TForm5.FormPaint(Sender: TObject); 
begin 

    // Draw ball A 
    Canvas.Brush.Color := clSkyBlue; 
    Canvas.Ellipse(EllipseRectFromPoint(FPosA)); 

    // Draw ball B 
    Canvas.Brush.Color := clMoneyGreen; 
    Canvas.Ellipse(EllipseRectFromPoint(FPosB)); 

end; 

procedure TForm5.Timer1Timer(Sender: TObject); 
begin 
    FPosA.X := FPosA.X + V.X; 
    FPosA.Y := FPosA.Y + V.Y; 
    Invalidate; 

    if Hypot(FPosA.X - FPosB.X, FPosA.Y - FPosB.Y) < 0.1 then 
    begin 
    Timer1.Enabled := false; 
    ShowMessage('We''re there!'); 
    end; 
end; 

end. 

두 공 :

unit Unit5; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ExtCtrls; 

type 
    TVector = record 
    X, Y: real; 
    end; 

    TForm5 = class(TForm) 
    Timer1: TTimer; 
    procedure FormPaint(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
    procedure Timer1Timer(Sender: TObject); 
    private 
    { Private declarations } 
    AreWeThereYetA, AreWeThereYetB: boolean; 
    FPosA, FPosB, FPosC: TVector; 
    vA, vB: TVector; 
    public 
    { Public declarations } 
    end; 

var 
    Form5: TForm5; 

implementation 

uses Math; 

{$R *.dfm} 

const RADIUS = 16; 

function RealPoint(X, Y: real): TVector; 
begin 
    result.X := X; 
    result.Y := Y; 
end; 

function RoundPoint(P: TVector): TPoint; 
begin 
    result.X := round(P.X); 
    result.Y := round(P.Y); 
end; 

procedure TForm5.FormCreate(Sender: TObject); 
var 
    DX, DY: real; 
begin 
    FPosA := RealPoint(32, 32); 
    FPosB := RealPoint(132, 32); 
    FPosC := RealPoint(500, 200); 

    DX := FPosC.X - FPosA.X; 
    DY := FPosC.Y - FPosA.Y; 
    vA.X := DX/100; 
    vA.Y := DY/100; 

    DX := FPosC.X - FPosB.X; 
    DY := FPosC.Y - FPosB.Y; 
    vB.X := DX/200; 
    vB.Y := DY/200; 

end; 

function EllipseRectFromPoint(P: TVector): TRect; 
var 
    ScreenPoint: TPoint; 
begin 
    ScreenPoint := RoundPoint(P); 
    result.Left := ScreenPoint.X - RADIUS; 
    result.Right := ScreenPoint.X + RADIUS; 
    result.Top := ScreenPoint.Y - RADIUS; 
    result.Bottom := ScreenPoint.Y + RADIUS; 
end; 

procedure TForm5.FormPaint(Sender: TObject); 
begin 

    // Draw ball A 
    Canvas.Brush.Color := clSkyBlue; 
    Canvas.Ellipse(EllipseRectFromPoint(FPosA)); 

    // Draw ball B 
    Canvas.Brush.Color := clMoneyGreen; 
    Canvas.Ellipse(EllipseRectFromPoint(FPosB)); 

    // Draw ball C 
    Canvas.Brush.Color := clRed; 
    Canvas.Ellipse(EllipseRectFromPoint(FPosC)); 

end; 

procedure TForm5.Timer1Timer(Sender: TObject); 
begin 

    if not AreWeThereYetA then 
    begin 
    FPosA.X := FPosA.X + VA.X; 
    FPosA.Y := FPosA.Y + VA.Y; 
    end; 

    if not AreWeThereYetB then 
    begin 
    FPosB.X := FPosB.X + VB.X; 
    FPosB.Y := FPosB.Y + VB.Y; 
    end; 

    Invalidate; 

    if Hypot(FPosA.X - FPosC.X, FPosA.Y - FPosC.Y) < 0.1 then 
    AreWeThereYetA := true; 

    if Hypot(FPosB.X - FPosC.X, FPosB.Y - FPosC.Y) < 0.1 then 
    AreWeThereYetB := true; 

    if AreWeThereYetA and AreWeThereYetB then 
    begin 
    Timer1.Enabled := false; 
    ShowMessage('We are there!'); 
    end; 
end; 

end. 

배열과 기록을 사용하여, 그것은 것 사용자 정의 속성 (색상, 반경 등)이있는 볼, 임의의 것들도 포함하여 N 볼로 일반화하기 쉽습니다. 또한 바운싱을 구현하는 것이 매우 쉽습니다. 또한, 실제 벡터 유형은 여기에서 좋을 것입니다.