之前我写过一篇《使用Asphyre开发游戏的方式 》的文章。文章中简述了如果使用asphyre3.10来开发游戏。但是使用asphyre3.10来开发游戏有一个很麻烦的问题――如何来实现VCL中按钮等等控件的效果。以前使用3.10的时候,我使用的方法是:定义出一个区域来,判断鼠标点击的是不是在这个区域,如果是那么做相应的操作。这样虽然也可以实现,但是其代码量和逻辑关系比较难以控制。很是麻烦。
最近使用Asphyre4.10和SpriteEngine来开发游戏,觉得将这两个结合起来实现按钮效果非常方便。下面我就将如果实现这种效果写出来。
我使用的Asphyre版本是Asphyre4snapshot这个可以在火人的BLOG上下载([url]http://www.huosoft.com/bbs/ShowPost.asp?ThreadID=20[/url])使用的SpriteEngine也可以在这个页面上下载到。
首先在Delphi2006的LIBRARY中加入它们。
然后在自己创建的工程中引入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('/images.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 值。其实以上的方法也可以用来实现图片的移动效果,具体方法我就不在这里写了。