2017-11-06 7 views
-2

これがあまりにも漠然としているのかどうかはわかりませんが(これは私の初めてのことですが)、ユーザーが制御しているシェイプがフォーム上の別のシェイプを通過しないようにする方法を考えようとしています。これまでは、可動シェイプに他のシェイプにヒットしたときにメッセージを表示させるようにしましたが、ユーザーのシェイプが他の固定シェイプを通過できず、ヒットしたときの移動方向に移動しないように変更したいと思いますオブジェクト。私はいくつかの助けか可能な解決に感謝します、ありがとう。私はあなたが簡単に2つの長方形が互いに交差しているかどうかを確認することができます可能な方法をIntersectRect使用をお勧めします2つの形状/矩形間の衝突検出を行う場合デルファイを使用してフォーム上の別のシェイプを通過するシェイプを防ぐ方法を教えてください。

コードは、これまでのところ、ここで

procedure TfrmMazeDesign1.Timer1Timer(Sender: TObject); 
begin 

    case direction of 
    1: 
     ShpUser.Top := ShpUser.Top - 1; 

    2: 
     ShpUser.Top := ShpUser.Top + 1; 

    3: 
     ShpUser.Left := ShpUser.Left - 1; 

    4: 
     ShpUser.Left := ShpUser.Left + 1; 

end; 

    if ShpUser.Left + ShpUser.Width = Shape1.Left then 

    showmessage('hitbar'); 

    if ShpUser.Left = Shape1.Left + Shape1.Width then 

    showmessage('hitbar'); 

end; 
+0

WITHこの作業を行うために管理私は、実際の形状は、私と考えています重要。円、長方形?あなたの質問にそれを必ず追加してください。 – nil

+1

はい、あまりにも曖昧です。我々は合理的な推測を行うための適切な文脈を持っていない。あなたのサンプルコードは、衝突検出がまだ解明されていないことを示唆しています。あなたの質問は、衝突が検出されたときに何をすべきかを尋ねることです。あなたはまだあなたが望むものを知っているようにも見えません。あなたは "ユーザーの形"を参照しますが、ユーザーがそれをどのように制御しているかを示すことさえありません。 _Message boxes_は、間違いなく、ダイアログがオブジェクトのユーザーコントロールを何とか壊してしまう最悪のUIです。 –

+0

私はあなたが面白いと思う挑戦を乗り越えるためにあなたの努力を拍手喝采します。しかし、率直に言って、それはあなたの現在の能力を超えて過度に行き渡っているようです。あなたのコードから、あなたのユーザが衝突するかもしれない画面上の他のすべての図形をどのように追跡するかについての計画をまだ作っていないことは明らかです。この挑戦に再訪する前に_データ構造について学ぶ時間を取ってください。 –

答えて

1

です。

次のことは、2つの長方形間の衝突を検出すると、移動する矩形を衝突前の位置に戻す必要があることです。
例では、矩形を1ピクセル移動しています。つまり、検出された衝突の場合は、1ピクセルだけ反対方向に移動します。そのため、最後の移動方向に関する情報を手元に用意するために、ケースステートメント内の衝突をチェックすることができます。
複数のピクセルでシェイプを移動する場合は、移動シェイプを移動して他のシェイプにちょうど接触するようにしてください。

ここでは、このソリューションのコード例を示しますより良い理解のためのコメント:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; 
    Shift: TShiftState); 
var IntersectionRect: TRect; 
begin 
    case Key of 
    VK_Left: 
    begin 
     //Move shape into new position 
     Shape1.Left := Shape1.Left - 1; 
     //Check for intersection of the shape rectangle against other shape rectangle 
     //First parameter which needs to be of variable type us used by function to return 
     //the dimensions of overlaping area/rectangle of the two provided rectangles 
     if IntersectRect(IntersectionRect, Shape1.BoundsRect, Shape2.BoundsRect) then 
     begin 
     showmessage('left side collision'); 
     //After detecting collision move shape back to previous possition 
     //If you are moving your shapes by more than one pixel you might want to 
     //reposition your so that it positioned just to the right of the other shape 
     //Shape1.Left := Shape2.Left + Shape2.Width + 1; 
     Shape1.Left := Shape1.Left + 1; 
     end; 
    end; 
    VK_Right: 
    begin 
     Shape1.Left := Shape1.Left + 1; 
     if IntersectRect(IntersectionRect, Shape1.BoundsRect, Shape2.BoundsRect) then 
     begin 
     showmessage('right side collision'); 
     Shape1.Left := Shape1.Left - 1; 
     end; 
    end; 
    VK_Up: 
    begin 
     Shape1.Top := Shape1.Top - 1; 
     if IntersectRect(IntersectionRect, Shape1.BoundsRect, Shape2.BoundsRect) then 
     begin 
     showmessage('tops side collision'); 
     Shape1.Top := Shape1.Top + 1; 
     end; 
    end; 
    VK_Down: 
    begin 
     Shape1.Top := Shape1.Top + 1; 
     if IntersectRect(IntersectionRect, Shape1.BoundsRect, Shape2.BoundsRect) then 
     begin 
     showmessage('bottom side collision'); 
     Shape1.Top := Shape1.Top - 1; 
     end; 
    end; 
    end; 
end; 
0

UPDATEが衝突検出のためにGRID

procedure TfrmMazeDesign.Timer1Timer(Sender: TObject); 

var IntersectionRect: TRect; 

collision, test_collision : boolean; 

up : boolean; 

right : boolean; 

frmMazeDesign: TfrmMazeDesign; 

    counter: integer; 

begin 
    counter := 1; 
    repeat 
    collision := IntersectRect(IntersectionRect, ShpUser.BoundsRect, FShapes[counter].BoundsRect) ; 
    counter := counter + 1 ; 
    until (collision) or (counter >= 200); 



    case direction of 
    1:begin  //Up 
     if collision then 
      ShpUser.Top := ShpUser.Top + 1 
      else 
      ShpUser.Top := ShpUser.Top - 1; 
     end; 
    2: begin  //down 
     if collision then 
      ShpUser.Top := ShpUser.Top - 1 
      else 
      ShpUser.Top := ShpUser.Top + 1; 
     end; 

    3: begin  //left 
     if collision then 
      ShpUser.Left := ShpUser.Left +1 
      else 
      ShpUser.Left := ShpUser.Left - 1; 
     end; 

    4: begin     //right 
     if collision then 
      ShpUser.Left := ShpUser.Left - 1 
      else 
      ShpUser.Left := ShpUser.Left + 1; 
     end; 


    end; 
    if collision then 
     direction := 0; 
end; 








end. 
関連する問題