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

📄 diablo.dpr

📁 此為國外大名鼎鼎的2D遊戲引擎HGE的Delphi版本 原官方是C++的,現在完全改為Delphi可使用,另外再增加許多單元與功能 新增的單元有HGEImages,HGECanvas,HGEDef
💻 DPR
📖 第 1 页 / 共 2 页
字号:
program DIABLO;

{$R *.res}

uses
  Windows, SysUtils, HGEImages, HGECanvas, HGEDef, HGE,
  Math, HGESpriteEngine;

type
  TShadowSprite = class;
  TTile = class(TSprite)
  public
     procedure DoDraw; override;
  end;

  TFinger = class(TAnimatedSprite)
  public
    procedure DoMove(const MoveCount: Single); override;
    procedure DoCollision(const Sprite: TSprite); override;
  end;

  TCharacter = class(TAnimatedSprite)
  private
    FWalkSpeed: Single;
    FDirection: Integer;
    FFramePerDir: Integer;
    FShadow: TShadowSprite;
  protected
    procedure SetDirectionAnim; virtual;
    procedure GoDirection8; virtual;
  public
    constructor Create(const AParent: TSprite); override;
    procedure DoDraw;override;
    property Shadow: TShadowSprite read FShadow write FShadow;
    property Direction: Integer read FDirection write FDirection;
    property WalkSpeed: Single read FWalkSpeed write FWalkSpeed;
    property FramePerDir: Integer read FFramePerDir write FFramePerDir;
  end;

  TLight=class(TCharacter);

  TShadowSprite = class(TCharacter)
  public
    procedure GoDirection8; override;
    procedure DoDraw; override;
    procedure DoMove(const MoveCount: Single); override;
  end;

  THero = class(TCharacter)
  private
    FShadow: TShadowSprite;
  public
    procedure DoMove(const MoveCount: Single); override;
    procedure DoDraw; override;
    property Shadow: TShadowSprite read FShadow write FShadow;
  end;

  TMonster = class(TCharacter)
  private
    FLight: TLight;
  public
    procedure DoMove(const MoveCount: Single); override;
    property Light: TLight read FLight write FLight;
  end;

var
  HGE: IHGE = nil;
  Images: THGEimages;
  Canvas: THGECanvas;
  Font: TSysFont;
  SpriteEngine: TSpriteEngine;
  Tiles: array of array of TTile;
  Monster: array of array of TMonster;
  Hero: THero;
  Finger: TFinger;
  MX, MY: Single;
  Velocity1: Single;
  Velocity2: Single;

procedure TTile.DoDraw;
begin
  if (X > Engine.WorldX-Width)and
  (Y > Engine.WorldY-Height) and
  (X < Engine.WorldX +800) and
  (Y < Engine.WorldY +600) then
     inherited DoDraw;
end;

procedure TCharacter.DoDraw;
begin
  if (X > Engine.WorldX-Width) and
  (Y > Engine.WorldY-Height)and
  (X < Engine.WorldX +800)and
  (Y < Engine.WorldY +600) then
     inherited DoDraw;
end;

procedure TFinger.DoMove(const MoveCount: Single);
begin
  inherited;
  X := Mx + Engine.WorldX;
  Y := My + Engine.WorldY;
  CollidePos := Point2(X + 16, Y + 16);
end;

procedure TCharacter.SetDirectionAnim;
begin
     case Direction of
          0: begin AnimStart := 0 * FramePerDir; MirrorX := False; end;
          1: begin AnimStart := 1 * FramePerDir; MirrorX := False; end;
          2: begin AnimStart := 2 * FramePerDir; MirrorX := False; end;
          3: begin AnimStart := 3 * FramePerDir; MirrorX := False; end;
          4: begin AnimStart := 4 * FramePerDir; MirrorX := False; end;
          //5,6,7 use image mirror
          5: begin AnimStart := 3 * FramePerDir; MirrorX := True; end;
          6: begin AnimStart := (3 - 1) * FramePerDir; MirrorX := True; end;
          7: begin AnimStart := (3 - 2) * FramePerDir; MirrorX := True; end;
     end;
end;

procedure TCharacter.GoDirection8;
begin
     if Direction = 0 then Y := Y - FWalkSpeed;
     if Direction = 1 then begin X := X + FWalkSpeed; Y := Y - FWalkSpeed; end;
     if Direction = 2 then X := X + FWalkSpeed;
     if Direction = 3 then begin X := X + FWalkSpeed; Y := Y + FWalkSpeed; end;
     if Direction = 4 then Y := Y + FWalkSpeed;
     if Direction = 5 then begin X := X - FWalkSpeed; Y := Y + FWalkSpeed; end;
     if Direction = 6 then X := X - FWalkSpeed;
     if Direction = 7 then begin X := X - FWalkSpeed; Y := Y - FWalkSpeed; end;
