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

📄 gameclasses.pas

📁 很好玩的一个DELPHI游戏
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{*******************************************************}
{                Magic Girl                             }
{         版权所有 (C) 2002, 2003 Rainstorey Studio     }
{         -----------------------------------------     }
{         CopyRight(?)Rainstorey Soft by 2006-2008      }
{         Power DelphiX for Delphi                      }
{         This Code License for GPL                     }
{         Magic Girl Classes Definition some Classes for}
{         GameSprite in Game.                           }
{         v0.40                                         }
{         Last Modification 2006-1-6 14:51:22           }
{         E-Mail:Rainstorey@163.com                     }
{         Blog:http://www.rainstorey.com/blog           }
{         WebSite:http://www.Rainstorey.com             }
{*******************************************************}
//TODO:魔法效果未实现,某些代码有更优方案。
unit GameClasses;

interface
uses Windows,SysUtils,Classes,
  DXDraws,DXSprite,DXInput,DXSounds;

function SleepEx(const t:Cardinal):Boolean;

var
  TDebug:Double; //调试变量
  //
type
  TEnemyActivityLine = (TALLine,TALALine,TALCLine,TALC1Line,TALILine,TALJLine,TALLLine,TALL1Line,TALMLine,TALNLine,TALOLine,TALSLine,TALULine,TALVLine,TALV1Line,TALWLine,TALXLine,TALZLine,TALZ1Line,TALRandLine);
  TTransmitType = (TTRand,TTLine,TTCircle,TTRadian);
  TAccuracy = (ACLow,ACStandard,ACHigh);
  TBulletType = (BTStandard,BTFire,BTLaser,BTWave,BTMoon,BTCircle);
  TArticleType = (ArtNone,Artsupper,ArtMoon,ArtCircle,ArtWave,ArtFire,ARTLaser,ArtPointA,ArtPointB,DiamondA,DiamondB,DiamondC);
  TOnGetArticle = procedure(ArticleType:TArticleType;Sender:TObject) of object;
  TDeadSound = (BomNone,EnemyBom,PlayerBom,ArtBom,Fire,Drip,Gun,LaserGun,Bom8,Bom9);
  //  TDeadAnim = (Anim1,Anim2,Anim3,Anim4,Anim5,Anim6,Anim7,Anim8,Anim9);
  TDeadSprite = class;

  TGameSprite = class(TImageSpriteEx)
  protected
    FQuiescence:Boolean;
    FSpeed:Integer;
    FShowSound:string;
    FDeadSound:TDeadSound;
    FDeadAnimSpeed:Double;
    FDeadImage:string;
    FDeadOffRect:TPoint;
    FDeadTimes:Integer;
    procedure Hit; virtual;
    //
  public
    class procedure PalleteAnim(DX:TDXDraw;Col:TRGBQuad;Time:Integer);
    constructor Create(AParent:TSprite); override;
    destructor Destroy; override;
    procedure DoMove(MoveCount:Integer); override;
    property Speed:Integer read FSpeed write FSpeed;
    property ShowSound:string read FShowSound write FShowSound;
    property DeadSound:TDeadSound read FDeadSound write FDeadSound;
    property DeadImage:string read FDeadImage write FDeadImage;
    property DeadOffRect:TPoint read FDeadOffRect write FDeadOffRect;
    property DeadTimes:Integer read FDeadTimes write FDeadTimes;
    property Quiescence:Boolean read FQuiescence write FQuiescence;

  end;

  TDeadSprite = class(TGameSprite)
  private
    FDeadSpeed:Integer;
    FDeadTimeCount:Integer;
    FDeadTime:Double;
  public
    constructor Create(AParent:TSprite); override;
    property DeadSpeed:Integer read FDeadSpeed write FDeadSpeed;
    procedure DoMove(MoveCount:Integer); override;
  end;

  TBossDead = class(TDeadSprite)
  private
    tempx:Double;
  public
    procedure DoMove(MoveCount:Integer); override;
  end;

  TBackPlayer = class(TGameSprite)
  private
    FStop:Boolean;
  public
    property Stop:Boolean read FStop write FStop;
    procedure DoMove(MoveCount:Integer); override;
  end;

  TEnemy = class(TGameSprite)
  protected
    FHP:Integer;
    FBullet:string;
    FTransmitProbability:Integer; //百分比
    FBulletSpeed:Integer;
    FProbability:Integer; //0为最高精确度
    FBuildArt:TArticleType;
    FTransmitType:TTransmitType;
    FScore:Integer;
    FLineType:TEnemyActivityLine;
    tempx,tempy:Double;
    FisHit:Boolean;
    procedure Transmit; virtual;
    property isHit:Boolean read FisHit write FisHit;
  public
    property Bulletspeed:Integer read FBulletSpeed write FBulletSpeed;
    property TransmitProbability:Integer read FTransmitProbability write FTransmitProbability;
    property Bullet:string read FBullet write FBullet;
    procedure DoMove(MoveCount:Integer); override;
    procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
    property Hp:Integer read FHP write FHP;
    constructor Create(AParent:TSprite); override;
    destructor Destroy; override;
    property Probability:Integer read FProbability write FProbability;
    property BuildArt:TArticleType read FBuildArt write FBuildArt;
    property TransmitType:TTransmitType read FTransmitType write FTransmitType;
    property Score:Integer read FScore write FScore;
    property LineType:TEnemyActivityLine read FLineType write FLineType;
  end;

  { TBoss }

  TBoss = class(TEnemy)
  private
    FBossBomb:TDeadSound;
    tempcount:Cardinal;
    tempcount1:Cardinal;
    FShootSound:TDeadSound;
  protected
    procedure Transmit; override;
  public
    property ShootSound:TDeadSound read FShootSound write FShootSound;
    procedure DoMove(MoveCount:Integer); override;
    constructor Create(AParent:TSprite); override;
    destructor Destroy; override;

  end;

  TMainPlayer = class(TGameSprite)
  private
    FSupperTime,FSupperTotalTime:Cardinal;
    FSupper:Boolean;
    FBulletType:TBulletType;
    FBulletCounts:Integer;
    FNCanControl:Boolean;
    FShootSound:TDeadSound;
    procedure SetBulletType(const Value:TBulletType);
  protected
    procedure SetFSupper(const Value:Boolean);
  public
    property ShootSound:TDeadSound read FShootSound write FShootSound;
    property NCanControl:Boolean read FNCanControl write FNCanControl;
    property BulletType:TBulletType read FBulletType write SetBulletType;
    property SupperTotalTime:Cardinal read FSupperTotalTime write FSupperTotalTime;
    property Supper:Boolean read FSupper write SetFSupper;
    procedure DoMove(MoveCount:Integer); override;
    procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
    destructor Destroy; override;
    constructor Create(AParent:TSprite); override;
  end;

{$WARNINGS OFF}
  TBullet = class(TGameSprite)
  private
    FPower:Integer;
  public
    constructor Create(AParent:TSprite); override;
    destructor Destroy; override;
    property Power:Integer read FPower write FPower;
    procedure DoMove(MoveCount:Integer); override;
    procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
  end;

  
  TMagicBullet=class(TBullet);

  TEnemyBullet = class(TGameSprite)
  private
    FAccuracy:TAccuracy;
    FDirectionOff:Boolean;
    FPorY:Double;
    FTransmitType:TTransmitType;
  protected
    XX,YY:Shortint;
    FCircleAngle,FCircleCenter:Double;
  public
    // property MainX:Double read FMainX write FMainY;
    // property MainY:Double read FMainY write FMainY;
     //  property EnemyX:Double read FEnemyX write FEnemyX;
     //  property EnemyY:Double read FEnemyY write FEnemyY;
    property Accuracy:TAccuracy read FAccuracy write FAccuracy;
    procedure DoMove(MoveCount:Integer); override;
    procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
    constructor Create(AParent:TSprite;FEnemy:TEnemy); virtual;
  end;
{$WARNINGS ON}

  //-----------------------------------------------------------------------//
  TArticle = class(TGameSprite)
  private
    FOnGetArticle:TOnGetArticle;
    FArticleType:TArticleType;
    procedure SetArticleType(const Value:TArticleType);
  public
    property ArticleType:TArticleType read FArticleType write SetArticleType;
    property OnArticle:TOnGetArticle read FOnGetArticle write FOnGetArticle;
    procedure DoCollision(Sprite:TSprite;var Done:Boolean); override;
    procedure DoMove(MoveCount:Integer); override;
  end;
  //------------------------------------------------------------------------------
  TBackMap = class(TBackgroundSprite)
  private
    FInclined:Double;
    FSpeed:Double;
  public
    property Speed:Double read FSpeed write FSpeed;
    property Inclined:Double read FInclined write FInclined;
    procedure DoMove(MoveCount:Integer); override;

  end;
  //-------------------------------------------------------------------------//
implementation

uses Main,GameConst;
const
  BulletPower:array[0..5] of Integer = (1,5,8,4,3,2);
  BulletName:array[0..5] of string = ('Bullet', 'Bullet1', 'Bullet2', 'Bullet3', 'Bullet4', 'Bullet5');
  BulletCount:array[0..5] of Integer = (99,4,2,6,99,3);
  ArticleName:array[0..11] of string = ('', 'ArtSupper', 'ArtMoon', 'ArtCircle', 'ArtWave', 'ArtFire', 'ArtLaser', 'ArtPointA', 'ArtPointB', 'BlueDiamond', 'YellowDiamond', 'GreenDiamond');
  DeadSoundName:array[0..7] of string = ('', 'EnemyBom', 'PlayerDead', 'ArtHide', 'Fire', 'Drip', 'Gun', 'LaserGun');
  //BombTypeName
  RadianRange:Integer = 100;
var
  BulletCounts:Integer;
  GameTick1,GameTick2:Cardinal;
  { TMainPlayer }

function SleepEx(const t:Cardinal):Boolean;
begin
  GameTick2:=FMain.FCount;
  if GameTick2 - GameTick1 > t then
  begin
    GameTick1:=GameTick2;
    Result:=True;
    Exit;
  end
  else
    Result:=False;
end;

constructor TMainPlayer.Create(AParent:TSprite);
begin
  inherited Create(AParent);
  FShootSound:=Fire;

end;

destructor TMainPlayer.Destroy;
begin
  if not (FMain.GameStatus = GameExit) //Fixed GameApplication can't exit at 2006-1-10 20:33:03
  then FMain.CreateMainPlayer;
  inherited Destroy;
end;

procedure TMainPlayer.DoCollision(Sprite:TSprite;var Done:Boolean);
var
  tempx,tempy:Double;
begin
  //Magic Girl主动去撞其他精灵则发生该事件。
  Done:=False;
  if not (FSupper) then
  begin
    tempx:=Abs(Sprite.X - Self.X);
    tempy:=Abs(Sprite.Y - Self.Y);
    if (Sprite is TEnemy) or ((Sprite is TEnemyBullet) and (32 > tempx) and (tempx > 16) and (27 > tempy) and (tempy > 11)) then
      Hit;
  end;
  if (Sprite is TArticle) then
  begin
    // FMain.WaveList.Items.Find(DeadSoundName[Ord(TArticle(Sprite).DeadSound)]).Play(False);
    with Sprite as TArticle do
    begin
      if Assigned(FOnGetArticle) then
        FOnGetArticle(FArticleType,Self);
      Hit;
    end;
  end;
end;

procedure TMainPlayer.DoMove(MoveCount:Integer);
begin
  inherited DoMove(MoveCount);
  if not (FNCanControl) then
    with FMain.Input do
    begin
      Update;
      if isup in Keyboard.States then Y:=Y - FSpeed;
      if isdown in Keyboard.States then Y:=Y + FSpeed;
      if isleft in Keyboard.States then X:=X - FSpeed;
      if isright in Keyboard.States then X:=X + FSpeed;

      if (isButton1 in Keyboard.States) and (BulletCounts < FBulletCounts) and SleepEx(3) then
      begin
        with TBullet.Create(FMain.SpriteEngine.Engine) do
        begin
          Image:=FMain.Image.Items.Find(BulletName[Ord(FBulletType)]);
          Width:=Image.Width;
          Height:=Image.Height;
          Power:=BulletPower[Ord(FBulletType)];
          X:=Self.X + Self.Image.PatternWidth;
          Y:=Abs(Image.PatternHeight div 2 - Self.Y) + 15;
          DeadSound:=BomNone;
          AnimCount:=Image.PatternCount - 1;
          AnimSpeed:=0.1;
          DeadImage:= 'Hit';
          DeadTimes:=10;
          DeadOffRect:=FMain.BulletOffPoint;
          FMain.WaveList.Items.Find(DeadSoundName[Ord(FShootSound)]).Play(False);
        end;
      end;
      if (FSupper) and (FMain.FCount - FSupperTime = FSupperTotalTime) then
        Supper:=False;
      if X < 0 then X:=0;
      if X > FMain.DXDraw.Width - 48 then X:=FMain.DXDraw.Width - 48;
      if Y < 0 then Y:=0;
      if Y > FMain.DXDraw.Height - 48 then Y:=FMain.DXDraw.Height - 48;
    end;
end;

procedure TMainPlayer.SetBulletType(const Value:TBulletType);
begin
  FBulletType:=Value;
  FBulletCounts:=BulletCount[Ord(FBulletType)];
end;

procedure TMainPlayer.SetFSupper(const Value:Boolean);
begin
  FSupper:=Value;
  if FSupper then
  begin
    AnimCount:=AnimCount + 1;
    FSupperTime:=FMain.FCount;
    if FSupperTotalTime = 0 then FSupperTotalTime:=300;
  end
  else
    AnimCount:=Image.PatternCount - 1;
end;

{ TBackMap }

procedure TBackMap.DoMove(MoveCount:Integer);
begin
  inherited DoMove(MoveCount);
  X:=X - FSpeed;
  Y:=Y + FInclined;
end;

{ TBullet }

constructor TBullet.Create(AParent:TSprite);
begin
  inherited Create(AParent);
  Inc(BulletCounts);
end;

destructor TBullet.Destroy;
begin
  Dec(BulletCounts);
  inherited Destroy;
end;

procedure TBullet.DoCollision(Sprite:TSprite;var Done:Boolean);
begin
  Done:=False;
  if (Sprite is TEnemy) then
  begin
    if not (Self.Image.Name = 'Bullet2') then Hit;
    if (TEnemy(Sprite).Hp - FPower) <= 0 then
    begin
      TEnemy(Sprite).isHit:=True; //敌方被击中时才计分
      TEnemy(Sprite).Hit;
    end
    else
    begin
      FMain.WaveList.Items.Find('Water').Play(False);
      TEnemy(Sprite).Hp:=TEnemy(Sprite).Hp - FPower; //减血
    end;
  end;

end;

procedure TBullet.DoMove(MoveCount:Integer);
begin
  inherited DoMove(MoveCount);
  X:=X + 24;
  if X >= FMain.DXDraw.Width then Dead;
end;

{ TEnemy }

constructor TEnemy.Create(AParent:TSprite);
begin
  inherited Create(AParent);
  //所有需要初始化的对象写在这。
  FScore:=100;
  FBulletSpeed:=2;
  FBuildArt:=DiamondB;
end;

destructor TEnemy.Destroy;
begin
  if FMain.GameStatus <> GameExit then    //Bug is Fixed;
  begin
    if FisHit then
      Inc(FMain.TotalScore,FScore);
    if (Ord(BuildArt) <> 0) then
      with TArticle.Create(FMain.SpriteEngine.Engine) do
      begin
        ArticleType:=BuildArt;
        Speed:=1;
        X:=Self.X + Self.Image.PatternWidth div 2;
        Y:=Self.Y + Self.Image.PatternHeight div 2;
        OnArticle:=FMain.GetOnArticle;
        DeadImage:= '';
        DeadSound:=ArtBom;
      end;
  end;
  inherited Destroy;
end;

procedure TEnemy.DoCollision(Sprite:TSprite;var Done:Boolean);
begin
  if (Sprite is TMainPlayer) then
    TMainPlayer(Sprite).DoCollision(Sprite,Done);
  if Sprite is TBullet then TBullet(Sprite).DoCollision(Self,Done);

end;

procedure TEnemy.DoMove(MoveCount:Integer);
begin
  //mess design
  inherited DoMove(MoveCount);
  //对列,以左手坐标系为准。起点已右边为起点,左边为终点。
  case FLineType of
    //直线
    TALLine:
      X:=X - FSpeed;
    //C子型
    TALCLine:
      begin
        tempx:=tempx + 1;
        X:=X + Round(16 * Cos(tempx / 16 * Pi));
        Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
        if tempx = 18 then tempx:=0;
        X:=X - FSpeed;
      end;
    TALC1Line:
      begin
        tempx:=tempx + 1;
        X:=X + Round(16 * Cos(tempx / 16 * Pi));
        Y:=Y - Round(16 * Sin(tempx / 16 * Pi));
        if tempx = 27 then tempx:=0;
        X:=X - FSpeed;
      end;
    //L型
    TALILine:Y:=Y + FSpeed;

    TALJLine:
      begin
        alpha:=Trunc(tempy);
        if (X >= FMain.DXDraw.Width - Image.Height * 6) then
        begin
          tempx:=tempx + 1;
          X:=X + Round(16 * Cos(tempx / 16 * Pi));
          Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
          //  if tempx = 36 then FSpeed:= -FSpeed;
        end;
        X:=X - FSpeed;
        tempy:=tempy * 2 + 1;
        if tempy > 255 then tempy:=255;
      end;
    TALLLine:
      begin
        if Y >= FMain.DXDraw.Height - Image.Height then
          X:=X - FSpeed
        else
          Y:=Y + FSpeed;
      end;
    TALL1Line:
      begin
        if Y <= 0 then
          X:=X - FSpeed
        else
          Y:=Y - FSpeed;
      end;
    TALMLine:;
    TALNLine:;
    TALOLine:
      begin
        tempx:=tempx + 1;
        X:=X + Round(16 * Cos(tempx / 16 * Pi));
        Y:=Y + Round(16 * Sin(tempx / 16 * Pi));
      end;
    TALSLine:

⌨️ 快捷键说明

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