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

📄 shooter.dpr

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

{$R *.res}

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

type
   TBullet = class(TAnimatedSprite)
  private
    FMoveSpeed: Single;
  public
    procedure DoMove(const MoveCount: Single); override;
    procedure DoCollision(const Sprite: TSprite); override;
    property MoveSpeed: Single read FMoveSpeed write FMoveSpeed;
  end;

  TCustomShip = class(TAnimatedSprite)
  private
    FMoveSpeed: Single;
  public
    procedure SetAnim(DoMirror: Boolean; APlayMode: TAnimPlayMode);
    procedure DoMove(const MoveCount: Single); override;
    property MoveSpeed: Single read FMoveSpeed write FMoveSpeed;
  end;

  TTail = class(TAnimatedSprite)
  private
    FMoveSpeed: Single;
  public
    procedure DoMove(const MoveCount: Single); override;
    property MoveSpeed: Single read FMoveSpeed write FMoveSpeed;
  end;

  TShip = class(TCustomShip)
  private
    FShadow: TCustomShip;
    FTail: TTail;
  public
    constructor Create(const AParent: TSprite); override;
    property Shadow: TCustomShip read FShadow write FShadow;
    property Tail: TTail read FTail write FTail;
  end;

  TEnemy = class(TAnimatedSprite)
  private
    FAI: Integer;
    FVelocity1: Single;
    FVelocity2: Single;
    Curve: Integer;
    OriginalX: Single;
    FShadow: TEnemy;
  public
    procedure DoMove(const MoveCount: Single); override;
    property AI: Integer read FAI write FAI;
    property Velocity1: Single read FVelocity1 write FVelocity1;
    property Velocity2: Single read FVelocity2 write FVelocity2;
    property Shadow: TEnemy read FShadow write FShadow;
  end;

  TCloud = class(TAnimatedSprite)
  private
    FSize: Single;
    FValue: Single;
  public
    procedure DoMove(const MoveCount: Single); override;
    property Size : Single read FSize write FSize;
    property Value : Single read FValue  write FValue;
  end;

var
  HGE: IHGE = nil;
  Images: THGEimages;
  Canvas: THGECanvas;
  Font: TSysFont;
  SpriteEngine: TSpriteEngine;
  Y1, Y2: Integer;
  Ship: TShip;
  BackX: Single;

procedure CreateEnemy;
var
     RandEnemy: Integer;
     Enemy: TEnemy;
begin
     for RandEnemy := 0 to 3 do
     begin
          if Random(120) = 25 then
          begin
               Enemy := TEnemy.Create(SpriteEngine);
               Enemy.Shadow := TEnemy.Create(SpriteEngine);
               with Enemy do
               begin
                    X := Random(700);
                    Y := -Random(200);
                    ImageName := 'Enemy' + IntToStr(Random(5));
                    Width := PatternWidth;
                    Height := PatternHeight;
                    AnimSpeed := 0.35;
                    AnimStart := 0;
                    AnimCount := 8;
                    AnimLooped := True;
                    DoAnimate := True;
                    CollideMode := cmCircle;
                    DoCenter := False;
                    Collisioned := True;
                    CollideRadius := 16;
                    AI := Random(3);
                    OriginalX := X;
                    Velocity1 := 1;
                    Velocity2 := 2;
                    //enemy's shadow
                    Shadow.X := X + 30;
                    Shadow.Y := Y + 30;
                    Shadow.ImageName := Imagename;
                    Shadow.AnimSpeed := 0.35;
                    Shadow.AnimStart := 0;
                    Shadow.AnimCount := 8;
                    Shadow.AnimLooped := True;
                    Shadow.DoAnimate := True;
                    Shadow.DoCenter := False;
                    Shadow.AI := AI;
                    Shadow.OriginalX := X + 40;
                    Shadow.Velocity1 := 1;
                    Shadow.Velocity2 := 2;
                    Shadow.Red := 0;
                    Shadow.Green := 0;
                    Shadow.Blue := 0;
                    Shadow.Alpha := 50;
                    Shadow.ScaleX := 0.7;
                    Shadow.ScaleY := 0.7;
               end;
          end;
     end;
end;

procedure CreateCloud;
var
     Cloud: TCloud;
begin
     if Random(80) = 40 then
     begin
          Cloud := TCloud.Create(SpriteEngine);
          with Cloud do
          begin
               X := Random(800);
               Y := -Random(500) - 200;
               ImageName := 'cloud' + IntToStr(Random(2));
               Width := PatternWidth;
               Height:=PatternHeight;
               ScaleY := 0.7;
               Size := 1;
               Value := 0.003;
               DoCenter := True;
               BlendMode := Blend_Add;
          end;
     end;
end;


procedure TBullet.DoMove(const MoveCount: Single);
begin
     inherited;
     Y := Y - FMoveSpeed;
     if Y < 0 then
     begin
          Dead;
          Visible := False;
     end;
     CollidePos := Point2(X + 13, Y + 8);
     Collision;
