DelphiX 是 Delphi 連結 DirectX 最早、最成熟的封裝庫(2000 年首發),雖官方 2000/07/17 後停止更新,但社群持續維護支援至 Delphi 2009。本文記錄安裝步驟、常見問題修正與首個測試動畫。
建議環境:Delphi 2007(最穩定),同步驗證 Delphi 2009 相容性。
DelphiXcfg.inc,將倒數第二行 {.$Define D3DRM} 改為 {$Define D3DRM}(啟用 Direct3D Retained Mode 支援)。DelphiX.dpk,再編譯執行期套件 DelphiX_Runtime.dpk。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DXDraws, StdCtrls, DXClass;
type
TForm1 = class(TDXForm) { 繼承 TDXForm 可自動處理 DirectX 初始化/釋放 }
DXDraw1: TDXDraw;
DXTimer1: TDXTimer;
DXImageList1: TDXImageList;
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure DXDraw1Initialize(Sender: TObject);
procedure DXDraw1Finalize(Sender: TObject);
procedure DXTimer1Timer(Sender: TObject; LagCount: Integer);
private
procedure CalculateTables;
procedure PlotPoint(XCenter, YCenter, Radius, Angle: Word);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
SineMove, CosineMove: array[0..255] of Integer;
SineTable: array[0..449] of Integer;
CenterX, CenterY: Integer;
x, y: Word = 0;
procedure TForm1.CalculateTables;
var
wCount: Word;
begin
for wCount := 0 to 255 do
begin
SineMove[wCount] := Round(Sin(Pi * wCount / 128) * 45);
CosineMove[wCount] := Round(Cos(Pi * wCount / 128) * 60);
end;
for wCount := 0 to 449 do
SineTable[wCount] := Round(Sin(Pi * wCount / 180) * 128);
end;
procedure TForm1.PlotPoint(XCenter, YCenter, Radius, Angle: Word);
var
a, b: Word;
begin
a := (Radius * SineTable[90 + Angle]);
asm sar a, 7 end; { 等同 a := a div 128 }
a := CenterX + XCenter + a;
b := (Radius * SineTable[Angle]);
asm sar b, 7 end;
b := CenterY + YCenter + b;
if (a < Width) and (b < Height) then
DXImageList1.Items[0].Draw(DXDraw1.Surface, a, b, 0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DXDraw1.Align := alClient;
CenterX := Width div 2;
CenterY := Height div 2;
CalculateTables;
end;
procedure TForm1.DXDraw1Finalize(Sender: TObject);
begin
DXTimer1.Enabled := False;
end;
procedure TForm1.DXDraw1Initialize(Sender: TObject);
begin
DXTimer1.Enabled := True;
end;
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
const
IncAngle = 12;
XMove = 7;
YMove = 8;
var
CountAngle, CountLong, IncLong: Word;
begin
if not DXDraw1.CanDraw then Exit;
IncLong := 2;
CountLong := 20;
DXDraw1.Surface.Fill(0);
repeat
CountAngle := 0;
repeat
PlotPoint(
CosineMove[(x + (200 - CountLong)) mod 255],
SineMove[(y + (200 - CountLong)) mod 255],
CountLong, CountAngle);
Inc(CountAngle, IncAngle);
until CountAngle >= 360;
Inc(CountLong, IncLong);
if (CountLong mod 3) = 0 then Inc(IncLong);
until CountLong >= 270;
x := (XMove + x) mod 255;
y := (YMove + y) mod 255;
with DXDraw1.Surface.Canvas do
begin
Brush.Style := bsClear;
Font.Color := clWhite;
Font.Size := 12;
TextOut(0, 0, 'FPS: ' + IntToStr(DXTimer1.FrameRate));
Release;
end;
DXDraw1.Flip;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if Key = VK_ESCAPE then Close;
end;
end.
設計時透過 DXImageList1.Items 編輯器匯入圖片,DFM 會自動以十六進位儲存 Picture.Data 與 ColorTable,無需外部檔案即可執行。
DXClass、DXDraws 在 uses 子句中。TDXDraw.Options 中取消 doHardware 改用軟體模擬。DXDraw1.Flip 在每幀結束呼叫,且 Surface.Fill 清除背景。完成安裝與首個動畫測試,代表 DelphiX 環境已就緒。後續將依序介紹 TDXDraw、TDXTimer、TDXImageList、TDXSpriteEngine 等核心元件,帶領你打造完整 2D 遊戲。