之前我写过一篇《使用Asphyre开发游戏的方式 》的文章。文章中简述了如果使用asphyre3.10来开发游戏。但是使用asphyre3.10来开发游戏有一个很麻烦的问题——如何来实现VCL中按钮等等控件的效果。以前使用3.10的时候,我使用的方法是:定义出一个区域来,判断鼠标点击的是不是在这个区域,如果是那么做相应的操作。这样虽然也可以实现,但是其代码量和逻辑关系比较难以控制。很是麻烦。
最近使用Asphyre4.10SpriteEngine来开发游戏,觉得将这两个结合起来实现按钮效果非常方便。下面我就将如果实现这种效果写出来。
我使用的Asphyre版本是Asphyre4snapshot这个可以在火人的BLOG上下载([url]http://www.huosoft.com/bbs/ShowPost.asp?ThreadID=20[/url])使用的SpriteEngine也可以在这个页面上下载到。
首先在Delphi2006LIBRARY中加入它们。
然后在自己创建的工程中引入AsphyreSprite, sphyreSpriteEffects,AsphyreSpriteUtils,AsphyreDevices,AsphyreDef,
  AsphyreEffects,AsphyreTimer,AsphyreImages,
  AsphyrePalettes
单元。
 
我们创建一个按钮类
// 按钮类
  TSpriteButton=class(TAnimatedSprite)
  private
  public
     procedure DoMove(const MoveCount: Single); override;
     procedure OnMouseClick; override;
     procedure OnMouseLeave; override;
     procedure OnMouseEnter; override;
     procedure OnMouseUp; override;
  end;
 
并在界面的CREATE事件中加入一下代码:
procedure TSHFrm.FormCreate(Sender: TObject);
begin
  inherited;
  //
加载图片的XML文件
 ImageGroups.ParseLink('/p_w_picpaths.xml');
 // 加载字体的XML文件
  FontGroups.ParseLink('/fonts.xml');
 // 初始化Devices
  Devices.InitEvent:=InitDevice;
  Devices.DoneEvent:=DoneDevice;
  Devices.Count:=1;
  if(not Devices.Initialize(DevConfig,Self)) then
  begin
    close();
    Exit;
  end;
 // 初始化Timer
  Timer.Enabled:=true;
  Timer.OnTimer:=TimerEvent;
  Timer.MaxFPS:= 4000;

end;
 
procedure TSHFrm.InitDevice(Sender: TAsphyreDevice);
begin
  inherited;
  SpriteEngine := TSpriteEngine.Create(nil);
  SpriteEngine.Device:=Sender;
  SpriteEngine.Image := Sender.Images;
  SpriteEngine.Canvas := Sender.Canvas;
  SpriteEngine.DoMouseEvent := True;
  //
设置界面的宽和高
  SpriteEngine.VisibleWidth:=1022;
  SpriteEngine.VisibleHeight:=738;
  // 创建系统按钮
  CreateSystemButton;
end;
 
procedure TSHFrm.DevConfig(Sender: TAsphyreDevice; Tag: TObject;
  var Config: TScreenConfig);
begin
  Config.Width   := 1022;
  Config.Height  := 738;
  Config.Windowed:= true;
  Config.VSync   := true;
  Config.BitDepth:= bd24Bit;
  Config.WindowHandle:= Self.Handle;
  Config.HardwareTL  := false;
  Config.DepthStencil:= dsNone;
end;
 
 
procedure TSHFrm.TimerEvent(Sender: TObject);
begin
  Devices[0].Render(0, DevRender, Self, cRGB1(255,255,0));
  Timer.Process();
end;
 
procedure TSHFrm.DevRender(Sender: TAsphyreDevice; Tag: TObject);
begin
  inherited;
  //
绘制背景
  DrawEx(Sender.Canvas,Sender.Images.Image['gameback'], 0, 0, 0, clWhite4, fxuBlend);
  {
绘制用户信息}
  //
自己的信息
  DrawOtherInfo(Sender);
  SpriteEngine.Draw;
  SpriteEngine.Move(1);
end;
 
以上是一些必须写的代码下来看如何来实现最大化,最小化和关闭按钮。
CreateSystemButton函数中创建系统按钮。
procedure TSHFrm.CreateSystemButton;
begin
  //
最小化
  with TSpriteButton.Create(SpriteEngine) do
  begin
    SetAnim('min',0,1,0,false);   //
按钮初始状态使用的图片
    DoAnimate := true;
    Width := 35;           //
按钮的宽
    Height:=22;            //
按钮的高
    X := 912;                //
按钮所在的X位置
    Y := 0;                    //
按钮所在的Y位置
    Tag := 101;            //
按钮的TAG
  end;
  // 最大化
  with TSpriteButton.Create(SpriteEngine) do
  begin
    SetAnim('max',3,3,0,false);
    DoAnimate := true;
    Width := 35;
    Height:=22;
    X := 947;
    Y := 0;
    Tag := 102;
  end;

  //
关闭
  with TSpriteButton.Create(SpriteEngine) do
  begin
    SetAnim('close',0,1,0,false);
    DoAnimate := true;
    Width := 35;
    Height:=22;
    X := 982;
    Y := 0;
    Tag := 103;
  end;
end;
 
TSpriteButton按钮类的中实现DoMove函数
procedure TSpriteButton.DoMove(const MoveCount: Single);
begin
  inherited;
  ActiveRect:=Rect(Round(X), Round(Y), Round(X+40), Round(Y+40));
end;
 
处理按钮类中鼠标点击等事件
procedure TSpriteButton.OnMouseClick;
begin
  inherited;
  case Self.Tag of
  101:             //
最小化
  begin
    SetAnim('min', 2, 2, 0, false);
  end;
  102:             //
最大化
  begin
    SetAnim('max', 3, 3, 0, false);
  end;
  103:             //
关闭
  begin
    SetAnim('close', 2, 2, 0, false);
    SHFrm.Close;
  end;
  end;
end;
procedure TSpriteButton.OnMouseEnter;
begin
  inherited;
  case Self.Tag of
  101:             //
最小化
  begin
    SetAnim('min', 1, 1, 0, false);
  end;
  102:             //
最大化
  begin
    SetAnim('max', 3, 3, 0, false);
  end;
  103:             //
关闭
  begin
    SetAnim('close', 1, 1, 0, false);
  end;
  end;
end;
procedure TSpriteButton.OnMouseLeave;
begin
  inherited;
  101:             //
最小化
  begin
    SetAnim('min', 0, 0, 0, false);
  end;
  102:             //
最大化
  begin
    SetAnim('max', 3, 3, 0, false);
  end;
  103:             //
关闭
  begin
    SetAnim('close', 0, 0, 0, false);
  end;
  end;
end;
procedure TSpriteButton.OnMouseUp;
begin
  inherited;
  case Self.Tag of
  101:             //
最小化
  begin
    SetAnim('min', 0, 0, 0, false);
  end;
  102:             //
最大化
  begin
    SetAnim('max', 3, 3, 0, false);
  end;
  103:             //
关闭
  begin
    SetAnim('close', 0, 0, 0, false);
  end;
  end;
end;
这样我们就实现了系统按钮的功能。通过以上的代码,大家不难看出对于鼠标事件的处理,主要是依照这个按钮对象的Tag 值。其实以上的方法也可以用来实现图片的移动效果,具体方法我就不在这里写了。