给你一个例子: unit Unit1;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus, DXClass, DXSprite, DXInput, DXDraws; type TDirection = (DrUp, DrDown, DrLeft, DrRight, DrUpLeft, DrUpRight, DrDownLeft, DrDownRight); TPlayerSprite = class (TImageSprite) CanMove: Boolean; protected procedure DoMove(MoveCount: Integer); override; procedure MoveTo(MoveCount:Integer; Direction: TDirection); procedure DoCollision(Sprite: TSprite; var Done: Boolean); override; end; TMainForm = class(TDXForm) DXDraw: TDXDraw; ImageList: TDXImageList; DXInput: TDXInput; DXTimer: TDXTimer; DXSpriteEngine: TDXSpriteEngine; MainMenu1: TMainMenu; N3434321: TMenuItem; N34321: TMenuItem; procedure FormCreate(Sender: TObject); procedure DXDrawFinalize(Sender: TObject); procedure DXDrawInitialize(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure DXDrawMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure DXTimerTimer(Sender: TObject; LagCount: Integer); private { Private declarations } AnchorX: Integer; AnchorY: Integer; {鼠标点击发生的位置} MouseX: Integer; MouseY: Integer; {鼠标当前位置} PlayerSprite: TPlayerSprite; {游戏中我们所用鼠标控制的人物} BackSprite: TBackGroundSprite; {游戏的背景图} public { Public declarations } end;const Speed = 5;var MainForm: TMainForm; Steps: Integer; {用于控制切换精灵动画图片的参数}implementation{$R *.dfm}{ TPlayerSprite }procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean); begin Done:=False; {已经侦测到碰撞,不再重复检测碰撞} {检测游戏人物是否与其它精灵发生了碰撞,此处可以扩展为对话等情节} end;procedure TPlayerSprite.DoMove(MoveCount: Integer); var l,r,d,u: Boolean; absX,absY: Integer; {游戏人物的当前位置与目的地的绝对距离} begin inherited DoMove(MoveCount); MoveCount:=Trunc(MoveCount*1.5); l:=false; r:=false; u:=false; d:=false; if (Trunc(X)-MainForm.AnchorX>0) then l:=true else r:=true; if (Trunc(Y)-MainForm.AnchorY>0) then u:=true else d:=true; absX:=abs(Trunc(X)-MainForm.AnchorX); absY:=abs(Trunc(Y)-MainForm.AnchorY); if absX<4 then begin l:=false; r:=false; end; if absY<4 then begin u:=false; d:=false; end; {如果绝对距离已经小于四个象素,则认为已经到达目的地} if u and l and not d and not r then MoveTo(MoveCount,DrUpLeft); if u and r and not l and not d then MoveTo(MoveCount,DrUpRight); if d and l and not r and not u then MoveTo(MoveCount,DrDownLeft); if d and r and not u and not l then MoveTo(MoveCount,DrDownRight); if d and not l and not r and not u then MoveTo(MoveCount,DrDown); if u and not l and not r and not d then MoveTo(MoveCount,DrUp); if l and not u and not r and not d then MoveTo(MoveCount,DrLeft); if r and not l and not u and not d then MoveTo(MoveCount,DrRight); {根据目的地来判断运动的方向,从而播放相应方向运动的动画} Collision; {检测碰撞} Engine.X := -X+Engine.Width div 2 - Width div 2; Engine.Y := -Y+Engine.Height div 2 - Height div 2; {移动引擎,从而是游戏人物处于舞台的正中央} end; procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer); begin if not DXDraw.CanDraw then exit; {检测DXDraw是否可以画,否则退出} DXInput.Update; {捕捉各类设备输入,这里我们用来检测鼠标的输入} LagCount := 1000 div 60; {用来控制整个游戏运行速度的参数} DXSpriteEngine.Move(LagCount); DXSpriteEngine.Dead; DXDraw.Surface.Fill(0); {将整个屏幕填充为黑色} DXSpriteEngine.Draw; with DXDraw.Surface.Canvas do begin brush.style:=bsclear; pen.style:=psclear; pen.color:=clwhite; Font.Color:=clWhite; Font.Size:=10;
textout(10,10,'Press ESC to Quit'); textout(100,100,'X: '+IntToStr(AnchorX)+'Y: '+IntToStr(AnchorY)); {鼠标点击的位置经转换后在游戏世界中的坐标} textout(100,200,'Sprit x:'+IntToStr(Trunc(PlayerSprite.x))+'Y: '+IntToStr(Trunc(PlayerSprite.y))); {精灵在游戏世界中的坐标} textout(100,300,'Relative x:'+IntToStr(AnchorX-Trunc(PlayerSprite.x))+'Y: '+IntToStr(AnchorY-Trunc(PlayerSprite.y))); {精灵当前位置与目的地之间的绝对距离} textout(200,100,'Mouse x:'+IntToStr(MainForm.MouseX)+'Y: '+IntToStr(MainForm.MouseY)); {鼠标当前位置,相对于窗口左上角,未转换为游戏世界坐标} Release; end; {在字母上输出相应参数,用于程序调试} DXDraw.Flip; {将内存中的后台表面翻转到当前并且显示} end;procedure TMainForm.DXDrawFinalize(Sender: TObject); begin DXTimer.Enabled := False; {关闭定时器} end;procedure TMainForm.DXDrawInitialize(Sender: TObject); begin DXTimer.Enabled := True; {启动定时器} end;procedure TMainForm.FormCreate(Sender: TObject); begin Steps:=0; AnchorX:=0; AnchorY:=0; MouseX:=320; MouseY:=240; {默认使鼠标处于屏幕的中央} ImageList.Items.MakeColorTable; DXDraw.ColorTable := ImageList.Items.ColorTable; DXDraw.DefColorTable := ImageList.Items.ColorTable; DXDraw.UpdatePalette; {更新系统调色板} BackSprite:=TBackgroundSprite.Create(DXSpriteEngine.Engine); with TBackgroundSprite(BackSprite) do begin SetMapSize(1, 1);{设定背景显示样式为1×1} Image := ImageList.Items.Find('background'); {载入背景图片} Z := -2; {设定背景层次} Tile := True; {设定背景填充样式为平铺} end; PlayerSprite := TPlayerSprite.Create(DXSpriteEngine.Engine); with TPlayerSprite(PlayerSprite) do begin Image := ImageList.Items.Find('player'); Z := 2; Width := Image.Width; Height := Image.Height; end; {载入游戏人物} end;procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin {如果按了Esc,则退出} if Key=VK_ESCAPE then Close; {全屏模式和窗口模式的切换} if (ssAlt in Shift) and (Key=VK_RETURN) then begin DXDraw.Finalize; if doFullScreen in DXDraw.Options then begin RestoreWindow; DXDraw.Cursor := crNone; BorderStyle := bsSizeable; DXDraw.Options := DXDraw.Options - [doFullScreen]; end else begin StoreWindow; DXDraw.Cursor := crNone; BorderStyle := bsNone; DXDraw.Options := DXDraw.Options + [doFullScreen]; end; DXDraw.Initialize; end; end; procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin AnchorX := x + Trunc(PlayerSprite.x)-320; AnchorY := y + Trunc(PlayerSprite.y)-240; {将鼠标在屏幕上点击的位置转换到游戏世界中} PlayerSprite.CanMove:=True; {此参数允许鼠标拖动} end;procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if PlayerSprite.CanMove then begin AnchorX := x + Trunc(PlayerSprite.x)-320; AnchorY := y + Trunc(PlayerSprite.y)-240; {在鼠标拖动过程中将鼠标在屏幕上点击的位置转换到游戏世界中} end; MouseX:=X; MouseY:=Y; {鼠标当前位置} end;procedure TMainForm.DXDrawMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin PlayerSprite.CanMove:=False; end; procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin DXSpriteEngine.Free; end;procedure TPlayerSprite.MoveTo(MoveCount: Integer; Direction: TDirection); begin {控制精灵往各个方向移动} case Direction of DrUp: begin Y := Y-(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+20+1; {当前动画中播放的图片序号} if steps>4*speed-2 then steps:=0; end; DrDown: begin Y := Y+(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+1; if steps> 4*speed-2 then steps:=0; end; DrLeft: begin X := X-(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+10+1; if steps>4*speed-2 then steps:=0; end; DrRight: begin X := X+(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+30+1; if steps>4*speed-2 then steps:=0; end; DrUpLeft: begin X := X-(150/1000)*MoveCount; Y := Y-(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+15+1; if steps>4*speed-2 then steps:=0; end; DrUpRight: begin X := X+(150/1000)*MoveCount; Y := Y-(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+25+1; if steps>4*speed-2 then steps:=0; end; DrDownLeft: begin X := X-(150/1000)*MoveCount; Y := Y+(150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+5+1; if steps>4*speed-2 then steps:=0; end; DrDownRight: begin X := X + (150/1000)*MoveCount; Y := Y + (150/1000)*MoveCount; Inc(steps); AnimPos:=steps div speed+35+1; if steps>4*speed-2 then steps:=0; end; end; end; end.
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Menus, DXClass, DXSprite, DXInput, DXDraws;
type
TDirection = (DrUp, DrDown, DrLeft, DrRight, DrUpLeft, DrUpRight, DrDownLeft, DrDownRight); TPlayerSprite = class (TImageSprite)
CanMove: Boolean;
protected
procedure DoMove(MoveCount: Integer); override;
procedure MoveTo(MoveCount:Integer; Direction: TDirection);
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
end;
TMainForm = class(TDXForm)
DXDraw: TDXDraw;
ImageList: TDXImageList;
DXInput: TDXInput;
DXTimer: TDXTimer;
DXSpriteEngine: TDXSpriteEngine;
MainMenu1: TMainMenu;
N3434321: TMenuItem;
N34321: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure DXDrawFinalize(Sender: TObject);
procedure DXDrawInitialize(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure DXDrawMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
private
{ Private declarations }
AnchorX: Integer;
AnchorY: Integer; {鼠标点击发生的位置}
MouseX: Integer;
MouseY: Integer; {鼠标当前位置}
PlayerSprite: TPlayerSprite; {游戏中我们所用鼠标控制的人物}
BackSprite: TBackGroundSprite; {游戏的背景图} public
{ Public declarations }
end;const
Speed = 5;var
MainForm: TMainForm; Steps: Integer; {用于控制切换精灵动画图片的参数}implementation{$R *.dfm}{ TPlayerSprite }procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
begin
Done:=False; {已经侦测到碰撞,不再重复检测碰撞}
{检测游戏人物是否与其它精灵发生了碰撞,此处可以扩展为对话等情节}
end;procedure TPlayerSprite.DoMove(MoveCount: Integer);
var
l,r,d,u: Boolean;
absX,absY: Integer; {游戏人物的当前位置与目的地的绝对距离}
begin
inherited DoMove(MoveCount);
MoveCount:=Trunc(MoveCount*1.5);
l:=false; r:=false; u:=false; d:=false; if (Trunc(X)-MainForm.AnchorX>0) then l:=true else r:=true;
if (Trunc(Y)-MainForm.AnchorY>0) then u:=true else d:=true; absX:=abs(Trunc(X)-MainForm.AnchorX);
absY:=abs(Trunc(Y)-MainForm.AnchorY); if absX<4 then begin l:=false; r:=false; end;
if absY<4 then begin u:=false; d:=false; end;
{如果绝对距离已经小于四个象素,则认为已经到达目的地} if u and l and not d and not r then MoveTo(MoveCount,DrUpLeft);
if u and r and not l and not d then MoveTo(MoveCount,DrUpRight);
if d and l and not r and not u then MoveTo(MoveCount,DrDownLeft);
if d and r and not u and not l then MoveTo(MoveCount,DrDownRight);
if d and not l and not r and not u then MoveTo(MoveCount,DrDown);
if u and not l and not r and not d then MoveTo(MoveCount,DrUp);
if l and not u and not r and not d then MoveTo(MoveCount,DrLeft);
if r and not l and not u and not d then MoveTo(MoveCount,DrRight);
{根据目的地来判断运动的方向,从而播放相应方向运动的动画} Collision; {检测碰撞}
Engine.X := -X+Engine.Width div 2 - Width div 2;
Engine.Y := -Y+Engine.Height div 2 - Height div 2;
{移动引擎,从而是游戏人物处于舞台的正中央}
end;
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
begin
if not DXDraw.CanDraw then exit;
{检测DXDraw是否可以画,否则退出}
DXInput.Update;
{捕捉各类设备输入,这里我们用来检测鼠标的输入} LagCount := 1000 div 60;
{用来控制整个游戏运行速度的参数}
DXSpriteEngine.Move(LagCount);
DXSpriteEngine.Dead; DXDraw.Surface.Fill(0);
{将整个屏幕填充为黑色}
DXSpriteEngine.Draw; with DXDraw.Surface.Canvas do
begin
brush.style:=bsclear;
pen.style:=psclear;
pen.color:=clwhite;
Font.Color:=clWhite;
Font.Size:=10;
textout(10,10,'Press ESC to Quit');
textout(100,100,'X: '+IntToStr(AnchorX)+'Y: '+IntToStr(AnchorY));
{鼠标点击的位置经转换后在游戏世界中的坐标}
textout(100,200,'Sprit x:'+IntToStr(Trunc(PlayerSprite.x))+'Y: '+IntToStr(Trunc(PlayerSprite.y)));
{精灵在游戏世界中的坐标}
textout(100,300,'Relative x:'+IntToStr(AnchorX-Trunc(PlayerSprite.x))+'Y: '+IntToStr(AnchorY-Trunc(PlayerSprite.y)));
{精灵当前位置与目的地之间的绝对距离}
textout(200,100,'Mouse x:'+IntToStr(MainForm.MouseX)+'Y: '+IntToStr(MainForm.MouseY));
{鼠标当前位置,相对于窗口左上角,未转换为游戏世界坐标}
Release;
end;
{在字母上输出相应参数,用于程序调试}
DXDraw.Flip;
{将内存中的后台表面翻转到当前并且显示}
end;procedure TMainForm.DXDrawFinalize(Sender: TObject);
begin
DXTimer.Enabled := False;
{关闭定时器}
end;procedure TMainForm.DXDrawInitialize(Sender: TObject);
begin
DXTimer.Enabled := True;
{启动定时器}
end;procedure TMainForm.FormCreate(Sender: TObject);
begin
Steps:=0;
AnchorX:=0;
AnchorY:=0; MouseX:=320;
MouseY:=240;
{默认使鼠标处于屏幕的中央}
ImageList.Items.MakeColorTable; DXDraw.ColorTable := ImageList.Items.ColorTable;
DXDraw.DefColorTable := ImageList.Items.ColorTable;
DXDraw.UpdatePalette;
{更新系统调色板} BackSprite:=TBackgroundSprite.Create(DXSpriteEngine.Engine);
with TBackgroundSprite(BackSprite) do
begin
SetMapSize(1, 1);{设定背景显示样式为1×1}
Image := ImageList.Items.Find('background'); {载入背景图片}
Z := -2; {设定背景层次}
Tile := True; {设定背景填充样式为平铺}
end; PlayerSprite := TPlayerSprite.Create(DXSpriteEngine.Engine);
with TPlayerSprite(PlayerSprite) do
begin
Image := ImageList.Items.Find('player');
Z := 2;
Width := Image.Width;
Height := Image.Height;
end;
{载入游戏人物}
end;procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
{如果按了Esc,则退出}
if Key=VK_ESCAPE then
Close; {全屏模式和窗口模式的切换}
if (ssAlt in Shift) and (Key=VK_RETURN) then
begin
DXDraw.Finalize; if doFullScreen in DXDraw.Options then
begin
RestoreWindow; DXDraw.Cursor := crNone;
BorderStyle := bsSizeable;
DXDraw.Options := DXDraw.Options - [doFullScreen];
end else
begin
StoreWindow; DXDraw.Cursor := crNone;
BorderStyle := bsNone;
DXDraw.Options := DXDraw.Options + [doFullScreen];
end; DXDraw.Initialize;
end;
end;
procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
AnchorX := x + Trunc(PlayerSprite.x)-320;
AnchorY := y + Trunc(PlayerSprite.y)-240;
{将鼠标在屏幕上点击的位置转换到游戏世界中}
PlayerSprite.CanMove:=True;
{此参数允许鼠标拖动}
end;procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if PlayerSprite.CanMove then
begin
AnchorX := x + Trunc(PlayerSprite.x)-320;
AnchorY := y + Trunc(PlayerSprite.y)-240;
{在鼠标拖动过程中将鼠标在屏幕上点击的位置转换到游戏世界中}
end; MouseX:=X;
MouseY:=Y;
{鼠标当前位置}
end;procedure TMainForm.DXDrawMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
PlayerSprite.CanMove:=False;
end;
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
DXSpriteEngine.Free;
end;procedure TPlayerSprite.MoveTo(MoveCount: Integer; Direction: TDirection);
begin
{控制精灵往各个方向移动}
case Direction of
DrUp:
begin
Y := Y-(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+20+1;
{当前动画中播放的图片序号}
if steps>4*speed-2 then steps:=0;
end;
DrDown:
begin
Y := Y+(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+1;
if steps> 4*speed-2 then steps:=0;
end;
DrLeft:
begin
X := X-(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+10+1;
if steps>4*speed-2 then steps:=0;
end;
DrRight:
begin
X := X+(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+30+1;
if steps>4*speed-2 then steps:=0;
end;
DrUpLeft:
begin
X := X-(150/1000)*MoveCount;
Y := Y-(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+15+1;
if steps>4*speed-2 then steps:=0;
end;
DrUpRight:
begin
X := X+(150/1000)*MoveCount;
Y := Y-(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+25+1;
if steps>4*speed-2 then steps:=0;
end;
DrDownLeft:
begin
X := X-(150/1000)*MoveCount;
Y := Y+(150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+5+1;
if steps>4*speed-2 then steps:=0;
end;
DrDownRight:
begin
X := X + (150/1000)*MoveCount;
Y := Y + (150/1000)*MoveCount;
Inc(steps);
AnimPos:=steps div speed+35+1;
if steps>4*speed-2 then steps:=0;
end;
end;
end;
end.
其实DXDraw是用来写2D程序的
一般用DXSprite和DXImageList.Items就够了
必要时用
DXDraw.Surface.Canvas
我的程序太长了,就不贴了吧
最好的办法是研究一下
DXSprites.pas DIB.pas