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

📄 main.pas

📁 很好玩的一个DELPHI游戏
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{*******************************************************}
{                Magic Girl                             }
{         版权所有 (C) 2002, 2003 Rainstorey Studio     }
{         ------------------------------------------    }
{                                                       }
{                                                       }
{            游戏逻辑实现单元,也是最无聊的代码。       }
{                                                       }
{                                                       }
{         E-Mail:Rainstorey@163.com                     }
{         WebSite:http://www.Rainstorey.com             }
{*******************************************************}

//TODO:更好的方法是分解逻辑和界面代码。
unit Main;

interface

uses
  Windows,Messages,SysUtils,Classes,Graphics,MMSystem,Controls,Forms,
  DXDraws,DXClass,DXSprite,DXInput,GameClasses,DXSounds,DXFonts,DIB,
  GameConst,DIBEffect,ExtCtrls;

type
  TFMain = class(TDXForm)
    DXDraw:TDXDraw;
    Image:TDXImageList;
    DXTimer1:TDXTimer;
    SpriteEngine:TDXSpriteEngine;
    Input:TDXInput;
    WaveList:TDXWaveList;
    Sound:TDXSound;
    DXFont:TDXFont;
    Timer1:TTimer;
    procedure DXDrawInitialize(Sender:TObject);
    procedure DXDrawFinalize(Sender:TObject);
    procedure FormCreate(Sender:TObject);
    procedure DXTimer1Timer(Sender:TObject;LagCount:Integer);
    procedure FormKeyDown(Sender:TObject;var Key:Word;
      Shift:TShiftState);
    procedure FormCloseQuery(Sender:TObject;var CanClose:Boolean);
    procedure Timer1Timer(Sender:TObject);
  private
    procedure BuildMap(const Back:Integer);
    procedure MCINOTIFY(var Message:TMessage); message MM_MCINOTIFY;
    procedure ShowDiamCount;
    procedure GameInit;
  public
    GameFullScreen:Boolean; //游戏已全屏幕显示
    FCount:Cardinal; //以100桢/秒计算,该值要等16个月后才会溢出。
    MainPlayer:TMainPlayer;
    BackMap:array[0..2] of TBackMap;
    Bullet:TBullet;
    BackPlayer:array[0..20] of TBackPlayer;
    BlueDiam,GreenDiam,YellowDiam:Integer;
    BulletOffPoint:TPoint;
    TotalScore:Cardinal;
    BossFCount:Cardinal;
    FSureFace:TDirectDrawSurface;
    LogoDIB:TDIBEffect;
    GameStatus:TGameStatus;
    ApplicationExit:Boolean;
    function CreateMainPlayer(const t:Cardinal = 0):Boolean;
    procedure GetOnArticle(ArticleType:TArticleType;Sender:TObject);
    procedure BuildEnemy;
    procedure GamePassAndAddScore;

  end;

var
  FMain:TFMain;

implementation

uses MainProcess;
{$R *.dfm}

procedure TFMain.DXDrawInitialize(Sender:TObject);
begin
  mciSendString('OPEN BGM01.mid TYPE SEQUENCER ALIAS BGM',nil,0,handle);

  DXTimer1.Enabled:=True;
  Self.Caption:= 'Demo Game';
  ShowCursor(False);
  GameInit;
  //兼容性问题
  with DXDraw.Surface.Canvas do
  begin
    Brush.Style:=bsClear;
    Font.Color:=clYellow;
    Font.Name:= 'MonoType Corsiva';
    Font.Size:=14;
  end;
  LogoDIB:=TDIBEffect.Create;
  LogoDIB.Assign(Image.Items.Find('MMLogo').Picture);
  //  FSureFace:=TDirectDrawSurface.Create(DXDraw.DDraw);

  GameStatus:=Gaming;
  DXTimer1.Interval:=0;
  GameStatus:=GameLogo;

  //WaveList.Items.Find('RainLogo').Play(false);
end;

procedure TFMain.DXDrawFinalize(Sender:TObject);
begin
  DXTimer1.Enabled:=False;
  mciSendString('STOP BGM',nil,0,handle);
  mciSendString('CLOSE ANIMATION',nil,0,handle);
  ShowCursor(True);
  GameStatus:=GameExit;
  ApplicationExit:=True;
  // FSureFace.Free;
  // FSureFace:=nil;
  // aa.Free;
end;

procedure TFMain.FormCreate(Sender:TObject);
begin
  Self.Color:=clBlack;
  DXDraw.Color:=clBlack;
  Randomize;
  ApplicationExit:=False;
  GameFullScreen:=True;
  if GameFullScreen then
  begin
    Self.BorderStyle:=bsNone;
    DXDraw.Display.Height:=600;
    DXDraw.Display.Width:=800;
    DXDraw.Display.BitCount:=16;
    DXDraw.Options:=DXDraw.Options + [doFullScreen];
    DXTimer1.Interval:=0;
  end;
  //打开硬件加速
 // DXDraw.Options:=DXDraw.Options+[do3D,doWaitVBlank,doDirectX7Mode,doHardware]-[doSystemMemory];

end;

procedure TFMain.DXTimer1Timer(Sender:TObject;LagCount:Integer);
begin
  if not (DXDraw.CanDraw) then Exit;
  DXDraw.Surface.Fill(0);
  // Image.Items.Find('DirectX').DrawAlpha(DXDraw.Surface,Bounds(0,DXDraw.SurfaceHeight - 100,40,59),0,FCount);
  // Image.Items.Find('Delphi').DrawAlpha(DXDraw.Surface,Bounds(0,DXDraw.SurfaceHeight - 41,114,41),0,FCount * 2);
  if (GameStatus = Gaming) or (GameStatus = GamePassing) then
  begin
    SpriteEngine.Move(1);
    SpriteEngine.Dead;
    SpriteEngine.Draw;
    ShowDiamCount;
    BuildEnemy;
    with DXDraw.Surface.Canvas do
    begin
      TextOut(30,10, 'FPS:' + IntToStr(DXTimer1.FrameRate));
      TextOut(30,30, 'FPSCount:' + IntToStr(FCount));
      TextOut(30,50, 'Press "Z" or "Space" key transmit bullet.Press "ESC" exit.');
      TextOut(30,70, 'SCORE:' + IntToStr(TotalScore));
      TextOut(120,DXDraw.SurfaceHeight - 30, 'RainBlog:http://www.rainstorey.com/blog');
      // TextOut(30,50,IntToStr(Trunc(TDebug)));
      Release;
    end;
    // aa.AddMonoNoise(FCount);
    // aa.Effect_AddColorNoise(fcount);
      // DXDraw.Surface.Draw(0,0,FSureFace.ClientRect,nil,True);
  { if FCount<50 then
   begin
      aa.Effect_Darkness(fcount);

    FSureFace.LoadFromDIB(aa);

    DXDraw.Surface.Draw(0,0,FSureFace.ClientRect,FSureFace,True);
    end;  }
  end;
  case GameStatus of
    GameMenu:
      begin
        LogoDIB.Assign(Image.Items.Find('MMLogo').Picture);
        LogoDIB.Effect_Mosaic(40 - FCount);

        DXDraw.Surface.LoadFromDIB(LogoDIB);
        DXDraw.Surface.Draw(0,0,DXDraw.Surface.ClientRect,DXDraw.Surface,True);
        if FCount = 200 then
        begin
          LogoDIB.Free;
          FCount:=0;
          GameStatus:=Gaming;
          mciSendString('PLAY BGM NOTIFY',nil,0,handle);
          WaveList.Items.Find('Go').Play(False);
        end;

      end;
    GameLogo:
      begin
        DXDraw.Surface.Fill(clwhite);
        Image.Items.Find('RainLogo').DrawAlpha(DXDraw.Surface,Bounds((DXDraw.Width div 2) - 215,(DXDraw.Height div 2) - 45,430,90),0,FCount);
        if FCount = 255 then
        begin
          FCount:=0;
          DXTimer1.Interval:=20;
          GameStatus:=GameMenu;
        end;
      end;
    GamePassing:GamePassAndAddScore;
    GamePass:
      begin
        LogoDIB.Emboss;
        DXDraw.Surface.LoadFromDIB(LogoDIB);
        DXDraw.Surface.Draw(0,0,DXDraw.Surface.ClientRect,DXDraw.Surface,True);
        DXTimer1.Enabled:=False;
        Timer1.Enabled:=True;
      end;
  end;
  DXDraw.Flip;
  Inc(FCount);
end;

procedure TFMain.FormKeyDown(Sender:TObject;var Key:Word;
  Shift:TShiftState);
begin
  if Key = VK_ESCAPE then Close;

end;

procedure TFMain.BuildMap(const Back:Integer);
var
  i,j:Integer;
begin
  case Back of
    0:
      begin
        for i:=0 to BackMap[Back].MapWidth - 1 do
          for j:=0 to BackMap[Back].MapHeight - 1 do
          begin
            BackMap[Back].Chips[i,j]:=Random(10);
          end;
      end;
    1:
      begin
        for i:=0 to BackMap[Back].MapWidth - 1 do
          for j:=0 to BackMap[Back].MapHeight - 1 do
          begin
            BackMap[Back].Chips[i,j]:=Random(300);
          end;
      end;
    2:
      begin
        for i:=0 to BackMap[Back].MapWidth - 1 do
          for j:=0 to BackMap[Back].MapHeight - 1 do
          begin
            BackMap[Back].Chips[i,j]:=Random(300);
          end;
      end;
  end;
end;

procedure TFMain.MCINOTIFY(var Message:TMessage);
begin
  mciSendString('SEEK BGM TO START',nil,0,handle);
  mciSendString('PLAY BGM NOTIFY',nil,0,handle);
end;

procedure TFMain.ShowDiamCount;
begin
  with DXDraw.Surface.Canvas do
  begin
    TextOut(DXDraw.SurfaceWidth - 75,6, 'X' + IntToStr(GreenDiam));
    TextOut(DXDraw.SurfaceWidth - 175,6, 'X' + IntToStr(BlueDiam));
    TextOut(DXDraw.SurfaceWidth - 275,6, 'X' + IntToStr(YellowDiam));
    Release;
  end;
  // DXFont.TextOut(DXDraw.Surface,0,52, 'SCORE:' + IntToStr(TotalScore));
end;

procedure TFMain.GameInit;
var
  i:Integer;
begin
  Image.Items.MakeColorTable;

  DXDraw.ColorTable:=Image.Items.ColorTable;
  DXDraw.DefColorTable:=Image.Items.ColorTable;
  DXDraw.UpdatePalette;

  //定义所有Sprite坐标系原点
  SpriteEngine.Engine.X:=0;
  SpriteEngine.Engine.Y:=0;
  //
  CreateMainPlayer;

  //--------------------------------
  BackMap[0]:=TBackMap.Create(SpriteEngine.Engine);
  BackMap[0].Image:=Image.Items.Find('Back0');
  BackMap[0].SetMapSize(300,DXDraw.SurfaceWidth);
  BackMap[0].Tile:=True;
  BackMap[0].Z:= -10;
  BackMap[0].Speed:=0.5;
  BackMap[0].Y:=Random(10);
  BuildMap(0);

  BackMap[1]:=TBackMap.Create(SpriteEngine.Engine);
  BackMap[1].Image:=Image.Items.Find('Back1');
  BackMap[1].SetMapSize(300,DXDraw.SurfaceWidth);
  BackMap[1].Tile:=True;
  BackMap[1].Z:= -9;
  BackMap[1].Speed:=10;
  BackMap[1].Inclined:=1;
  BackMap[1].Y:=Random(25);
  BuildMap(1);

  BackMap[2]:=TBackMap.Create(SpriteEngine.Engine);
  BackMap[2].Image:=Image.Items.Find('Back2');
  BackMap[2].SetMapSize(300,DXDraw.SurfaceWidth);
  BackMap[2].Tile:=True;
  BackMap[2].Z:= -8;
  BackMap[2].Speed:=5;
  BackMap[2].Inclined:= -2;
  BackMap[2].Y:=Random(25);
  BuildMap(2);

  for i:=0 to 5 do
  begin
    BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
    with BackPlayer[i] do
    begin
      Image:=FMain.Image.Items.Find('Back3');
      Width:=Image.Width;
      Height:=Image.Height;
      AnimCount:=Image.PatternCount - 1;
      Speed:=Random(25) + 1;
      X:=Random(DXDraw.SurfaceWidth);
      Z:=1;
    end;
  end;

  for i:=6 to 8 do
  begin
    BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
    with BackPlayer[i] do
    begin
      Image:=FMain.Image.Items.Find('Back4');
      Width:=Image.Width;
      Height:=Image.Height;
      AnimCount:=Image.PatternCount - 1;
      Speed:=Random(20) + 1;
      X:=Random(DXDraw.SurfaceWidth);
      Z:=1;
    end;
  end;

  for i:=9 to 11 do
  begin
    BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
    with BackPlayer[i] do
    begin
      Image:=FMain.Image.Items.Find('Back5');
      Width:=Image.Width;
      Height:=Image.Height;
      AnimCount:=Image.PatternCount - 1;
      Speed:=Random(20) + 1;
      X:=Random(DXDraw.SurfaceWidth);
      Z:=1;
    end;
  end;

  for i:=12 to 15 do
  begin
    BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
    with BackPlayer[i] do
    begin
      Image:=FMain.Image.Items.Find('Back6');
      Width:=Image.Width;
      Height:=Image.Height;
      AnimCount:=Image.PatternCount - 1;
      Speed:=Random(20) + 1;
      X:=Random(DXDraw.SurfaceWidth);
      Z:=1;
    end;
  end;

  for i:=16 to 17 do
  begin
    BackPlayer[i]:=TBackPlayer.Create(SpriteEngine.Engine);
    with BackPlayer[i] do
    begin
      Image:=FMain.Image.Items.Find('Back7');
      Width:=Image.Width;
      Height:=Image.Height;
      AnimCount:=Image.PatternCount - 1;
      Speed:=Random(20) + 1;
      X:=Random(DXDraw.SurfaceWidth);
      Z:=1;
    end;
  end;

  BackPlayer[18]:=TBackPlayer.Create(SpriteEngine.Engine);
  with BackPlayer[18] do
  begin
    Image:=FMain.Image.Items.Find('BlueDiamond');
    Width:=Image.Width;
    Height:=Image.Height;
    AnimCount:=Image.PatternCount - 1;
    Quiescence:=True;
    X:=DXDraw.SurfaceWidth - 200;
    Y:=0;
    Z:=10;
  end;

  BackPlayer[19]:=TBackPlayer.Create(SpriteEngine.Engine);
  with BackPlayer[19] do
  begin
    Image:=FMain.Image.Items.Find('YellowDiamond');
    Width:=Image.Width;
    Height:=Image.Height;
    AnimCount:=Image.PatternCount - 1;
    Quiescence:=True;
    X:=DXDraw.SurfaceWidth - 300;
    Y:=0;
    Z:=10;
  end;

  BackPlayer[20]:=TBackPlayer.Create(SpriteEngine.Engine);
  with BackPlayer[20] do
  begin
    Image:=FMain.Image.Items.Find('GreenDiamond');
    Width:=Image.Width;
    Height:=Image.Height;
    AnimCount:=Image.PatternCount - 1;
    Quiescence:=True;
    X:=DXDraw.SurfaceWidth - 100;
    Y:=0;
    Z:=10;
  end;
  BulletOffPoint.X:=20;
  BulletOffPoint.Y:=0;
end;

//这是一个不好的设计,因该重新考虑其它方案来取代这冗长无聊的代码!!!

procedure TFMain.BuildEnemy;
var
  i:Integer;
begin

⌨️ 快捷键说明

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