⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usprite.pas

📁 一个dos游戏的源代码
💻 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 + -