end;

procedure TBullet.DoCollision(const Sprite: TSprite);
begin
     if (Sprite is TEnemy) then
     begin
          Collisioned := False;
          Visible := False;
          Dead;
          with TEnemy(Sprite) do
          begin
               BlendMode := Blend_Add;
               ImageName := 'explode';
               AnimCount := 32;
               AnimSpeed := 0.35;
               AnimLooped := False;
               Shadow.Dead;
          end;
     end;
end;

procedure TCustomShip.SetAnim(DoMirror: Boolean; APlayMode: TAnimPlayMode);
begin
     MirrorX := DoMirror;
     AnimStart := 0;

     AnimPlayMode := APlayMode;
     AnimCount := 4;
     AnimSpeed := 0.15;
     DoAnimate := True;
end;

procedure TCustomShip.DoMove(const MoveCount: Single);

begin
     inherited;
    //move Right
     if HGE.Input_GetKeyState(HGEK_RIGHT) then
     begin
          X := X + FMoveSpeed;
          if X > 560 then X:=560;
          if Trunc(AnimPos) = 0 then
               SetAnim(False, pmForward);
     end;

     if HGE.Input_KeyUp(HGEK_RIGHT) then
          SetAnim(False, pmBackward);

     //move left
     if HGE.Input_GetKeyState(HGEK_LEFT) then
     begin
          X := X - FMoveSpeed;
          if X < -50 then X:=-50;
          if Trunc(AnimPos) = 0 then
               SetAnim(True, pmForward);
     end;

     if HGE.Input_KeyUp(HGEK_LEFT) then
          SetAnim(True, pmBackward);

     if HGE.Input_GetKeyState(HGEK_UP) then
     begin
          Y := Y - FMoveSpeed;
          if Y < -40 then Y := -40;
     end;

     if HGE.Input_GetKeyState(HGEK_DOWN) then
     begin
          Y := Y + FMoveSpeed;
          if Y > 380 then Y := 380;
     end;
     Collision;
end;

constructor TShip.Create(const AParent: TSprite);
begin
     inherited;
     X := 300;
     Y := 300;
     ScaleX := 0.5;
     ScaleY := 0.5;
     MoveSpeed := 2;
     ImageName := 'ship4';
     Animlooped:=False;
  // self shadow
     Shadow := TCustomShip.Create(SpriteEngine);
     Shadow.X := 300;
     Shadow.Y := 250;
     Shadow.ScaleX := 0.4;
     Shadow.ScaleY := 0.4;
     Shadow.MoveSpeed := 1.2;
     Shadow.Red := 0;
     Shadow.Green := 0;
     Shadow.Blue := 0;
     Shadow.Alpha := 80;
     Shadow.ImageName := 'ship4';
  //
     Tail := TTail.Create(SpriteEngine);
     Tail.X := 322;
     Tail.Y := 356;
     Tail.ScaleX := 0.5;
     Tail.ScaleY := 0.65;
     Tail.MoveSpeed := 2;
     Tail.ImageName := 'tail';
     Tail.AnimSpeed := 0.1;
     Tail.AnimStart := 0;
     Tail.AnimCount := 3;
     Tail.AnimLooped := True;
     Tail.DoAnimate := True;
     Tail.BlendMode := Blend_Add;
end;

procedure TTail.DoMove(const MoveCount: Single);
begin
     inherited;
     if HGE.Input_GetKeyState(HGEK_RIGHT) then
     begin
          X := X + FMoveSpeed;
          if X > 582 then X := 582;
     end;
     if HGE.Input_GetKeyState(HGEK_LEFT) then
     begin
          X := X - FMoveSpeed;
          if x<-30 then X:=-30;
     end;
     if HGE.Input_GetKeyState(HGEK_UP) then
          Y := Y - FMoveSpeed;

     if HGE.Input_GetKeyState(HGEK_DOWN) then
     begin
          Y := Y + FMoveSpeed;
          if Y > 440 then Y:=440;
     end;
end;

procedure TEnemy.DoMove(const MoveCount: Single);
begin
     inherited;

     CollidePos := Point2(X + 32, Y + 32);
     if ImageName = 'explode' then
     begin
          Collisioned := False;
          Velocity1 := 0;
          Velocity2 := 0;
          if Trunc(AnimPos) = 31 then
               Dead;
      end;
    // AI = 0 just move the enemy downwards
    // AI = 1 move the enemy down in a nice sinus curve
    // AI = 2 make the enemy hunt the player
     case FAI of
          0: begin
                    Y := Y + Velocity2;
             end;
          1: begin
                    Y := Y + Velocity1;
                    Curve := Curve + Round(Velocity1);
                    X := OriginalX + Round(100 * sin(2 * PI * Curve / 360));
             end;
          2: begin
                    Y := Y + Velocity2;
                    if Ship.X > X then X := X + Velocity1;
                    if Ship.X < X then X := X - Velocity1;
             end;
     end;
     // if the enemy goes out of screen clear it out of memory
     if (Y > 600) then
     begin
          Dead;
          Visible := False;
          Collisioned := False;
     end;