end;

procedure TFinger.DoCollision(const Sprite: TSprite);
begin

     if (Sprite is TMonster) then
     begin
          with TMonster(Sprite) do
          begin
               Red := 180;
               Green := 180;
               Blue := 180;
               Font.Print(Round(X - Engine.WorldX) + 10,
               Round(Y - Engine.WorldY) - 15,ImageName);

          end;
     end;

     if (Sprite is THero) then
     begin
          with THero(Sprite) do
          begin
               Red := 200;
               Green := 200;
               Blue := 200;
               BlendMode := Blend_Bright;//FxBrightAdd;
               Font.Print( Round(X - Engine.WorldX) + 30,
               Round(Y - Engine.WorldY),ImageName);

          end;
     end;
end;

constructor TCharacter.Create(const AParent: TSprite);
begin
     inherited;
     FWalkSpeed := 1.25;
end;

procedure TShadowSprite.DoDraw;
begin
           if (X1 > Engine.WorldX-Width )and
          (Y1 > Engine.WorldY-Height) and
          (X1 < Engine.WorldX +Engine.VisibleWidth)  and
          (Y1 < Engine.WorldY +Engine.VisibleHeight) then
          Engine.Canvas.Draw4V(Engine.Images.Image[ImageName],
          PatternIndex,
          Trunc(X1 + OffsetX - Engine.WorldX), Trunc(Y1 + OffsetY - Engine.WorldY),
          Trunc(X2 + OffsetX - Engine.WorldX), Trunc(Y2 + OffsetY - Engine.WorldY),
          Trunc(X3 + OffsetX - Engine.WorldX), Trunc(Y3 + OffsetY - Engine.WorldY),
          Trunc(X4 + OffsetX - Engine.WorldX), Trunc(Y4 + OffsetY - Engine.WorldY),
          MirrorX, MirrorY,
          ARGB(Alpha,Red, Green, Blue),Blend_Default);
end;

procedure TShadowSprite.DoMove;
begin
     inherited;
     GoDirection8;
     SetDirectionAnim;
end;

procedure TShadowSprite.GoDirection8;
begin
     if Direction = 0 then begin Y1 := Y1 - FWalkSpeed; Y2 := Y2 - FWalkSpeed; Y3 := Y3 - FWalkSpeed; Y4 := Y4 - FWalkSpeed; end;
     if Direction = 1 then begin X1 := X1 + FWalkSpeed; X2 := X2 + FWalkSpeed; X3 := X3 + FWalkSpeed; X4 := X4 + FWalkSpeed; Y1 := Y1 - FWalkSpeed; Y2 := Y2 - FWalkSpeed; Y3 := Y3 - FWalkSpeed; Y4 := Y4 - FWalkSpeed; end;
     if Direction = 2 then begin X1 := X1 + FWalkSpeed; X2 := X2 + FWalkSpeed; X3 := X3 + FWalkSpeed; X4 := X4 + FWalkSpeed; end;
     if Direction = 3 then begin X1 := X1 + FWalkSpeed; X2 := X2 + FWalkSpeed; X3 := X3 + FWalkSpeed; X4 := X4 + FWalkSpeed; Y1 := Y1 + FWalkSpeed; Y2 := Y2 + FWalkSpeed; Y3 := Y3 + FWalkSpeed; Y4 := Y4 + FWalkSpeed; end;
     if Direction = 4 then begin Y1 := Y1 + FWalkSpeed; Y2 := Y2 + FWalkSpeed; Y3 := Y3 + FWalkSpeed; Y4 := Y4 + FWalkSpeed; end;
     if Direction = 5 then begin X1 := X1 - FWalkSpeed; X2 := X2 - FWalkSpeed; X3 := X3 - FWalkSpeed; X4 := X4 - FWalkSpeed; Y1 := Y1 + FWalkSpeed; Y2 := Y2 + FWalkSpeed; Y3 := Y3 + FWalkSpeed; Y4 := Y4 + FWalkSpeed; end;
     if Direction = 6 then begin X1 := X1 - FWalkSpeed; X2 := X2 - FWalkSpeed; X3 := X3 - FWalkSpeed; X4 := X4 - FWalkSpeed; end;
     if Direction = 7 then begin X1 := X1 - FWalkSpeed; X2 := X2 - FWalkSpeed; X3 := X3 - FWalkSpeed; X4 := X4 - FWalkSpeed; Y1 := Y1 - FWalkSpeed; Y2 := Y2 - FWalkSpeed; Y3 := Y3 - FWalkSpeed; Y4 := Y4 - FWalkSpeed; end;
