FireMonkey 框架為 Delphi 開發者提供了強大的圖形和動畫功能,本文將逐步講解如何運用這些功能開發更具互動性的應用程式。首先,利用類別輔助方法可以簡化繪圖程式碼,提高程式碼的可讀性和維護性。接著,使用 TTimer 元件可以實作基本的動畫效果,而對於需要更高精確度的計時,則可以選擇 TStopwatch。FireMonkey 的父子關係設計簡化了 UI 佈局,形狀元件則提供了豐富的繪圖元素,方便開發者快速構建視覺化介面。此外,動畫元件的屬性設定和插值調整,可以更精細地控制動畫效果。最後,透過處理觸控事件和手勢,可以讓應用程式更具互動性,提升使用者經驗。
FireMonkey 圖形繪製與動畫實作
在 Delphi 的 FireMonkey 框架中,圖形繪製和動畫實作是非常重要的功能。本文將探討如何使用 FireMonkey 進行圖形繪製和動畫實作,並提供詳細的程式碼範例和解析。
使用類別輔助方法簡化繪圖程式碼
首先,我們可以透過建立類別輔助方法(Class Helper)來簡化 FireMonkey 中的繪圖程式碼。以下是一個範例:
TFmxCanvasHelper = class helper for TCanvas
public
procedure SolidRect(ARect: TRectF; AColor: TColor);
procedure Line(A, B: TPointF; AColor: TColor; AThickness: Single);
procedure SolidCircle(A: TPointF; R: Double; AColor: TColor);
end;
procedure TFmxCanvasHelper.SolidRect(ARect: TRectF; AColor: TColor);
begin
Fill.Color := AColor;
FillRect(ARect, 0, 0, [], DEFAULT_OPACITY);
end;
procedure TFmxCanvasHelper.Line(A, B: TPointF; AColor: TColor; AThickness: Single);
begin
Stroke.Color := AColor;
Stroke.Kind := TBrushKind.bkSolid;
Stroke.Thickness := AThickness;
DrawLine(A, B, DEFAULT_OPACITY);
end;
procedure TFmxCanvasHelper.SolidCircle(A: TPointF; R: Double; AColor: TColor);
begin
var ARect := RectF(A.X-R, A.Y-R, A.X+R, A.Y+R);
Fill.Color := AColor;
Fill.Kind := TBrushKind.Solid;
FillEllipse(ARect, DEFAULT_OPACITY);
end;
程式碼解析:
SolidRect方法用於繪製一個實心矩形。Line方法用於繪製一條直線。SolidCircle方法用於繪製一個實心圓。
這些方法簡化了在 FireMonkey 中進行基本圖形繪製的程式碼,使得開發者可以更輕鬆地建立複雜的圖形效果。
使用 TTimer 元件實作動畫效果
為了實作動畫效果,我們可以使用 TTimer 元件。以下是一個範例,展示瞭如何使用 TTimer 元件來模擬日出效果:
TFormSunCodeAnim = class(TForm)
PaintBox1: TPaintBox;
Timer1: TTimer;
procedure PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
FSunPosY: Double;
end;
procedure TFormSunCodeAnim.FormCreate(Sender: TObject);
begin
FSunPosY := self.Height + 150;
end;
procedure TFormSunCodeAnim.Timer1Timer(Sender: TObject);
begin
if FSunPosY > END_SUN_POS_Y then
FSunPosY := FSunPosY - 10;
Invalidate;
end;
procedure TFormSunCodeAnim.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.BeginScene;
try
Canvas.SolidRect(PaintBox1.BoundsRect, TAlphaColorRec.Skyblue);
var X := POS_X;
var Y := FSunPosY;
Canvas.SolidCircle(PointF(X, Y), SUN_RADIUS, TAlphaColorRec.Yellow);
for var I := 0 to RAY_COUNT-1 do
begin
var Angle := I * Pi * 2 / RAY_COUNT;
var A := PointF(X, Y);
var B := PointF(x + RAY_LENGTH * Cos(Angle), y + RAY_LENGTH * Sin(Angle));
Canvas.Line(A, B, TAlphaColorRec.Yellow, 5);
end;
finally
Canvas.EndScene;
end;
end;
程式碼解析:
FormCreate事件初始化太陽的初始位置。Timer1Timer事件處理程式更新太陽的位置並使畫布無效以觸發重繪。PaintBox1Paint事件處理程式根據當前太陽的位置繪製天空、太陽和太陽的光芒。
精確計時與動畫控制
雖然 TTimer 元件可以滿足大部分的動畫需求,但在某些需要精確計時的場合,例如物理引擎模擬,我們需要使用更精確的計時方法。TStopwatch 是 Delphi 提供的一個用於精確計時的結構。以下是一個範例:
TFormTiming = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
FLastTime: Double;
end;
procedure TFormTiming.FormCreate(Sender: TObject);
begin
TStopwatch.StartNew;
Log('Stopwatch Frequency = ' + TStopwatch.Frequency.ToString);
end;
function TFormTiming.GetRawReferenceTime: Double;
begin
Result := TStopwatch.GetTimeStamp / TStopwatch.Frequency;
end;
procedure TFormTiming.Timer1Timer(Sender: TObject);
var
T, Elapsed: Double;
begin
T := GetRawReferenceTime;
Elapsed := T - FLastTime;
FLastTime := T;
Log('T=' + T.ToString + ' Elapsed=' + Elapsed.ToString);
end;
程式碼解析:
GetRawReferenceTime方法傳回自TStopwatch開始以來經過的時間(以秒為單位)。Timer1Timer事件處理程式計算每次觸發之間的時間間隔,並記錄下來。
透過使用 TStopwatch,我們可以獲得比 TTimer 更精確的時間控制,從而滿足對時間敏感的應用需求。
使用FireMonkey進行精確計時與視覺化設計
精確計時範例解析
在開發高效能應用程式時,精確的計時功能至關重要。透過FireMonkey框架,我們可以輕鬆實作毫秒級的計時精確度。即使在一個幾乎空的應用程式中,計時器的準確度也可以達到幾毫秒。在更複雜的應用程式中,差異可能會更大。
FireMonkey的父子關係威力
FireMonkey的架構設計中,父子關係(Parenting)是一個非常強大的特性。任何FireMonkey元件都可以包含其他元件,這種包含關係使得子元件繼承父元件的屬性,如位置、縮放比例和旋轉角度。這種特性為建立複雜的使用者介面提供了極大的靈活性,因為我們可以建立組合控制項而無需宣告全新的類別。
使用形狀元件進行繪圖
FireMonkey提供了豐富的形狀(Shape)元件,如直線、圓形、橢圓、矩形等,這些元件封裝了畫布上的繪圖功能,大大減少了低階繪圖程式碼的撰寫。
重建太陽視覺化範例
- 新增一個Form HD元素到專案中。
- 放置一個TRectangle元件在表單上,並將其與客戶區域對齊。將其
Name屬性設為RectSky,並將其Fill.Color設為天空藍色。 - 放置一個TCircle元件在表單上,命名為
CircleSun。調整其Width和Height屬性為100,將其位置設在畫面的左上角。 - 變更
CircleSun的Fill.Color和Stroke.Color為黃色。
新增太陽光芒
- 選取太陽的圓形元件,然後在其上放置一個TLine元件,命名為
LineRay01。 - 設定
LineRay01的LineType為Top,使其成為水平線。調整其Width、Height、Stroke.Color和Thickness屬性。 - 確保TLine元件是TCircle的子元件,這樣其屬性會相對於父元件。
旋轉太陽光芒
- 複製
LineRay01並貼上到CircleSun下,調整新線條的RotationAngle屬性以實作旋轉效果。 - 變更
RotationCenter屬性以控制旋轉中心。 - 重複此過程以建立多條太陽光芒,最終實作具有12條光芒的太陽視覺效果。
動畫設計
FireMonkey提供了強大的動畫元件,可以輕鬆實作屬性的動態變更。無需撰寫計時器相關程式碼,即可實作背景執行緒中的動畫效果。
新增動畫至太陽圓形元件
- 在Object Inspector中展開
CircleSun的Position.Y屬性。 - 選擇「Create New TFloatAnimation」以建立一個新的浮點數動畫元件。
- 這樣就實作了對
CircleSun位置的動態變更,從而實作了太陽升起的動畫效果。
程式碼解析
// 無需手動撰寫動畫相關程式碼,FireMonkey的視覺化設計工具已經處理了大部分工作。
// 以下是一個簡單的範例,展示如何以程式設計方式控制動畫:
// 假設FloatAnimation1是繫結到CircleSun的Position.Y屬性的動畫元件
FloatAnimation1.StartValue := 200; // 起始值
FloatAnimation1.StopValue := 50; // 結束值
FloatAnimation1.Duration := 5; // 動畫持續時間(秒)
FloatAnimation1.Start; // 啟動動畫
內容解密:
FloatAnimation1.StartValue和StopValue定義了動畫的起始和結束值。Duration屬性控制動畫的持續時間。Start方法用於啟動動畫。
強化 FireMonkey 應用程式的互動性
FireMonkey 為開發者提供了豐富的工具和元件,讓我們能夠輕鬆建立動態且互動性強的應用程式。在本章中,我們將探討如何利用 FireMonkey 的動畫元件和觸控事件,來創造更具吸引力和使用者友好的應用程式。
使用動畫元件
動畫是提升應用程式視覺吸引力的關鍵元素。FireMonkey 提供了 TFloatAnimation 這樣的動畫元件,讓我們能夠輕鬆地為應用程式新增動畫效果。讓我們透過一個簡單的例子來瞭解如何使用動畫元件。
設定動畫屬性
在設計階段,我們可以使用 Object Inspector 來設定動畫元件的屬性。例如,對於一個 TFloatAnimation 元件,我們可以設定其 Duration、Enabled、StopValue 和 StartValue 等屬性。
- 將
Duration設定為 2 秒,控制動畫的播放時間。 - 將
Enabled設定為 True,使動畫在應用程式啟動時自動開始。 - 設定
StopValue為 100 和StartValue為 600,定義動畫的起始和結束值。
我們也可以在程式碼中動態設定 StartValue,以適應不同的螢幕高度。例如:
procedure TFormSunCompAnim.FormCreate(Sender: TObject);
begin
FloatAnimation1.StartValue := RectSky.Height + 150;
end;
調整插值方式
動畫的插值方式(Interpolation)決定了動畫值的變化方式。預設情況下,TFloatAnimation 使用線性插值(Linear)。我們可以將其更改為正弦插值(Sinusoidal),以獲得更自然的動畫效果。
處理觸控事件
FireMonkey 表單支援處理簡單觸控、多點觸控和手勢事件。這些功能使我們能夠建立更具互動性的應用程式。
觸控事件處理
在 FireMonkey 中,表單和控制元件都支援觸控事件。當使用者觸控螢幕時,會觸發 OnMouseDown 事件;當觸控點改變或結束時,分別會觸發 OnMouseMove 和 OnMouseUp 事件。
讓我們透過修改 Sun 應用程式來示範如何處理觸控事件,以允許使用者改變太陽的位置。
- 宣告必要的欄位:在表單類別中宣告私有欄位
FReady、FDown和FMoving,以追蹤太陽的移動狀態和初始觸控點。
type
TFormSunMove = class(TForm)
// ...
private
FReady: Boolean;
FDown: TPointF;
FMoving: Boolean;
end;
- 初始化和完成事件:在
OnCreate事件中初始化FReady為 False,並在動畫的OnFinish事件中將其設定為 True,以確保使用者只能在動畫完成後移動太陽。
procedure TFormSunMove.FormCreate(Sender: TObject);
begin
FReady := False;
FloatAnimation1.StartValue := RectSky.Height + 150;
end;
procedure TFormSunMove.FloatAnimation1Finish(Sender: TObject);
begin
FReady := True;
end;
- 處理滑鼠事件:實作
OnMouseDown和OnMouseUp事件,以控制太陽的移動。
procedure TFormSunMove.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
if FReady then
begin
FDown := PointF(X, Y);
FMoving := True;
end;
end;
procedure TFormSunMove.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
if FMoving then
begin
CircleSun.Position.X := CircleSun.Position.X + (X - FDown.X);
CircleSun.Position.Y := CircleSun.Position.Y + (Y - FDown.Y);
FMoving := False;
end;
end;
圖表翻譯:
此圖示描述瞭如何在 Object Inspector 中設定互動式手勢。 此圖示呈現了在 FireMonkey 中設定旋轉手勢的過程,使用者可以透過這個手勢對應用程式中的物件進行旋轉操作。
使用手勢
FireMonkey 支援處理標準和互動式手勢。讓我們為 Sun 演示應用程式新增旋轉手勢支援。
啟用旋轉手勢:在 Object Inspector 中選擇表單,並展開其 Touch 屬性。勾選 Rotate 手勢下的 Interactive Gestures 子屬性。
處理手勢事件:雙擊表單的
OnGesture事件,並實作事件處理函式,以回應旋轉手勢。
// OnGesture 事件處理範例
procedure TFormSunMove.FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
// 處理旋轉手勢
if EventInfo.GestureID = igiRotate then
begin
// 在此新增旋轉邏輯
end;
end;
圖表翻譯:
此圖示顯示瞭如何在 FireMonkey 中組態互動式手勢。 透過此圖示,使用者可以瞭解如何為應用程式新增旋轉手勢,從而實作更豐富的互動體驗。