삼각형 모양이 필요하므로 삼각형 클래스 TShape 형식을 상속하고 페인트 방법을 재정의했습니다. 모든 것이 잘 작동하지만 마우스로이 모양을 옮겨야합니다. onMouseDown 이벤트를 처리하는 모든 도형에 대해 메서드를 설정했습니다. 움직이는 것도 좋습니다. 그러나 두 모양이 겹치는 경우 (모양이 실제로 일부 투명 영역이있는 사각형 임), 위쪽 모양 투명 영역이 다른 모양보다 위에 있으면 위쪽 모양이 아래 모양 대신 움직입니다. 델파이가 어떻게 작동하는지는 정확합니다. 그러나 사용자에게는 직관적이지 않습니다. 어떻게하면 될까요? 이벤트 대기열에서 이벤트를 제거하지 않고 기본 모양으로 보낸 가능성이 있습니까? 그렇다면 간단할까요?델파이 - 겹치는 TShapes 이동
6
A
답변
0
모양 이동을 시작하기 전에 마우스 클릭이 삼각형 영역 내에 있는지 테스트합니다. 즉 약간의 수학이 필요하지만, 다음과 같이 당신은 또한, 임시 영역을 작성하여 WinAPI를 PtInRegion 기능을 악용 할 수 있습니다 : 내 댓글 당
function PtInPolygon(const Pt: TPoint; const Points: array of TPoint): Boolean;
var
Region: HRGN;
begin
Region := CreatePolygonRgn(Points[0], Length(Points), WINDING);
try
Result := PtInRegion(Region, Pt.X, Pt.Y);
finally
DeleteObject(Region);
end;
end;
procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
StartMove: Boolean;
begin
StartMove := PtInPolygon(Point(X, Y), [Point(100, 0), Point(200, 200),
Point(0, 200)]);
...
9
A '간단한 샘플 재 설계'는 다음과 같습니다.
unit Unit4;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
const
NUM_TRIANGLES = 10;
COLORS: array[0..12] of integer = (clRed, clGreen, clBlue, clYellow, clFuchsia,
clLime, clGray, clSilver, clBlack, clMaroon, clNavy, clSkyBlue, clMoneyGreen);
type
TTriangle = record
X, Y: integer; // bottom-left corner
Base, Height: integer;
Color: TColor;
end;
TTriangles = array[0..NUM_TRIANGLES - 1] of TTriangle;
TForm4 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
FTriangles: TTriangles;
FDragOffset: TPoint;
FTriangleActive: boolean;
function GetTriangleAt(AX, AY: Integer): Integer;
function IsMouseDown: boolean;
public
{ Public declarations }
end;
var
Form4: TForm4;
implementation
uses Math;
{$R *.dfm}
procedure TForm4.FormCreate(Sender: TObject);
var
i: Integer;
begin
FTriangleActive := false;
Randomize;
for i := 0 to NUM_TRIANGLES - 1 do
with FTriangles[i] do
begin
base := 40 + Random(80);
height := 40 + Random(40);
X := Random(ClientWidth - base);
Y := height + Random(ClientHeight - height);
Color := RandomFrom(COLORS);
end;
end;
procedure TForm4.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
TriangleIndex: integer;
TempTriangle: TTriangle;
i: Integer;
begin
TriangleIndex := GetTriangleAt(X, Y);
if TriangleIndex <> -1 then
begin
FDragOffset.X := X - FTriangles[TriangleIndex].X;
FDragOffset.Y := Y - FTriangles[TriangleIndex].Y;
TempTriangle := FTriangles[TriangleIndex];
for i := TriangleIndex to NUM_TRIANGLES - 2 do
FTriangles[i] := FTriangles[i + 1];
FTriangles[NUM_TRIANGLES - 1] := TempTriangle;
Invalidate;
end;
FTriangleActive := TriangleIndex <> -1;
end;
function TForm4.IsMouseDown: boolean;
begin
result := GetKeyState(VK_LBUTTON) and $8000 <> 0;
end;
procedure TForm4.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if IsMouseDown and FTriangleActive then
begin
FTriangles[high(FTriangles)].X := X - FDragOffset.X;
FTriangles[high(FTriangles)].Y := Y - FDragOffset.Y;
Invalidate;
end;
end;
procedure TForm4.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FTriangleActive := false;
end;
procedure TForm4.FormPaint(Sender: TObject);
var
i: Integer;
Vertices: array of TPoint;
begin
SetLength(Vertices, 3);
for i := 0 to NUM_TRIANGLES - 1 do
with FTriangles[i] do
begin
Canvas.Brush.Color := Color;
Vertices[0] := Point(X, Y);
Vertices[1] := Point(X + Base, Y);
Vertices[2] := Point(X + Base div 2, Y - Height);
Canvas.Polygon(Vertices);
end;
end;
function TForm4.GetTriangleAt(AX, AY: Integer): Integer;
var
i: Integer;
begin
result := -1;
for i := NUM_TRIANGLES - 1 downto 0 do
with FTriangles[i] do
if InRange(AY, Y - Height, Y) and
InRange(AX, round(X + (Base/2) * (Y - AY)/Height),
round(X + Base - (Base/2) * (Y - AY)/Height)) then
Exit(i);
end;
end.
설정하는 것을 잊지 마세요 형태의
DoubleBuffered
true
합니다.
컴파일 샘플 데모 : http://privat.rejbrand.se/MovingTriangles.exe
+0
이 답변을 게시 한 이후로 오랜 시간이 걸렸으나 'AX'분/최대 계산에 대해 'InRange'를 설명 할 수 있습니까? 그 종류의 불면 내 마음, 나는 수학이나 기하학을 오랫동안 생각 havent. 더 많이 응시 한 후에 나는 내가 이해하기 시작했다고 생각한다. 'Y-AY'(작은 삼각형 높이)를 '높이'로 나누면 주어진 'AY'를 사용하여 잠재적 인 작은 삼각형 '기본'의 절반을 축소 할 수 있습니까? 그러나 양면에서 절단하는 것이 'X'가 그 범위에 있다는 것을 어떻게 알 수 있습니까? 나는 약간의 그림을 그렸고 그것은 사실이며 지금은 그것을 볼 수 있지만 프로그래밍 방식으로 완료했을 때 분명하지는 않습니다. – Raith
관련 문제
- 1. 델파이 대 CopyMemory 이동
- 2. 델파이 : VSS에서 멀리 이동
- 3. 델파이 디버깅에서 프로그램 카운터 이동
- 4. 델파이 : 창 이동 시작과 끝 감지
- 5. 델파이 -
- 6. 겹치는 System.Drawing.Graphics가
- 7. 델파이 2009와 델파이 2010
- 8. 델파이 2010 : 델파이
- 9. 델파이 : 커서 이동 외에도 TClientDataset의 레코드에 액세스하는 방법이 있습니까
- 10. 델파이 :
- 11. 델파이 :
- 12. 두 객체가 겹치는 패턴
- 13. 청사진 CSS 겹치는 div
- 14. 겹치는 개체 - 도움말
- 15. IE7에서 겹치는 열
- 16. 자바 ScrollPane 겹치는 내용
- 17. 겹치는 세포-내용이
- 18. 스윙 겹치는 구성 요소
- 19. HTML div와 겹치는 플래시
- 20. html5 캔버스에서 겹치는 폴리곤
- 21. 시간이 겹치는 행 삭제
- 22. 겹치는 divs, 절대적으로 상대적입니까?
- 23. 겹치는 시간 범위 찾기
- 24. 겹치는 div가있는 앵커
- 25. 서로 겹치는 MySQL 쿼리
- 26. 규칙이 겹치는 문제
- 27. 헌장 기능은 델파이 코드에서 델파이
- 28. 델파이 2006와 함께 델파이 2010
- 29. 델파이 진동 진행 막대
- 30. 디자인 모드에서 겹치는 패널 숨기기
폼에 컨트롤 (심지어 그래픽 컨트롤) 이동 애니메이션을 그리기 나쁘다. 내가 너라면, 사용자 지정 데이터 구조에 장면을 저장 한 다음 양식을 완전히 수동으로 그릴 것입니다. 그렇다면 아무런 제약이 없습니다. 원하는 마우스 인터페이스를 구현할 수 있습니다. –