end;

procedure TMonster.DoMove(const MoveCount: Single);
begin
     inherited;
     case Random(100) of
          50: Direction := Random(8);
     end;
     GoDirection8;
     SetDirectionAnim;
     CollidePos := Point2(X + 60, Y + 50);
     Light.X := X + Width div 2;
     Light.Y := Y + Height div 2+20;
     if ImageName = 'Mega Demon' then CollidePos := Point2(X + 120, Y + 100);
end;

procedure CreateTiles(ArrayA, ArrayB, OffsetX, OffsetY: Integer);
var
  a, b: Integer;
begin
  SetLength(Tiles, ArrayA, ArrayB);
  for a := 0 to ArrayA - 1 do
  begin
    for b := 0 to ArrayB - 1 do
    begin
      Tiles[a,b] := TTile.Create(SpriteEngine);
      Tiles[a,b].ImageName := 'Floor';
      Tiles[a,b].Width:=Tiles[a,b].PatternWidth;
      Tiles[a,b].Height:=Tiles[a,b].PatternHeight;
      Tiles[a,b].Moved := False;
      Tiles[a,b].X := 79 * b + OffsetX;
      if (b mod 2) = 0 then
        Tiles[a, b].Y := 79 * a + OffsetY;
      if (b mod 2) = 1 then
        Tiles[a, b].Y := 40 + 79 * a + OffsetY;
      Tiles[a, b].PatternIndex := Random(30);
    end;
  end;
end;

procedure DrawTiles;
var
  a, b: Integer;
begin
  for a := 0 to High(Tiles) - 1 do
  begin
    for b := 0 to High(Tiles[0]) - 1 do
    begin
      Tiles[a, b].DoDraw;
  // Tiles[a,b].Move(1);
    end;
  end;
end;

procedure CreateMonsters(ArrayA, ArrayB: Integer);
var
  a, b: Integer;
begin
  SetLength(Monster, ArrayA, ArrayB);
  for a := 0 to ArrayA - 1 do
  begin
    for b := 0 to ArrayB - 1 do
    begin
      Monster[a, b] := TMonster.Create(SpriteEngine);
      Monster[a, b].ImageName := Images.Items[Random(7)].Name;
      Monster[a,b].Width:=Monster[a,b].PatternWidth;
      Monster[a,b].Height:=Monster[a,b].PatternHeight;
      Monster[a, b].FramePerDir := Monster[a, b].PatternCount div 5;
      Monster[a, b].X := Random(7000) - 3000;
      Monster[a, b].Y := Random(7000) - 3000;
      Monster[a, b].Direction := Random(8);
      Monster[a, b].AnimCount := Monster[a, b].FramePerDir;
      Monster[a, b].AnimSpeed := 0.35;
      Monster[a, b].DoAnimate := True;
      Monster[a, b].AnimLooped := True;
      Monster[a, b].Red := 165;
      Monster[a, b].Green := 165;
      Monster[a, b].Blue := 165;
      Monster[a,b].BlendMode:= Blend_Bright;
      Monster[a, b].CollideRadius := 25;
      if Monster[a, b].ImageName = 'dm' then Monster[a, b].CollideRadius := 50;
      Monster[a, b].Collisioned := True;
      Monster[a, b].Light := TLight.Create(SpriteEngine);
      Monster[a, b].Light.ImageName := 'Light';
      Monster[a,b].Light.Moved:=False;
      Monster[a,b].Light.Collisioned:=False;
      Monster[a,b].Light.Width:= Monster[a,b].Light.PatternWidth;
      Monster[a,b].Light.Height:= Monster[a,b].Light.PatternHeight;
      Monster[a, b].Light.BlendMode := Blend_Light;
      Monster[a, b].Light.ScaleX := 0.5;
      Monster[a, b].Light.ScaleY := 0.3;
      Monster[a, b].Light.DoCenter:=True;
      //Create Sprite's shadow
      Monster[a, b].Shadow := TShadowSprite.Create(SpriteEngine);
      Monster[a, b].Shadow.DrawMode := 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -