home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / DELPHIX.ZIP / Samples / Sprite / Shoot / Main.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-06  |  26.2 KB  |  1,177 lines

  1. unit Main;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, ExtCtrls, Menus, DXClass, DXSprite, DXInput, DXDraws,
  8.   DXSounds, DIB;
  9.  
  10. type
  11.   TGameScene = (
  12.     gsNone,
  13.     gsTitle,
  14.     gsMain,
  15.     gsGameOver
  16.   );
  17.  
  18.   TMainForm = class(TDXForm)
  19.     DXTimer: TDXTimer;
  20.     DXDraw: TDXDraw;
  21.     SpriteEngine: TDXSpriteEngine;
  22.     DXInput: TDXInput;
  23.     ImageList: TDXImageList;
  24.     DXWaveList: TDXWaveList;
  25.     DXSound: TDXSound;
  26.     MainMenu: TMainMenu;
  27.     GameMenu: TMenuItem;
  28.     GameStart: TMenuItem;
  29.     GamePause: TMenuItem;
  30.     GameExit: TMenuItem;
  31.     OptionMenu: TMenuItem;
  32.     OptionFullScreen: TMenuItem;
  33.     OptionSound: TMenuItem;
  34.     OptionShowFPS: TMenuItem;
  35.     N4: TMenuItem;
  36.     N3: TMenuItem;
  37.     N1: TMenuItem;
  38.     procedure DXDrawFinalize(Sender: TObject);
  39.     procedure DXDrawInitialize(Sender: TObject);
  40.     procedure FormCreate(Sender: TObject);
  41.     procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
  42.     procedure DXTimerActivate(Sender: TObject);
  43.     procedure DXTimerDeactivate(Sender: TObject);
  44.     procedure OptionFullScreenClick(Sender: TObject);
  45.     procedure DXDrawInitializing(Sender: TObject);
  46.     procedure GameStartClick(Sender: TObject);
  47.     procedure GamePauseClick(Sender: TObject);
  48.     procedure GameExitClick(Sender: TObject);
  49.     procedure OptionSoundClick(Sender: TObject);
  50.     procedure FormDestroy(Sender: TObject);
  51.     procedure OptionShowFPSClick(Sender: TObject);
  52.     procedure FormKeyDown(Sender: TObject; var Key: Word;
  53.       Shift: TShiftState);
  54.   private
  55.     FScene: TGameScene;
  56.     FNextScene: TGameScene;
  57.     FBlink: DWORD;
  58.     FBlinkTime: DWORD;
  59.     FEnemyAdventPos: Integer;
  60.     FFrame: Integer;
  61.     FScore: Integer;
  62.     procedure BlinkStart;
  63.     procedure BlinkUpdate;
  64.     procedure PlaySound(const Name: string; Wait: Boolean);
  65.     procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
  66.     procedure StartScene(Scene: TGameScene);
  67.     procedure StartSceneTitle;
  68.     procedure StartSceneMain;
  69.     procedure StartSceneGameOver;
  70.     procedure EndScene;
  71.     procedure EndSceneTitle;
  72.     procedure EndSceneMain;
  73.     procedure EndSceneGameOver;
  74.     procedure SceneTitle;
  75.     procedure SceneMain;
  76.     procedure SceneGameOver;
  77.   end;
  78.  
  79. var
  80.   MainForm: TMainForm;
  81.  
  82. implementation
  83.  
  84. {$R *.DFM}
  85.  
  86. type
  87.   TPlayerSprite = class(TImageSprite)
  88.   private
  89.     FCounter: Integer;
  90.     FMode: Integer;
  91.     FTamaCount: Integer;
  92.     FOldTamaTime: Integer;
  93.   protected
  94.     procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
  95.     procedure DoMove(MoveCount: Integer); override;
  96.   public
  97.     constructor Create(AParent: TSprite); override;
  98.   end;
  99.  
  100.   TTamaSprite = class(TImageSprite)
  101.   private
  102.     FPlayerSprite: TPlayerSprite;
  103.   protected
  104.     procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
  105.     procedure DoMove(MoveCount: Integer); override;
  106.   public
  107.     constructor Create(AParent: TSprite); override;
  108.     destructor Destroy; override;
  109.   end;
  110.  
  111.   TScrollBackground = class(TBackgroundSprite)
  112.   private
  113.     FSpeed: Double;
  114.   protected
  115.     procedure DoMove(MoveCount: Integer); override;
  116.   end;
  117.  
  118.   TBakuhatu = class(TImageSprite)
  119.   protected
  120.     procedure DoMove(MoveCount: Integer); override;
  121.   public
  122.     constructor Create(AParent: TSprite); override;
  123.   end;
  124.  
  125.   TEnemy = class(TImageSprite)
  126.   private
  127.     FCounter: Integer;
  128.     FLife: Integer;
  129.     FMode: Integer;
  130.     procedure Hit; virtual;
  131.   protected
  132.     procedure HitEnemy(Deaded: Boolean); virtual;
  133.   end;
  134.  
  135.   TEnemyTama = class(TEnemy)
  136.   private
  137.     FPlayerSprite: TSprite;
  138.   protected
  139.     procedure DoMove(MoveCount: Integer); override;
  140.   public
  141.     constructor Create(AParent: TSprite); override;
  142.   end;
  143.  
  144.   TEnemyUFO = class(TEnemy)
  145.   protected
  146.     procedure DoMove(MoveCount: Integer); override;
  147.     procedure HitEnemy(Deaded: Boolean); override;
  148.   public
  149.     constructor Create(AParent: TSprite); override;
  150.   end;
  151.  
  152.   TEnemyAttacker = class(TEnemy)
  153.   protected
  154.     procedure DoMove(MoveCount: Integer); override;
  155.     procedure HitEnemy(Deaded: Boolean); override;
  156.   public
  157.     constructor Create(AParent: TSprite); override;
  158.   end;
  159.  
  160.   TEnemyBoss = class(TEnemy)
  161.   private
  162.     FCounter: Integer;
  163.     FTamaF: Integer;
  164.     FTamaT: Integer;
  165.     FPutTama: Boolean;
  166.   protected
  167.     procedure DoMove(MoveCount: Integer); override;
  168.     procedure HitEnemy(Deaded: Boolean); override;
  169.   public
  170.     constructor Create(AParent: TSprite); override;
  171.   end;
  172.  
  173. {  Enemy appearance table  }
  174.   TSpriteClass = class of TSprite;
  175.  
  176.   TEnemyAdvent = record
  177.     f: Integer;       {  Frame No  }
  178.     c: TSpriteClass;  {  Class  }
  179.     x: Integer;       {  X  }
  180.     y: Integer;       {  Y  }
  181.   end;
  182.  
  183. const
  184.   EnemyAdventTable: array[0..27] of TEnemyAdvent = (
  185.     (f: 100; c: TEnemyUFO; x: 0; y: 0),
  186.     (f: 100; c: TEnemyUFO; x: 0; y: 120),
  187.     (f: 100; c: TEnemyUFO; x: 0; y: 240),
  188.     (f: 100; c: TEnemyUFO; x: 0; y: 360),
  189.  
  190.     (f: 200; c: TEnemyUFO; x: 0; y: 60),
  191.     (f: 200; c: TEnemyUFO; x: 0; y: 180),
  192.     (f: 200; c: TEnemyUFO; x: 0; y: 300),
  193.     (f: 200; c: TEnemyUFO; x: 0; y: 420),
  194.  
  195.     (f: 300; c: TEnemyUFO; x: 0; y: -60),
  196.     (f: 300; c: TEnemyUFO; x: 0; y: 60),
  197.     (f: 300; c: TEnemyUFO; x: 0; y: 180),
  198.     (f: 300; c: TEnemyUFO; x: 0; y: 300),
  199.  
  200.     (f: 400; c: TEnemyAttacker; x: 0; y: 100),
  201.     (f: 420; c: TEnemyAttacker; x: 0; y: 200),
  202.     (f: 440; c: TEnemyAttacker; x: 0; y: 300),
  203.     (f: 450; c: TEnemyAttacker; x: 0; y: 200),
  204.     (f: 455; c: TEnemyAttacker; x: 0; y: 100),
  205.  
  206.     (f: 460; c: TEnemyUFO; x: 0; y: 240),
  207.     (f: 470; c: TEnemyUFO; x: 0; y: 240),
  208.     (f: 480; c: TEnemyUFO; x: 0; y: 240),
  209.     (f: 490; c: TEnemyUFO; x: 0; y: 240),
  210.     (f: 500; c: TEnemyUFO; x: 0; y: 240),
  211.  
  212.     (f: 520; c: TEnemyAttacker; x: 0; y: 240),
  213.     (f: 530; c: TEnemyAttacker; x: 0; y: 240),
  214.     (f: 540; c: TEnemyAttacker; x: 0; y: 240),
  215.     (f: 550; c: TEnemyAttacker; x: 0; y: 240),
  216.     (f: 560; c: TEnemyAttacker; x: 0; y: 240),
  217.  
  218.     (f: 600; c: TEnemyBoss; x: 0; y: 200)
  219.   );
  220.  
  221.  
  222. {  TPlayerSprite  }
  223.  
  224. constructor TPlayerSprite.Create(AParent: TSprite);
  225. begin
  226.   inherited Create(AParent);
  227.   Image := MainForm.ImageList.Items.Find('Machine');
  228.   Width := Image.Width;
  229.   Height := Image.Height;
  230.  
  231.   X := 20;
  232.   Y := 240-Height div 2;
  233.   Z := 2;
  234.  
  235.   AnimCount := Image.PatternCount;
  236.   AnimLooped := True;
  237.   AnimSpeed := 15/1000;
  238. end;
  239.  
  240. procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
  241. begin
  242.   if Sprite is TEnemy then
  243.   begin
  244.     MainForm.PlaySound('Explosion', False);
  245.     Collisioned := False;
  246.     FCounter := 0;
  247.     FMode := 1;
  248.     Done := False;
  249.  
  250.  
  251.     {  Image change  }
  252.     Image := MainForm.ImageList.Items.Find('Explosion');
  253.     Width := Image.Width;
  254.     Height := Image.Height;
  255.  
  256.     AnimCount := Image.PatternCount;
  257.     AnimLooped := False;
  258.     AnimSpeed := 15/1000;
  259.     AnimPos := 0;
  260.   end;
  261. end;
  262.  
  263. procedure TPlayerSprite.DoMove(MoveCount: Integer);
  264. begin
  265.   inherited DoMove(MoveCount);
  266.  
  267.   if FMode=0 then
  268.   begin
  269.     {  Existing now  }
  270.     if isUp in MainForm.DXInput.States then
  271.       Y := Y - (250/1000)*MoveCount;
  272.  
  273.     if isDown in MainForm.DXInput.States then
  274.       Y := Y + (250/1000)*MoveCount;
  275.  
  276.     if isLeft in MainForm.DXInput.States then
  277.       X := X - (250/1000)*MoveCount;
  278.  
  279.     if isRight in MainForm.DXInput.States then
  280.       X := X + (250/1000)*MoveCount;
  281.  
  282.     if X<0 then X := 0;
  283.     if X>640-Width then X := 640-Width;
  284.     if Y<0 then Y := 0;
  285.     if Y>480-Height then Y := 480-Height;
  286.  
  287.     if isButton1 in MainForm.DXInput.States then
  288.     begin
  289.       {  Bounce launching  }
  290.       if (FTamaCount<8) and (FCounter-FOldTamaTime>=100) then
  291.       begin
  292.         Inc(FTamaCount);
  293.         with TTamaSprite.Create(Engine) do
  294.         begin
  295.           FPlayerSprite := Self;
  296.           X := Self.X+Self.Width;
  297.           Y := Self.Y+Self.Height div 2-Height div 2;
  298.           Z := 10;
  299.         end;
  300.  
  301.         FOldTamaTime := FCounter;
  302.       end;
  303.     end;
  304.  
  305.     Collision;
  306.   end else if FMode=1 then
  307.   begin
  308.     {  death  }
  309.     if FCounter>200 then
  310.     begin
  311.       FCounter := 0;
  312.       FMode := 2;
  313.       Visible := False;
  314.     end;
  315.   end else if FMode=2 then
  316.   begin
  317.     {  Game over!!  }
  318.     if FCounter>1500 then
  319.     begin
  320.       MainForm.FNextScene := gsGameOver;
  321.  
  322.       MainForm.PlaySound('SceneMov', False);
  323.       MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
  324.       Sleep(200);
  325.     end;
  326.   end;
  327.  
  328.   FCounter := FCounter + MoveCount;
  329. end;
  330.  
  331. {  TTamaSprite  }
  332.  
  333. constructor TTamaSprite.Create(AParent: TSprite);
  334. begin
  335.   inherited Create(AParent);
  336.   Image := MainForm.ImageList.Items.Find('Bounce');
  337.   Z := 2;                                       
  338.   Width := Image.Width;
  339.   Height := Image.Height;
  340.  
  341.   AnimCount := Image.PatternCount;
  342.   AnimLooped := True;
  343.   AnimSpeed := 15/1000;
  344. end;
  345.  
  346. destructor TTamaSprite.Destroy;
  347. begin
  348.   Dec(FPlayerSprite.FTamaCount);
  349.   inherited Destroy;
  350. end;
  351.  
  352. procedure TTamaSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
  353. begin
  354.   if (Sprite is TEnemy) and (not (Sprite is TEnemyTama)) then
  355.   begin
  356.     TEnemy(Sprite).Hit;
  357.     Dead;
  358.   end;
  359.   Done := False;
  360. end;
  361.  
  362. procedure TTamaSprite.DoMove(MoveCount: Integer);
  363. begin
  364.   inherited DoMove(MoveCount);
  365.   X := X+(800/1000)*MoveCount;
  366.  
  367.   if X>=640 then Dead;
  368.  
  369.   Collision;
  370. end;
  371.  
  372. {  TScrollBackground  }
  373.  
  374. procedure TScrollBackground.DoMove(MoveCount: Integer);
  375. begin
  376.   inherited DoMove(MoveCount);
  377.   X := X - MoveCount*(60/1000)*FSpeed;
  378. end;
  379.  
  380. {  TBakuhatu  }
  381.  
  382. constructor TBakuhatu.Create(AParent: TSprite);
  383. begin
  384.   inherited Create(AParent);
  385.   Image := MainForm.ImageList.Items.Find('Explosion');
  386.   Width := Image.Width;
  387.   Height := Image.Height;
  388.  
  389.   AnimCount := Image.PatternCount;
  390.   AnimLooped := True;
  391.   AnimSpeed := 15/1000;
  392.   AnimPos := Random(AnimCount);
  393. end;
  394.  
  395. procedure TBakuhatu.DoMove(MoveCount: Integer);
  396. begin
  397.   inherited DoMove(MoveCount);
  398. end;
  399.  
  400. {  TEnemyTama  }
  401.  
  402. constructor TEnemyTama.Create(AParent: TSprite);
  403. begin
  404.   inherited Create(AParent);
  405.   Image := MainForm.ImageList.Items.Find('Bounce');
  406.   Width := Image.Width;
  407.   Height := Image.Height;
  408.  
  409.   AnimCount := Image.PatternCount;
  410.   AnimLooped := True;
  411.   AnimSpeed := 15/1000;
  412. end;
  413.  
  414. procedure TEnemyTama.DoMove(MoveCount: Integer);
  415. begin
  416.   inherited DoMove(MoveCount);
  417.   X := X - MoveCount*(600/1000);
  418.  
  419.   if X<-Width then Dead;
  420. end;
  421.  
  422. {  TEnemy  }
  423.  
  424. procedure TEnemy.Hit;
  425. begin
  426.   Dec(FLife);
  427.   if FLife<=0 then
  428.   begin
  429.     Collisioned := False;
  430.     HitEnemy(True);
  431.   end else
  432.     HitEnemy(False);
  433. end;
  434.  
  435. procedure TEnemy.HitEnemy(Deaded: Boolean);
  436. begin
  437.   if Deaded then
  438.     MainForm.PlaySound('Explosion', False);
  439. end;
  440.  
  441. {  TEnemyUFO  }
  442.  
  443. constructor TEnemyUFO.Create(AParent: TSprite);
  444. begin
  445.   inherited Create(AParent);
  446.   Image := MainForm.ImageList.Items.Find('Enemy-disk');
  447.   Width := Image.Width;
  448.   Height := Image.Height;
  449.  
  450.   AnimCount := Image.PatternCount;
  451.   AnimLooped := True;
  452.   AnimSpeed := 15/1000;
  453. end;
  454.  
  455. procedure TEnemyUFO.HitEnemy(Deaded: Boolean);
  456. begin
  457.   if Deaded then
  458.   begin
  459.     MainForm.PlaySound('Explosion', False);
  460.     FMode := 2;
  461.     FCounter := 0;
  462.  
  463.     Inc(MainForm.FScore, 1000);
  464.  
  465.     {  Image change  }
  466.     Image := MainForm.ImageList.Items.Find('Explosion');
  467.     Width := Image.Width;
  468.     Height := Image.Height;
  469.  
  470.     AnimCount := Image.PatternCount;
  471.     AnimLooped := False;
  472.     AnimSpeed := 15/1000;
  473.     AnimPos := 0;
  474.   end;
  475. end;
  476.  
  477. procedure TEnemyUFO.DoMove(MoveCount: Integer);
  478. begin
  479.   inherited DoMove(MoveCount);
  480.  
  481.   if FMode=0 then
  482.   begin
  483.     {  Existing now  }
  484.     X := X - MoveCount*(300/1000);
  485.     Y := Y + Cos256(FCounter div 15)*2;
  486.  
  487.     if X<-Width then Dead;
  488.   end else if FMode=2 then
  489.   begin
  490.     {  death  }
  491.     X := X - MoveCount*(300/1000);
  492.     if FCounter>200 then
  493.       Dead;
  494.   end;
  495.                        
  496.   FCounter := FCounter + MoveCount;
  497. end;
  498.  
  499. {  TEnemyAttacker  }
  500.  
  501. constructor TEnemyAttacker.Create(AParent: TSprite);
  502. begin
  503.   inherited Create(AParent);
  504.   Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
  505.   Width := Image.Width;
  506.   Height := Image.Height;
  507.  
  508.   AnimCount := Image.PatternCount;
  509.   AnimLooped := True;
  510.   AnimSpeed := 15/1000;
  511. end;
  512.  
  513. procedure TEnemyAttacker.HitEnemy(Deaded: Boolean);
  514. begin
  515.   if Deaded then
  516.   begin
  517.     MainForm.PlaySound('Explosion', False);
  518.     FMode := 2;
  519.     FCounter := 0;
  520.  
  521.     Inc(MainForm.FScore, 1000);
  522.  
  523.     {  Image change  }
  524.     Image := MainForm.ImageList.Items.Find('Explosion');
  525.     Width := Image.Width;
  526.     Height := Image.Height;
  527.  
  528.     AnimCount := Image.PatternCount;
  529.     AnimLooped := False;
  530.     AnimSpeed := 15/1000;
  531.     AnimPos := 0;
  532.   end;
  533. end;
  534.  
  535. procedure TEnemyAttacker.DoMove(MoveCount: Integer);
  536. begin
  537.   inherited DoMove(MoveCount);
  538.  
  539.   if FMode=0 then
  540.   begin
  541.     {  Existing now  }
  542.     X := X - MoveCount*(300/1000)-FCounter div 128;
  543.  
  544.     if X<-Width then Dead;
  545.   end else if FMode=2 then
  546.   begin
  547.     {  death  }
  548.     X := X - MoveCount*(300/1000);
  549.     if FCounter>200 then
  550.       Dead;
  551.   end;
  552.  
  553.   FCounter := FCounter + MoveCount;
  554. end;
  555.  
  556. {  TEnemyBoss  }
  557.  
  558. constructor TEnemyBoss.Create(AParent: TSprite);
  559. begin
  560.   inherited Create(AParent);
  561.   Image := MainForm.ImageList.Items.Find('Enemy-boss');
  562.   Width := Image.Width;
  563.   Height := Image.Height;
  564.  
  565.   AnimCount := Image.PatternCount;
  566.   AnimLooped := True;
  567.   AnimSpeed := 15/1000;
  568.   PixelCheck := True;
  569.  
  570.   Collisioned := False;
  571.              
  572.   FLife := 20;
  573. end;
  574.  
  575. procedure TEnemyBoss.HitEnemy(Deaded: Boolean);
  576. begin
  577.   if Deaded then
  578.   begin
  579.     MainForm.PlaySound('Explosion', False);
  580.     FMode := 2;
  581.     FCounter := 0;
  582.  
  583.     Inc(MainForm.FScore, 100000);
  584.   end else
  585.   begin
  586.     MainForm.PlaySound('kan!!', False);
  587.     Inc(MainForm.FScore, 100);
  588.   end;
  589. end;
  590.  
  591. procedure TEnemyBoss.DoMove(MoveCount: Integer);
  592. var
  593.   i: Integer;
  594. begin
  595.   inherited DoMove(MoveCount);
  596.  
  597.   if FMode=0 then
  598.   begin
  599.     {  Appearance  }
  600.     if X>450 then
  601.       X := X - MoveCount*(300/1000)
  602.     else
  603.     begin
  604.       Collisioned := True;
  605.       FMode := 1;
  606.       FPutTama := True;
  607.     end;
  608.  
  609.     Y := Y + Cos256(FCounter div 15)*5;
  610.   end else if FMode=1 then
  611.   begin
  612.     {  Attack  }
  613.     Y := Y + Cos256(FCounter div 15)*5;
  614.  
  615.     if FPutTama then
  616.     begin
  617.       if FTamaT>100 then
  618.       begin
  619.         {  Bounce launching  }
  620.         with TEnemyTama.Create(Engine) do
  621.         begin
  622.           FPlayerSprite := Self;
  623.           Z := 1;
  624.           X := Self.X-Width;
  625.           Y := Self.Y+Self.Height div 2-Height div 2;
  626.         end;
  627.  
  628.         Inc(FTamaF);
  629.         if FTamaF>Random(30) then
  630.           FPutTama := False;
  631.  
  632.         FTamaT := 0;
  633.       end;
  634.  
  635.       FTamaT := FTamaT + MoveCount;
  636.     end else
  637.     begin
  638.       FTamaT := FTamaT + MoveCount;
  639.       if FTamaT>2000+Random(500) then
  640.       begin
  641.         FPutTama := True;
  642.         FTamaF := 0;
  643.         FTamaT := 0;
  644.       end;
  645.     end;
  646.   end else if FMode=2 then
  647.   begin
  648.     {  death  }
  649.     for i:=0 to 20 do
  650.     begin
  651.       with TBakuhatu.Create(Engine) do
  652.       begin
  653.         Z := 10;
  654.         X := Self.X+Random(Self.Width)-16;
  655.         Y := Self.Y+Random(Self.Height)-16;
  656.       end;
  657.  
  658.     Inc(MainForm.FScore, 1000);
  659.    end;
  660.  
  661.    FMode := 3;
  662.   end else if FMode=3 then
  663.   begin
  664.     {  Game clear!!  }
  665.     if FCounter>3000 then
  666.     begin
  667.       MainForm.FNextScene := gsGameOver;
  668.  
  669.       MainForm.PlaySound('SceneMov', False);
  670.       MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
  671.       Sleep(200);
  672.     end;
  673.   end;
  674.  
  675.   FCounter := FCounter + MoveCount;
  676. end;
  677.  
  678. procedure TMainForm.FormCreate(Sender: TObject);
  679. begin
  680.   ImageList.Items.MakeColorTable;
  681.  
  682.   DXDraw.ColorTable := ImageList.Items.ColorTable;
  683.   DXDraw.DefColorTable := ImageList.Items.ColorTable;
  684.   DXDraw.UpdatePalette;
  685.  
  686.   {  Window mode  }
  687.   OptionFullScreen.Checked := True;
  688.   OptionFullScreenClick(OptionFullScreen);
  689.  
  690.   {  Sound on  }
  691.   OptionSound.Checked := False;
  692.   OptionSoundClick(OptionSound);
  693.  
  694.  
  695.   GameStartClick(GameStart);
  696. end;
  697.  
  698. procedure TMainForm.FormDestroy(Sender: TObject);
  699. begin
  700.   DXTimer.Enabled := False;
  701. end;
  702.  
  703. procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  704.   Shift: TShiftState);
  705. begin
  706.   if (ssAlt in Shift) and (Key=VK_RETURN) then
  707.   begin
  708.     OptionFullScreenClick(OptionFullScreen)
  709.   end;
  710. end;
  711.  
  712. procedure TMainForm.GameStartClick(Sender: TObject);
  713. begin
  714.   {  From the start  }
  715.   StartScene(gsTitle);
  716. end;
  717.  
  718. procedure TMainForm.GamePauseClick(Sender: TObject);
  719. begin
  720.   {  Pause  }
  721.   GamePause.Checked := not GamePause.Checked;
  722.   DXTimer.Enabled := not GamePause.Checked;
  723. end;
  724.  
  725. procedure TMainForm.GameExitClick(Sender: TObject);
  726. begin
  727.   Close;
  728. end;
  729.  
  730. procedure TMainForm.OptionFullScreenClick(Sender: TObject);
  731. begin
  732.   {  Screen mode change  }
  733.   OptionFullScreen.Checked := not OptionFullScreen.Checked;
  734.  
  735.   if OptionFullScreen.Checked then
  736.   begin
  737.     {  FullScreen mode  }
  738.     DXDraw.Finalize;
  739.  
  740.     if not (doFullScreen in DXDraw.Options) then
  741.       StoreWindow;
  742.  
  743.     DXDraw.Options := DXDraw.Options + [doFullScreen];
  744.     DXDraw.Display.Width := 640;
  745.     DXDraw.Display.Height := 480;
  746.     DXDraw.Display.BitCount := 8;
  747.     DXDraw.Initialize;
  748.   end else
  749.   begin
  750.     {  Window mode  }
  751.     DXDraw.Finalize;
  752.  
  753.     if doFullScreen in DXDraw.Options then
  754.       RestoreWindow;
  755.  
  756.     DXDraw.Options := DXDraw.Options - [doFullScreen];
  757.     DXDraw.Display.Width := 640;
  758.     DXDraw.Display.Height := 480;
  759.     DXDraw.Display.BitCount := 8;
  760.     DXDraw.Initialize;
  761.   end;
  762. end;
  763.  
  764. procedure TMainForm.OptionSoundClick(Sender: TObject);
  765. begin
  766.   {  Sound  }
  767.   OptionSound.Checked := not OptionSound.Checked;
  768.  
  769.   if OptionSound.Checked then
  770.   begin
  771.     if not DXSound.Initialized then
  772.     begin
  773.       try
  774.         DXSound.Initialize;
  775.       except
  776.         OptionSound.Checked := False;
  777.       end;
  778.     end;
  779.   end else
  780.     DXSound.Finalize;
  781. end;
  782.  
  783. procedure TMainForm.OptionShowFPSClick(Sender: TObject);
  784. begin
  785.   OptionShowFPS.Checked := not OptionShowFPS.Checked;
  786. end;
  787.  
  788. procedure TMainForm.DXDrawInitializing(Sender: TObject);
  789. begin
  790.   if doFullScreen in DXDraw.Options then
  791.   begin
  792.     BorderStyle := bsNone;
  793.     DXDraw.Cursor := crNone;
  794.   end else
  795.   begin
  796.     BorderStyle := bsSingle;
  797.     DXDraw.Cursor := crDefault;
  798.   end;
  799. end;
  800.  
  801. procedure TMainForm.DXDrawInitialize(Sender: TObject);
  802. begin
  803.   DXTimer.Enabled := True;
  804. end;
  805.  
  806. procedure TMainForm.DXDrawFinalize(Sender: TObject);
  807. begin
  808.   DXTimer.Enabled := False;
  809. end;
  810.  
  811. procedure TMainForm.DXTimerActivate(Sender: TObject);
  812. begin
  813.   Caption := Application.Title;
  814. end;
  815.  
  816. procedure TMainForm.DXTimerDeactivate(Sender: TObject);
  817. begin
  818.   Caption := Application.Title + ' [Pause]';
  819. end;
  820.  
  821. procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
  822. begin
  823.   if not DXDraw.CanDraw then exit;
  824.  
  825.   DXInput.Update;
  826.  
  827.   case FScene of
  828.     gsTitle   : SceneTitle;
  829.     gsMain    : SceneMain;
  830.     gsGameOver: SceneGameOver;
  831.   end;
  832.  
  833.   if FNextScene<>gsNone then
  834.   begin
  835.     StartScene(FNextScene);
  836.     FNextScene := gsNone;
  837.   end;
  838.  
  839.   if OptionShowFPS.Checked then
  840.   begin
  841.     {  Frame rate display  }
  842.     with DXDraw.Surface.Canvas do
  843.     begin
  844.       Brush.Style := bsClear;
  845.       Font.Color := clWhite;
  846.       Font.Size := 12;
  847.       Textout(0, 0, 'FPS: '+inttostr(DXTimer.FrameRate));
  848.       Release;
  849.     end;
  850.   end;
  851.  
  852.   DXDraw.Flip;
  853. end;
  854.  
  855. procedure TMainForm.BlinkStart;
  856. begin
  857.   FBlink := 0;
  858.   FBlinkTime := GetTickCount;
  859. end;
  860.  
  861. procedure TMainForm.BlinkUpdate;
  862. begin
  863.   if GetTickCount<>FBlinkTime then
  864.   begin
  865.     FBlink := FBlink + (GetTickCount-FBlinkTime);
  866.     FBlinkTime := GetTickCount;
  867.   end;
  868. end;
  869.  
  870. procedure TMainForm.PlaySound(const Name: string; Wait: Boolean);
  871. begin
  872.   if OptionSound.Checked then
  873.   begin
  874.     DXWaveList.Items.Find(Name).Play(Wait);
  875.   end;
  876. end;
  877.  
  878. procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
  879.  
  880.   function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  881.   begin
  882.     with Result do
  883.     begin
  884.       rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
  885.       rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
  886.       rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
  887.       rgbReserved := 0;
  888.     end;
  889.   end;
  890.  
  891. var
  892.   i: Integer;
  893.   t, t2: DWORD;
  894.   ChangePalette: Boolean;
  895.   c: Integer;
  896. begin
  897.   if DXDraw.Initialized then
  898.   begin
  899.     c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
  900.  
  901.     {  Palette animation  }
  902.     ChangePalette := False;
  903.     if DXDraw.CanPaletteAnimation then
  904.     begin
  905.       t := GetTickCount;
  906.       while Abs(GetTickCount-t)<Time do
  907.       begin
  908.         t2 := Trunc(Abs(GetTickCount-t)/Time*255);
  909.  
  910.         for i:=0 to 255 do
  911.           DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
  912.  
  913.         DXDraw.UpdatePalette;
  914.         ChangePalette := True;
  915.       end;
  916.     end else
  917.       Sleep(Time);
  918.  
  919.     DXDraw.Surface.Fill(c);
  920.     DXDraw.Flip;
  921.     DXDraw.Surface.Fill(c);
  922.     DXDraw.Flip;
  923.     DXDraw.Surface.Fill(c);
  924.     DXDraw.Flip;
  925.     DXDraw.Surface.Fill(c);
  926.     DXDraw.Flip;
  927.  
  928.     if ChangePalette then
  929.     begin
  930.       DXDraw.ColorTable := DXDraw.DefColorTable;
  931.       DXDraw.UpdatePalette;
  932.     end;
  933.  
  934.     DXDraw.Surface.Fill(c);
  935.     DXDraw.Flip;
  936.   end;
  937. end;
  938.  
  939. const
  940.   DXInputButton = [isButton1, isButton2, isButton3,
  941.     isButton4, isButton5, isButton6, isButton7, isButton8, isButton9, isButton10, isButton11,
  942.     isButton12, isButton13, isButton14, isButton15, isButton16, isButton17, isButton18,
  943.     isButton19, isButton20, isButton21, isButton22, isButton23, isButton24, isButton25,
  944.     isButton26, isButton27, isButton28, isButton29, isButton30, isButton31, isButton32];
  945.  
  946. procedure TMainForm.StartScene(Scene: TGameScene);
  947. begin
  948.   EndScene;
  949.  
  950.   DXInput.States := DXInput.States - DXInputButton;
  951.  
  952.   FScene := Scene;
  953.  
  954.   BlinkStart;
  955.  
  956.   case FScene of
  957.     gsTitle   : StartSceneTitle;
  958.     gsMain    : StartSceneMain;
  959.     gsGameOver: StartSceneGameOver;
  960.   end;
  961. end;
  962.  
  963. procedure TMainForm.StartSceneTitle;
  964. begin
  965.   {  Title scene beginning  }
  966. end;
  967.  
  968. procedure TMainForm.StartSceneMain;
  969. var
  970.   i, j: Integer;
  971. begin
  972.   {  Main scene beginning  }
  973.   FScore := 0;
  974.   FEnemyAdventPos := 0;
  975.   FFrame := 0;
  976.  
  977.   {  Player object  }
  978.   TPlayerSprite.Create(SpriteEngine.Engine);
  979.  
  980.   {  Background  }
  981.   with TScrollBackground.Create(SpriteEngine.Engine) do
  982.   begin
  983.     SetMapSize(200, 10);
  984.     Image := ImageList.Items.Find('Star');
  985.     Y := 10;
  986.     Z := -13;
  987.     FSpeed := 0.5;
  988.     Tile := True;
  989.  
  990.     for i:=0 to MapHeight-1 do
  991.       for j:=0 to MapWidth-1 do
  992.       begin
  993.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
  994.         if Random(100)<95 then Chips[j, i] := -1;
  995.       end;
  996.   end;
  997.  
  998.   with TScrollBackground.Create(SpriteEngine.Engine) do
  999.   begin
  1000.     SetMapSize(200, 10);
  1001.     Image := ImageList.Items.Find('Star');
  1002.     Y := 30;
  1003.     Z := -12;
  1004.     FSpeed := 1;
  1005.     Tile := True;
  1006.  
  1007.     for i:=0 to MapHeight-1 do
  1008.       for j:=0 to MapWidth-1 do
  1009.       begin
  1010.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
  1011.         if Random(100)<95 then Chips[j, i] := -1;
  1012.       end;
  1013.   end;
  1014.  
  1015.   with TScrollBackground.Create(SpriteEngine.Engine) do
  1016.   begin
  1017.     SetMapSize(200, 10);
  1018.     Image := ImageList.Items.Find('Star');
  1019.     Y := 40;
  1020.     Z := -11;
  1021.     FSpeed := 2;
  1022.     Tile := True;
  1023.  
  1024.     for i:=0 to MapHeight-1 do
  1025.       for j:=0 to MapWidth-1 do
  1026.       begin
  1027.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
  1028.         if Random(100)<95 then Chips[j, i] := -1;
  1029.       end;
  1030.   end;
  1031. end;
  1032.  
  1033. procedure TMainForm.StartSceneGameOver;
  1034. begin
  1035.   {  Game over scene beginning  }
  1036. end;
  1037.  
  1038. procedure TMainForm.EndScene;
  1039. begin
  1040.   case FScene of
  1041.     gsTitle   : EndSceneTitle;
  1042.     gsMain    : EndSceneMain;
  1043.     gsGameOver: EndSceneGameOver;
  1044.   end;
  1045. end;
  1046.  
  1047. procedure TMainForm.EndSceneTitle;
  1048. begin
  1049.   {  Title scene end  }
  1050. end;
  1051.  
  1052. procedure TMainForm.EndSceneMain;
  1053. begin
  1054.   {  Main scene end  }
  1055.   SpriteEngine.Engine.Clear;
  1056. end;
  1057.  
  1058. procedure TMainForm.EndSceneGameOver;
  1059. begin
  1060.   {  Game over scene end  }
  1061. end;
  1062.  
  1063. procedure TMainForm.SceneTitle;
  1064. var
  1065.   Logo: TPictureCollectionItem;
  1066. begin
  1067.   {  Title scene  }
  1068.   DXDraw.Surface.Fill(0);
  1069.  
  1070.   Logo := ImageList.Items.Find('Logo');
  1071.   Logo.DrawWaveX(DXDraw.Surface, 30, 80, Logo.Width, Logo.Height, 0,
  1072.     Trunc(16-Cos256(FBlink div 60)*16), 32, -FBlink div 5);
  1073.     
  1074.   with DXDraw.Surface.Canvas do
  1075.   begin
  1076.     Brush.Style := bsClear;
  1077.     Font.Color := clRed;
  1078.     Font.Size := 40;
  1079.  
  1080.     if (FBlink div 300) mod 2=0 then
  1081.     begin
  1082.       Font.Color := clWhite;
  1083.       Font.Size := 30;
  1084.       Textout(160, 300, 'PUSH BUTTON 1');
  1085.     end;
  1086.  
  1087.     BlinkUpdate;
  1088.  
  1089.     Release;
  1090.   end;
  1091.  
  1092.   if isButton1 in DXInput.States then
  1093.   begin
  1094.     PlaySound('SceneMov', False);
  1095.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  1096.     Sleep(200);
  1097.  
  1098.     StartScene(gsMain);
  1099.   end;
  1100. end;
  1101.  
  1102. procedure TMainForm.SceneMain;
  1103. var
  1104.   Enemy: TSprite;
  1105. begin
  1106.   {  Main scene  }
  1107.   SpriteEngine.Move(1000 div 60);
  1108.   SpriteEngine.Dead;
  1109.  
  1110.   {  Enemy appearance  }
  1111.   while (Low(EnemyAdventTable)<=FEnemyAdventPos) and (FEnemyAdventPos<=High(EnemyAdventTable)) and
  1112.     (EnemyAdventTable[FEnemyAdventPos].f<=FFrame) do
  1113.   begin
  1114.     with EnemyAdventTable[FEnemyAdventPos] do
  1115.     begin
  1116.       Enemy := c.Create(SpriteEngine.Engine);
  1117.       Enemy.x := 640+x;
  1118.       Enemy.y := y;
  1119.     end;
  1120.  
  1121.     Inc(FEnemyAdventPos);
  1122.   end;
  1123.  
  1124.   DXDraw.Surface.Fill(0);
  1125.   if FNextScene=gsNone then
  1126.   begin
  1127.     SpriteEngine.Draw;
  1128.  
  1129.     with DXDraw.Surface.Canvas do
  1130.     begin
  1131.       Brush.Style := bsClear;
  1132.       Font.Color := clYellow;
  1133.       Font.Size := 20;
  1134.       Textout(10, 10, IntToStr(FScore));
  1135.       Release;
  1136.     end;
  1137.   end;
  1138.  
  1139.   Inc(FFrame);
  1140. end;
  1141.  
  1142. procedure TMainForm.SceneGameOver;
  1143. begin
  1144.   {  Game over scene  }
  1145.   DXDraw.Surface.Fill(0);
  1146.   with DXDraw.Surface.Canvas do
  1147.   begin
  1148.     Brush.Style := bsClear;
  1149.     Font.Color := clRed;
  1150.     Font.Size := 40;
  1151.     Textout(190, 100, 'Game Over');
  1152.  
  1153.     if (FBlink div 300) mod 2=0 then
  1154.     begin
  1155.       Font.Color := clWhite;
  1156.       Font.Size := 30;
  1157.       Textout(160, 300, 'PUSH BUTTON 1');
  1158.     end;
  1159.  
  1160.     BlinkUpdate;
  1161.  
  1162.     Release;
  1163.   end;
  1164.  
  1165.   if isButton1 in DXInput.States then
  1166.   begin
  1167.     PlaySound('SceneMov', False);
  1168.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  1169.     Sleep(200);
  1170.  
  1171.     StartScene(gsTitle);
  1172.   end;
  1173. end;
  1174.  
  1175. end.
  1176.  
  1177.