end;

procedure TCloud.DoMove(const MoveCount: Single);
begin
     inherited;
     Y := Y + 0.8;
     FSize := FSize + FValue;
     if (FSize > 1) or (FSize < 0.9) then FValue := -FValue;
     ScaleX := FSize;
     if HGE.Input_GetKeyState(HGEK_RIGHT) then
          X := X - 0.35;
     if HGE.Input_GetKeyState(HGEK_LEFT) then
          X := X +0.35;
     if Y > 600 then
     begin
          Dead;
          Visible := False;
     end;
end;


function FrameFunc: Boolean;
var
   I: Integer;
   Bullet: TBullet;
begin
   if HGE.Input_KeyDown(HGEK_CTRL) or  HGE.Input_KeyDown(HGEK_SPACE) then
    begin
          for I := 0 to 1 do
          begin
               Bullet := TBullet.Create(SpriteEngine);
               Bullet.Collisioned := True;
               Bullet.CollideMode := cmCircle;
               Bullet.CollideRadius := 5;
               Bullet.MoveSpeed := 7;
               Bullet.DoCenter := False;
               Bullet.X := Ship.X + 10;
               if i = 1 then Bullet.X := Ship.X + 28;
               Bullet.Y := Ship.Y + 10;
               Bullet.ImageName := 'Bulletr';
               Bullet.BlendMode := Blend_Add;
               Bullet.ScaleX := 0.1;
               Bullet.ScaleY := 0.15;
               Bullet.MirrorY := True;
          end;
     end;

  case HGE.Input_GetKey of
    HGEK_ESCAPE:
    begin
      FreeAndNil(Canvas);
      FreeAndNil(Images);
      FreeAndNil(SpriteEngine);
      Result := True;
      Exit;
    end;
  end;
  Result := False;
end;

function RenderFunc: Boolean;
begin
  HGE.Gfx_BeginScene;
  HGE.Gfx_Clear(0);
  Canvas.DrawPart(Images.Image['jungle'], BackX, 0, 0, Y1, 800, 1024 , $FFFFFFFF, Blend_Default);
  Y1 := Y1 - 1;
  Y2 := Y2 + 1;
  CreateEnemy;
  CreateCloud;
  SpriteEngine.Draw;
  SpriteEngine.Move(1);
  SpriteEngine.Dead;
  if HGE.Input_GetKeyState(HGEK_RIGHT) then
      BackX := BackX - 0.25;
  if HGE.Input_GetKeyState(HGEK_LEFT) then
      BackX := BackX + 0.25;
  Ship.Shadow.PatternIndex := Ship.PatternIndex;
  HGE.Gfx_EndScene;
  Result := False;
end;

procedure Main;
var
  I: Integer;
begin
  HGE := HGECreate(HGE_VERSION);
  HGE.System_SetState(HGE_FRAMEFUNC,FrameFunc);
  HGE.System_SetState(HGE_RENDERFUNC,RenderFunc);
  HGE.System_SetState(HGE_USESOUND, False);
  HGE.System_SetState(HGE_WINDOWED,False);
  HGE.System_SetState(HGE_SCREENWIDTH, 640);
  HGE.System_SetState(HGE_SCREENHEIGHT,480);
  HGE.System_SetState(HGE_SCREENBPP,16);
  HGE.System_SetState(HGE_FPS,HGEFPS_VSYNC);
  Canvas := THGeCanvas.Create;
  Images := THGEImages.Create;
  SpriteEngine := TSpriteEngine.Create(nil);
  Spriteengine.Images := Images;
  SpriteEngine.Canvas := Canvas;

  if (HGE.System_Initiate) then
  begin
    Images.LoadFromFile('bulletr.png');
    Images.LoadFromFile('cloud0.png');
    Images.LoadFromFile('cloud1.png');
    Images.LoadFromFile('enemy0.png',64,64);
    Images.LoadFromFile('enemy1.png',64,64);
    Images.LoadFromFile('enemy2.png',64,64);
    Images.LoadFromFile('enemy3.png',64,64);
    Images.LoadFromFile('enemy4.png',64,64);
    Images.LoadFromFile('explode.png',64,64);
    Images.LoadFromFile('jungle.png');
    Images.LoadFromFile('tail.png',40,20);
    Images.LoadFromFile('ship4.png',128,128);
    Ship := TShip.Create(SpriteEngine);
    Ship.Z := -5;
    BackX := -100;
    HGE.System_Start;
  end
  else
    MessageBox(0,PChar(HGE.System_GetErrorMessage),'Error',MB_OK or MB_ICONERROR or MB_SYSTEMMODAL);

  HGE.System_Shutdown;
  HGE := nil;
end;

begin
  ReportMemoryLeaksOnShutdown := True;
  Main;
end.

⌨️ 快捷键说明

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