首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

DelphiX 教學 (16):DXImageList1.Items.Find 依名稱快速檢索圖片項目

     編輯:Delphi

在管理大量遊戲圖片資源時,透過索引存取 DXImageList1.Items 不夠直觀且難以維護。Find 方法支援依**名稱字串**快速檢索 TPictureCollectionItem,大幅提升程式碼可讀性與維護性。本文示範建立命名圖片集合與依名稱繪製的完整流程。

核心概念

  • DXImageList1.Items 是 TPictureCollection 集合,每個項目為 TPictureCollectionItem。
  • 每個項目可設定 Name 屬性 (字串),作為唯一識別碼。
  • Find(const Name: string): TPictureCollectionItem 回傳第一個符合名稱的項目,找不到回傳 nil。
  • 名稱比較**不分大小寫**。

完整範例程式碼

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    DXDraw1: TDXDraw;
    DXImageList1: TDXImageList;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  ImgPath1 = 'C:\Temp\DelphiX.bmp';
  ImgPath2 = 'C:\Temp\DelphiX.jpg';
begin
  DXImageList1.DXDraw := DXDraw1;
  
  { 建立第一個項目並命名為 'img1' }
  DXImageList1.Items.Add;
  DXImageList1.Items[DXImageList1.Items.Count - 1].Picture.LoadFromFile(ImgPath1);
  DXImageList1.Items[DXImageList1.Items.Count - 1].Name := 'img1';
  
  { 建立第二個項目並命名為 'img2' }
  DXImageList1.Items.Add;
  DXImageList1.Items[DXImageList1.Items.Count - 1].Picture.LoadFromFile(ImgPath2);
  DXImageList1.Items[DXImageList1.Items.Count - 1].Name := 'img2';
  
  { 設計時亦可在物件檢視器中直接設定 Items 集合與 Name 屬性 }
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TPictureCollectionItem;
begin
  DXDraw1.Surface.Fill(0);
  Item := DXImageList1.Items.Find('img1');
  if Assigned(Item) then
    Item.Draw(DXDraw1.Surface, 0, 0, 0);
  DXDraw1.Flip;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TPictureCollectionItem;
begin
  DXDraw1.Surface.Fill(0);
  Item := DXImageList1.Items.Find('img2');
  if Assigned(Item) then
    Item.Draw(DXDraw1.Surface, 0, 0, 0);
  DXDraw1.Flip;
end;

end.

執行效果

按鈕點擊分別繪製名為 img1 和 img2 的圖片

進階應用模式

  1. 資源管理器封裝:
    type
      TResourceManager = class
      private
        FImageList: TDXImageList;
      public
        function GetImage(const Name: string): TPictureCollectionItem;
        procedure DrawImage(const Name: string; Surface: TDirectDrawSurface; X, Y: Integer);
      end;
    
    function TResourceManager.GetImage(const Name: string): TPictureCollectionItem;
    begin
      Result := FImageList.Items.Find(Name);
      if not Assigned(Result) then
        raise Exception.CreateFmt('找不到圖片資源: %s', [Name]);
    end;
    
  2. 命名規範建議:
    • 前綴分類:'player_idle', 'enemy_boss', 'ui_btn_ok'
    • 版本控制:'tileset_v1_grass', 'tileset_v2_grass'
    • 避免特殊字元,僅使用英數字與底線。
  3. 動態載入與快取:
    procedure LoadResources(const List: TStringList);
    var
      i: Integer;
      Item: TPictureCollectionItem;
    begin
      for i := 0 to List.Count - 1 do
      begin
        Item := TPictureCollectionItem(DXImageList1.Items.Add);
        Item.Name := List.Names[i];  // 從 Ini/JSON 讀取名稱
        Item.Picture.LoadFromFile(List.ValueFromIndex[i]);
      end;
    end;
    

效能與注意事項

  • 線性搜尋:Find 內部為線性遍歷,項目超過百個時建議自行建立 TDictionary 快取。
  • 重名風險:若有重名項目,Find 僅回傳第一個,建議命名唯一。
  • 設計時 vs 執行時:設計時在物件檢視器編輯 Items 集合更直觀,執行時動態建立適合模組化載入。
  • 釋放管理:DXImageList1.Clear 會釋放所有項目,搭配 FreeAndNil 管理元件生命週期。

實務開發建議

將 Find 封裝在資源管理類別中,統一處理錯誤檢查、快取、延遲載入等邏輯,避免在遊戲主迴圈中直接呼叫 Find 造成效能抖動。建議在場景載入階段預先解析所需資源參考存入陣列/字典,執行期直接使用參考繪製。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved