📄 usprite.pas
字号:
//极限1000米
//Author: CrazyWill
//Email: CrazyWill@163.com
unit uSprite;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ImgList, ExtCtrls, StdCtrls, MMSystem,
IniFiles, uInclude;
type
TSprite = class
private
FMaxHP: Integer; //最大生命值
FCurrentHP: Integer;
FX, FY: Integer; //坐标
FSpeed: Integer; //行进速度
FCollisionCount: Integer; //连续碰撞计数器
FMoveDelay, FMoveDelayCount: Integer; //下次动作前的延迟次数
FActive: Boolean; //是否进行动作
FVisible: Boolean; //是否可见
FRect: TRect; //占用矩形区域
FDirection: TDirection; //前进方向
FInvBitmap: TBitmap; //图片及贴图用图片
FBit_Left, FBit_Right: TBitmap;
No_Left, No_Right, No_Up, No_Down: Integer; //目前显示的小图片编号
Numbers: Integer; //每张角色图片包含几张小图在里面;
//角色中心点所在位置
function GetTile_X: Integer;
function GetTile_Y: Integer;
//取得角色的宽和高
function GetObjectWidth: Integer;
function GetObjectHeight: Integer;
//取得角色尺寸
function GetObjectRect: TRect;
procedure SetDirection(Value: TDirection);
//边界碰撞检查
procedure CheckBoundCollisions(var X, Y: Integer; var bCollision: Boolean);
public
constructor Create; virtual;
destructor Destroy; override;
procedure Draw(Canvas: TCanvas); //绘制角色
procedure Move; //进行下一步动作
procedure RollBack; //角色随地图卷动而后退
property X: Integer read FX write FX;
property Y: Integer read FY write FY;
property Tile_X: Integer read GetTile_X;
property Tile_Y: Integer read GetTile_Y;
property HP: Integer read FCurrentHP write FCurrentHP;
property MaxHP: integer read FMaxHP;
property Direction: TDirection read FDirection write SetDirection;
property Speed: Integer read FSpeed write FSpeed;
property Active: Boolean read FActive write FActive;
property Visible: Boolean read FVisible write FVisible;
property Rect: TRect read FRect;
property ObjectRect: TRect read GetObjectRect;
property ObjectWidth: Integer read GetObjectWidth;
property ObjectHeight: Integer read GetObjectHeight;
end;
implementation
constructor TSprite.Create;
var
ini: TIniFile;
sTemp: string;
iniSection: string;
begin
inherited Create;
// 初始化
iniSection := 'Sprite';
FX := WORLD_WIDTH div 2;
FY := 0;
Direction := drRight;
FActive := False;
FVisible := True;
// 角色的 Bitmap
FBit_Left := TBitmap.Create;
FBit_Right := TBitmap.Create;
No_Left := 0;
No_Right := 0;
No_Up := 0;
No_Down := 0;
// 透明贴图用的 Bitmap
FInvBitmap := TBitmap.Create;
ini := TIniFile.Create(IniDirectory + IniFilename);
sTemp := ini.ReadString(iniSection, 'RunLeft_Filename', '');
FBit_Left.LoadFromFile(IniDirectory + sTemp);
sTemp := ini.ReadString(iniSection, 'RunRight_Filename', '');
FBit_Right.LoadFromFile(IniDirectory + sTemp);
FSpeed := ini.ReadInteger(iniSection, 'Speed', SPRITE_DEFAULT_SPEED);
FMoveDelay := ini.ReadInteger(iniSection, 'MoveDelay', 0);
FMoveDelayCount := 0;
FMaxHP := ini.ReadInteger(iniSection, 'MaxHP', SPRITE_DEFAULT_MAXHP);
HP := FMaxHP; //当前生命值与最大值相同
FInvBitmap.Width := ini.ReadInteger(iniSection, 'Width', FInvBitmap.Width);
FInvBitmap.Height := ini.ReadInteger(iniSection, 'Height', FInvBitmap.Height);
FInvBitmap.Transparent := True;
FInvBitmap.TransparentColor := TRANSPARENT_COLOR;
Numbers := ini.ReadInteger(iniSection, 'Numbers', Numbers);
// if FBit_Left.Width < ObjectWidth * Numbers then
// raise Exception.Create('Width of bitmap is invalid');
// if FBit_Left.Height < ObjectHeight * (GetFrameMax + 1) then
// raise Exception.Create('Height of bitmap is invalid');
FY := ini.ReadInteger('Map', 'Height', 0)
- ini.ReadInteger('Map', 'GroundHeight', 0) - FInvBitmap.Height;
ini.Destroy;
end;
destructor TSprite.Destroy;
begin
FInvBitmap.Free;
FBit_Left.Free;
FBit_right.free;
inherited Destroy;
end;
procedure TSprite.Draw(Canvas: TCanvas);
begin
if not FVisible then
Exit;
case FDirection of
drRight:
begin
FInvBitmap.Canvas.CopyRect(ObjectRect, FBit_Right.Canvas,
Classes.Rect(No_Right * ObjectWidth, 0,
(No_Right + 1) * ObjectWidth, ObjectHeight));
end;
drLeft:
begin
FInvBitmap.Canvas.CopyRect(ObjectRect, FBit_Left.Canvas,
Classes.Rect(No_Left * ObjectWidth, 0,
(No_Left + 1) * ObjectWidth, ObjectHeight));
end;
drUp:
begin
end;
drDown:
begin
end;
end;
Canvas.Draw(FX, fy, FInvBitmap);
end;
procedure TSprite.CheckBoundCollisions(var X, Y: Integer;
var bCollision: Boolean);
var
OrgX, OrgY: Integer;
begin
//边界检查
OrgX := X;
OrgY := Y;
if Y < 0 then
Y := 0;
if X < 0 then
X := 0;
if X + ObjectWidth >= WORLD_WIDTH then
X := WORLD_WIDTH - ObjectWidth;
if Y + ObjectHeight >= WORLD_HEIGHT then
Y := WORLD_HEIGHT - ObjectHeight;
if (OrgX <> X) or (OrgY <> Y) then
bCollision := True;
end;
procedure TSprite.Move;
var
X, Y: Integer;
begin
if not FActive then
Exit;
if FSpeed = 0 then
Exit;
if (FMoveDelay <> 0) then
begin
Inc(FMoveDelayCount);
if FMoveDelayCount <> FMoveDelay then
Exit;
FMoveDelayCount := 0;
end;
X := FX;
Y := fy;
case FDirection of
drRight:
begin
No_Right := (No_Right + 1) mod Numbers;
Inc(X, FSpeed - MapRollSpeed);
end;
drLeft:
begin
No_Left := (No_Left + 1) mod Numbers;
dec(X, FSpeed + MapRollSpeed);
end;
{ drUp:
begin
No_Up:=(No_Up+1) mod Numbers;
dec(Y, FSpeed);
end;
drDown:
begin
No_Down:=(No_Down+1) mod Numbers;
Inc(Y, FSpeed);
end;
}
end;
if X < 0 then
X := 0;
if X + ObjectWidth >= WORLD_WIDTH then
X := WORLD_WIDTH - ObjectWidth;
// if CheckCollisions(X, Y) then
begin
FX := X;
fy := Y;
end;
FRect := ObjectRect;
FRect := classes.Rect(FRect.Left + 5, FRect.Top + 5, FRect.Right - 5,
FRect.Bottom - 5);
OffsetRect(FRect, FX, Fy);
end;
function TSprite.GetTile_X: Integer;
begin
Result := (FX + ObjectWidth div 2);
end;
function TSprite.GetTile_Y: Integer;
begin
Result := (fy + ObjectHeight div 2);
end;
function TSprite.GetObjectWidth: Integer;
begin
with GetObjectRect do
Result := Right - Left;
end;
function TSprite.GetObjectHeight: Integer;
begin
with GetObjectRect do
Result := Bottom - Top;
end;
procedure TSprite.SetDirection(Value: TDirection);
begin
if Value <> FDirection then
begin
FCollisionCount := 0;
No_Left := 0;
No_Right := 0;
No_Up := 0;
No_Down := 0;
FDirection := Value;
end;
end;
function TSprite.GetObjectRect: TRect;
begin
Result := FInvBitmap.Canvas.ClipRect;
end;
//角色随地图卷动而后退
procedure TSprite.RollBack;
begin
dec(FX, MapRollSpeed);
if X < 0 then
X := 0;
FRect := ObjectRect;
FRect := classes.Rect(FRect.Left + 5, FRect.Top + 5, FRect.Right - 5,
FRect.Bottom - 5);
OffsetRect(FRect, FX, Fy);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -