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

📄 doudou.dpr.~1~

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

{$R *.res}

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

type
  TActorState = (StandLeft, StandRight, WalkLeft, WalkRight, Die);

  TTileAttribute = (taNormal, taPlatform, taBlock, taTreasure, taSlope);
  TMapRec = record
     X, Y: Integer;
     ImageName: string[10];
  end;

  TTile = class(TAnimatedSprite)
  private
    FCollideRight: Integer;
    FCollideBottom: Integer;
  public
    ID: Integer;
    procedure DoMove(const MoveCount: Single); override;
  end;

  TActor = class(TJumperSprite)
  private
    FState: TActorState;
    FMoveSpeed: Single;
    FLeft, FTop, FRight, FBottom: Integer;
  public
    procedure DoMove(const MoveCount: Single); override;
    procedure DoCollision(const Sprite: TSprite); override;
    constructor Create(const AParent: TSprite); override;
    property MoveSpeed: Single read FMoveSpeed write FMoveSpeed;
    property State: TActorState read FState write FState;
    property Left: Integer read FLeft write FLeft;
    property Top: Integer read FTop write FTop;
    property Right: Integer read FRight write FRight;
    property Bottom: Integer read FBottom write FBottom;
   end;

  TEnemy = class(TjumperSprite)
  private
    FState: TActorState;
    FCollideRight: Integer;
    FCollideBottom: Integer;
  public
    procedure DoMove(const MoveCount: Single); override;
    procedure DoCollision(const Sprite: TSprite); override;
    property State: TActorState read FState write FState;
  end;

  TSpray = class(TPlayerSprite)
  public
    procedure DoMove(const MoveCount: Single); override;
  end;

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

var
  HGE: IHGE = nil;
  Images: THGEimages;
  Canvas: THGECanvas;
  Font: TSysFont;
  SpriteEngine: TSpriteEngine;
  Fs: TFileStream;
  FileSize: Integer;
  MapData: array of TMapRec;
  Layer1Pos: Single;
  Layer2Pos: Single;
  LeftEdge, RightEdge: Integer;
  FruitCount: Integer;
  Actor: TActor;
  UserRefreshRate: Integer;

procedure LoadImages;
var
  FileSearchRec: TSearchRec;
begin
  if FindFirst(ExtractFilePath(ParamStr(0)) + 'Gfx\'+ '*.png', faAnyfile, FileSearchRec) = 0 then
  repeat
    Images.LoadFromFile('Gfx\'+FileSearchRec.Name);
  until  FindNext(FileSearchRec) <> 0;
  FindClose(FileSearchRec);
  Images.LoadFromFile('Idle.png',110, 118);
  Images.LoadFromFile('Walk.png',110, 118);
  Images.LoadFromFile('Jump.png',110, 118);
  Images.LoadFromFile('Dead.png',110, 118);
  Images.LoadFromFile('Enemy1.png',50, 40);
  Images.LoadFromFile('Enemy2.png',40, 40);
  Images.LoadFromFile('Enemy3.png',48, 35);
  Images.LoadFromFile('Spring1.png',48, 48);
end;

procedure LoadMapData(FileName: string);
begin
     Fs := TFileStream.Create(ExtractFilePath(ParamStr(0)) + FileName, fmOpenRead);
     Fs.ReadBuffer(FileSize, SizeOf(FileSize));
     SetLength(MapData, FileSize);
     Fs.ReadBuffer(MapData[0], SizeOf(TMapRec) * FileSize);
     Fs.Destroy;
end;

procedure CreateMap;
var
   I:Integer;
begin
     Actor := TActor.Create(SpriteEngine);
     Actor.Z:=15;
     Actor.TruncMove := True;
     for I := FileSize - 1 downto 0 do
     begin
          if (MapData[i].ImageName <> 'Enemy1') and  (MapData[i].ImageName <> 'Enemy2') and (MapData[i].ImageName <> 'Enemy3') then
          begin
               with  TTile.Create(SpriteEngine) do
               begin
                    ImageName := MapData[i].ImageName;
                    X := MapData[i].X - 540;
                    Y := MapData[i].Y - 150;
                    Z:=10;
                    TruncMove := True;
                   // Moved := False;
                    Width := PatternWidth;
                    Height := PatternHeight;
                    CollideMode := cmRect;
                    Collisioned := True;
                    FCollideRight := PatternWidth;
                    FCollideBottom:= PatternHeight;
               end;
          end
          else
         //create Enemy
          begin
               with TEnemy.Create(SpriteEngine) do
               begin
                    ImageName := MapData[i].ImageName;
                    X := MapData[i].X - 540;
                    Y := MapData[i].Y - 150;
                    Z := 15;
                    TruncMove := True;
                    Width := PatternWidth;
                    Height := PatternHeight;
                    Collisioned := True;
                    CollideMode := cmRect;
                    FCollideRight :=PatternWidth;
                    FCollideBottom:=PatternHeight;
                    State := Walkleft;
                    JumpState := jsfalling;
                    AnimCount := PatternCount;
              end;
         end;
    end;
end;


procedure SprayBox(PosX, PosY: Single);
var
   I: Integer;
begin
     for I := 0 to 6 do
     begin
          with TParticleSprite.Create(SpriteEngine) do
          begin
               ImageName := 'Star';
               X := PosX + Random(20);
               Y := PosY + Random(20);
               Z := 20;
               LifeTime := 150;
               Decay := 1;
               ScaleX := 1.2;
               ScaleY := 1.2;
               UpdateSpeed := 0.5;
               VelocityX := -4 + Random * 8;
               VelocityY := -Random * 7;
               AccelX := 0;
               AccelY := 0.2 + Random / 2;
          end;
     end;
end;

procedure TSpray.DoMove(const MoveCount: Single);
begin
     Accelerate;
     UpdatePos(1);
     Alpha := Alpha - 3;
     if Alpha < 0 then Dead;
end;

procedure SprayFruit(PosX, PosY: Single);
var
   I: Integer;
begin
     for I :=0 to 15 do
     begin
          with TSpray.Create(SpriteEngine) do
          begin
               ImageName:='flare';
               BlendMode := Blend_Add;
               X := PosX;
               Y := PosY;
               Z := 20;
               ScaleX := 0.1;
               ScaleY := 0.1;
               Red := 255;
               Green := 50;
               Blue := 0;
               Acceleration := 0.05;
               MinSpeed := 0.8;
               MaxSpeed := 1;
               Direction:= I * 16;
          end;
     end;
end;

procedure TGreenApple.DoMove(const MoveCount: Single);
begin
     inherited;
     CollideRect := Rect(Round(X),
                    Round(Y),
                    Round(X + PatternWidth),
                    Round(Y + PatternHeight));
     Collision;
end;

procedure TGreenApple.DoCollision(const Sprite: TSprite);
begin
     if (Sprite is TTile) then
     begin
          if  (TTile(Sprite).ImageName = 'Ground1')  or (TTile(Sprite).ImageName='Rock1') or ( TTile(Sprite).ImageName= 'Rock2')  then
          begin
               JumpState := jsNone;
               Y := TTile(Sprite).Y-28;
          end;
     end;
end;

procedure CreateGreenApple(PosX, PosY: Single);
begin
     Randomize;
     if Random(3) = 1 then
     begin
          with TGreenApple.Create(SpriteEngine) do
          begin
               ImageName := 'Fruit'+ IntToStr( 2 + Random(2));
               X := PosX;
               Y := PosY;
               Z := 5;
               CollideMode := cmRect;
               Collisioned := True;
               DoJump := True;
          end;
     end;
end;
function FrameFunc: Boolean;
begin
  case HGE.Input_GetKey of
    HGEK_ESCAPE:
    begin
      FreeAndNil(Canvas);
      FreeAndNil(Images);
      FreeAndNil(SpriteEngine);
      FreeAndNil(Font);
      Result := True;
      Exit;
    end;
  end;
  Result := False;
end;

procedure TTile.DoMove;
begin
     inherited;
     CollideRect := Rect(Round(X),
                    Round(Y),
                    Round(X + FCollideRight),
                    Round(Y + FCollideBottom));

     if ImageName='Spring1' then
     CollideRect := Rect(Round(X),
                    Round(Y + 25),
                    Round(X + FCollideRight),
                    Round(Y + FCollideBottom));
end;

procedure TActor.DoMove(const MoveCount: Single);
begin
     inherited;
     if Y > 1200 then
     begin
          SpriteEngine.Clear;
          CreateMap;
       //   MainForm.Music.Songs.Find('Music1').Play;
          FruitCount:=0;
          Exit;
     end;
     Left :=   Round(X + 45);
     Top :=    Round(Y + 45);
     Right :=  Round(X + 65);
     Bottom := Round(Y + 110);
     CollideRect := Rect(Left, Top, Right, Bottom);
     //falling--when walk out of tile edge
     if (Self.Right < LeftEdge) or (Self.Left > RightEdge+1) then
     begin
          if JumpState <> jsJumping then
               JumpState := jsFalling;
     end;

     if HGE.Input_GetKeyState(HGEK_RIGHT) and (state <> Die)then
     begin
          State := WalkRight;
          X := X + MoveSpeed;
          case JumpState of
               jsNone:
               begin
                     if UserRefreshRate=60 then SetAnim('Walk', 0, 12, 0.45, True, False, True);
                     if UserRefreshRate=75 then SetAnim('Walk', 0, 12, 0.4, True, False, True);
                     if UserRefreshRate=85 then SetAnim('Walk', 0, 12, 0.35, True, False, True);
                     if UserRefreshRate=100 then SetAnim('Walk', 0, 12, 0.3, True, False, True);
                     if UserRefreshRate=120 then SetAnim('Walk', 0, 12, 0.25, True, False, True);
               end;
               jsJumping: SetAnim('Jump', 0, 3, 0.06, False, False, True);
               jsFalling: SetAnim('Jump', 2, 2, 0, False, False, True);
          end;
     end;

     if HGE.Input_GetKeyState(HGEK_LEFT)and (State <> Die) then
     begin
          State := WalkLeft;
          X := X - MoveSpeed;
          case JumpState of
               jsNone:
               begin
                    if UserRefreshRate=60 then  SetAnim('Walk', 0, 12, 0.45, True, True, True);
                    if UserRefreshRate=75 then  SetAnim('Walk', 0, 12, 0.4, True, True, True);
                    if UserRefreshRate=85 then  SetAnim('Walk', 0, 12, 0.35, True, True, True);
                    if UserRefreshRate=100 then  SetAnim('Walk', 0, 12, 0.3, True, True, True);
                    if UserRefreshRate=120 then  SetAnim('Walk', 0, 12, 0.25, True, True, True);
               end;
               jsJumping: SetAnim('Jump', 0, 3, 0.06, False, True, True);
               jsFalling: SetAnim('Jump', 2, 2, 0, False, True, True);
          end;
     end;

     if HGE.Input_KeyUp(HGEK_RIGHT) and (State <> Die)then
     begin
          State := StandRight;
          if JumpState = jsNone then
               SetAnim('Idle', 0, 12, 0.25, True, False, True);
     end;

     if HGE.Input_KeyUp(HGEK_LEFT)and (State <> Die) then
     begin
          State := StandLeft;
          if JumpState = jsNone then
               SetAnim('Idle', 0, 12, 0.25, True, True, True);
     end;

     if (JumpState = jsNone) then
     begin
          if HGE.Input_KeyDown(HGEK_CTRL) or HGE.Input_KeyDown(HGEK_Space) and (state<>die)then
          begin
               DoJump := True;
            //   MainForm.Music.Songs.Items[1].Play;
               Animpos := 0;
               case State of
                    StandRight:
                    begin
                         if UserRefreshRate=60 then SetAnim('Jump', 0, 3, 0.06, True, False, True);
                         if UserRefreshRate=75 then SetAnim('Jump', 0, 3, 0.05, True, False, True);
                         if UserRefreshRate=85 then SetAnim('Jump', 0, 3, 0.04, True, False, True);
                         if UserRefreshRate=100 then SetAnim('Jump', 0, 3, 0.03, True, False, True);
                         if UserRefreshRate=120 then SetAnim('Jump', 0, 3, 0.02, True, False, True);
                    end;
                    StandLeft:
                    begin
                         if UserRefreshRate=60 then SetAnim('Jump', 0, 3, 0.06, True, True, True);
                         if UserRefreshRate=75 then SetAnim('Jump', 0, 3, 0.05, True, True, True);
                         if UserRefreshRate=85 then SetAnim('Jump', 0, 3, 0.04, True, True, True);
                         if UserRefreshRate=100 then SetAnim('Jump', 0, 3, 0.03, True, True, True);
                         if UserRefreshRate=120 then SetAnim('Jump', 0, 3, 0.03, True, True, True);
                    end;
               end;
          end;
     end;

     if Engine.WorldX < (X - 350) then
            Engine.WorldX := X - 350;

     if Engine.WorldX > (X - 345) then
            Engine.WorldX := X - 345;

     if Engine.WorldY > (Y + 50) then
           Engine.Worldy := Y + 50 ;

     if Y < 250 then
     begin
          if Engine.WorldY < (Y - 250) then
               Engine.WorldY := Y - 250;
     end;
     if UserRefreshRate = 60 then
     begin
          Layer1pos := Engine.Worldx*2*0.25-20000;
          Layer2pos := Engine.Worldx*1*0.25-20000;
     end;
     if  (UserRefreshRate=75)  then
     begin
          Layer1pos:=Engine.Worldx*1.5*0.5-20000;
          Layer2pos:=Engine.Worldx*0.5-20000;
     end;
     if  (UserRefreshRate=85)  then
     begin
          Layer1pos:=Engine.Worldx*1.5*0.5-20000;
          Layer2pos:=Engine.Worldx*1*0.5-20000;
     end;
     if  (UserRefreshRate=100)  then
     begin
          Layer1pos:=Engine.Worldx*1.5*0.5-20000;
          Layer2pos:=Engine.Worldx*1*0.5-20000;
     end;
     if  (UserRefreshRate=120)  then

⌨️ 快捷键说明

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