Subversion Repositories spacemission

Rev

Rev 7 | Rev 14 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit GamMain;
  2.  
  3. // TODO: 2024 Quellcode optimieren und klassen-namen überdenken
  4. // TODO: 2024 Form Screen center anstelle Desktop Center => OK!
  5. // TODO: 2024 Vollbild entf.
  6. // TODO: 2024 DPlayX.dll auskommentieren => OK!
  7. // TODO: 2024 Software-Update routine prüfen
  8. // TODO: 2024 EV CodeSign
  9. // TODO: 2024 Spielstände usw. "Spiele" Ordner speichern, Config in Registry sichern, etc.
  10. // TODO: 2024 Neue Einheiten => Medikit, Ufo das im Kreis fliegt und nicht weggeht
  11. // TODO: 2024 Bei Pause => Entweder alles grau werden lassen, oder irgendwo "Pause" hinschreiben (nur Not in die Form Caption)
  12. // TODO: 2024 Alle Notizen durchschauen
  13. // TODO: 2024 Boss schwieriger machen: Er soll auch nach links und rechts gehen?
  14. // TODO: 2024 Cooldown für Laser?
  15. // TODO: 2024 Musik und Sounds optimieren
  16. // TODO: 2024 Pausiertes Spiel: Fenster bewegen lässt das Spiel wieder starten
  17. // TODO: 2024 Zwei Fenster in Taskleiste
  18. // TODO: 2024 "Doku" in Hilfemenü einbinden, ggf. auch den Leveleditor ins Menü machen
  19. // TODO: 2024 Highscore Liste
  20.  
  21. interface
  22.  
  23. uses
  24.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem, Dialogs,
  25.   StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
  26.   INIFiles, ShellAPI, wininet, DirectX;
  27.  
  28. type
  29.   TGameScene = (
  30.     gsNone,
  31.     gsTitle,
  32.     gsMain,
  33.     gsGameOver,
  34.     gsNewLevel,
  35.     gsWin
  36.   );
  37.  
  38.   TGameInterval = (
  39.     giMittel,
  40.     giLeicht,
  41.     giSchwer,
  42.     giMaster
  43.   );
  44.  
  45.   TMusicTrack = (
  46.     mtNone,
  47.     mtGame,
  48.     mtBoss,
  49.     mtScene,
  50.     mtTitle
  51.   );
  52.  
  53.   {TSoundFile = (
  54.     sfNone,
  55.     sfSceneMov,
  56.     sfExplosion,
  57.     sfHit,
  58.     sfShoot,
  59.     sfDanger,
  60.     sfEnde,
  61.     sfFrage,
  62.     sfLevIntro
  63.   );}
  64.  
  65.   TBackground = class(TBackgroundSprite)
  66.   private
  67.     FSpeed: Double;
  68.   protected
  69.     procedure DoMove(MoveCount: Integer); override;
  70.   end;
  71.  
  72.   TBackgroundSpecial = class(TBackgroundSprite)
  73.   private
  74.     FSpeed: Double;
  75.   protected
  76.     procedure DoMove(MoveCount: Integer); override;
  77.   end;
  78.  
  79.   TExplosion = class(TImageSprite)
  80.   private
  81.     FCounter: Integer;
  82.   protected
  83.     procedure DoMove(MoveCount: Integer); override;
  84.   public
  85.     constructor Create(AParent: TSprite); override;
  86.   end;
  87.  
  88.   TPlayerSprite = class(TImageSprite)
  89.   private
  90.     FCounter: Integer;
  91.     FMode: Integer;
  92.     FTamaCount: Integer;
  93.     FOldTamaTime: Integer;
  94.   protected
  95.     procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
  96.     procedure DoMove(MoveCount: Integer); override;
  97.   public
  98.     constructor Create(AParent: TSprite); override;
  99.     procedure FlyAway;
  100.   end;
  101.  
  102.   TTamaSprite = class(TImageSprite)
  103.   private
  104.     FPlayerSprite: TPlayerSprite;
  105.   protected
  106.     procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
  107.     procedure DoMove(MoveCount: Integer); override;
  108.   public
  109.     constructor Create(AParent: TSprite); override;
  110.     destructor Destroy; override;
  111.   end;
  112.  
  113.   TEnemyClass = class of TEnemy;
  114.   TEnemy = class(TImageSprite)
  115.   private
  116.     FCounter: Integer;
  117.     FLife: integer;
  118.     FMode: Integer;
  119.   protected
  120.     procedure HitEnemy(ADead: Boolean); virtual;
  121.   public
  122.     procedure Hit(AHitStrength: integer = 1);
  123.     constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
  124.     destructor Destroy; override;
  125.   end;
  126.  
  127.   TEnemyTama = class(TImageSprite)
  128.   private
  129.     FPlayerSprite: TSprite;
  130.   protected
  131.     procedure DoMove(MoveCount: Integer); override;
  132.   public
  133.     constructor Create(AParent: TSprite); override;
  134.   end;
  135.  
  136.   TEnemyMeteor = class(TEnemy)
  137.   protected
  138.     procedure DoMove(MoveCount: Integer); override;
  139.     procedure HitEnemy(ADead: Boolean); override;
  140.   public
  141.     constructor Create(AParent: TSprite; ALifes: integer); override;
  142.   end;
  143.  
  144.   TEnemyUFO = class(TEnemy)
  145.   protected
  146.     procedure DoMove(MoveCount: Integer); override;
  147.     procedure HitEnemy(ADead: Boolean); override;
  148.   public
  149.     constructor Create(AParent: TSprite; ALifes: integer); override;
  150.   end;
  151.  
  152.   TEnemyUFO2 = class(TEnemy)
  153.   private
  154.     FCounter: Integer;
  155.     FTamaCount: Integer;
  156.     FOldTamaTime: Integer;
  157.   protected
  158.     procedure DoMove(MoveCount: Integer); override;
  159.     procedure HitEnemy(ADead: Boolean); override;
  160.   public
  161.     constructor Create(AParent: TSprite; ALifes: integer); override;
  162.   end;
  163.  
  164.   TEnemyAttacker = class(TEnemy)
  165.   protected
  166.     procedure DoMove(MoveCount: Integer); override;
  167.     procedure HitEnemy(ADead: Boolean); override;
  168.   public
  169.     constructor Create(AParent: TSprite; ALifes: integer); override;
  170.   end;
  171.  
  172.   TEnemyAttacker2 = class(TEnemy)
  173.   private
  174.     FCounter: Integer;
  175.     FTamaF: Integer;
  176.     FTamaT: Integer;
  177.     FPutTama: Boolean;
  178.   protected
  179.     procedure DoMove(MoveCount: Integer); override;
  180.     procedure HitEnemy(ADead: Boolean); override;
  181.   public
  182.     constructor Create(AParent: TSprite; ALifes: integer); override;
  183.   end;
  184.  
  185.   TEnemyAttacker3 = class(TEnemy)
  186.   private
  187.     FCounter: Integer;
  188.     FTamaCount: Integer;
  189.     FOldTamaTime: Integer;
  190.   protected
  191.     procedure DoMove(MoveCount: Integer); override;
  192.     procedure HitEnemy(ADead: Boolean); override;
  193.   public
  194.     constructor Create(AParent: TSprite; ALifes: integer); override;
  195.   end;
  196.  
  197.   TEnemyBoss = class(TEnemy)
  198.   private
  199.     FCounter: Integer;
  200.     FTamaF: Integer;
  201.     FTamaT: Integer;
  202.     FPutTama: Boolean;
  203.     waiter1, waiter2: integer;
  204.   protected
  205.     procedure DoMove(MoveCount: Integer); override;
  206.     procedure HitEnemy(ADead: Boolean); override;
  207.   public
  208.     constructor Create(AParent: TSprite; ALifes: integer); override;
  209.   end;
  210.  
  211.   TEnemyAdvent = record
  212.     spriteClass: TEnemyClass;
  213.     x: extended;
  214.     y: extended;
  215.     lifes: integer;
  216.   end;
  217.  
  218.   TMainForm = class(TDXForm)
  219.     MainMenu: TMainMenu;
  220.     Spiel: TMenuItem;
  221.     GameStart: TMenuItem;
  222.     GamePause: TMenuItem;
  223.     Beenden: TMenuItem;
  224.     Einstellungen: TMenuItem;
  225.     OptionFullScreen: TMenuItem;
  226.     OptionMusic: TMenuItem;
  227.     Leer2: TMenuItem;
  228.     Leer4: TMenuItem;
  229.     Hilfe: TMenuItem;
  230.     OptionSound: TMenuItem;
  231.     Leer3: TMenuItem;
  232.     Spielstand: TMenuItem;
  233.     Leer5: TMenuItem;
  234.     Neustart: TMenuItem;
  235.     OptionBreitbild: TMenuItem;
  236.     Spielgeschwindigkeit: TMenuItem;
  237.     Leicht: TMenuItem;
  238.     Mittel: TMenuItem;
  239.     Schwer: TMenuItem;
  240.     Informationen: TMenuItem;
  241.     Leer6: TMenuItem;
  242.     Leer1: TMenuItem;
  243.     Cheat: TMenuItem;
  244.     CheckUpdates: TMenuItem;
  245.     Master: TMenuItem;
  246.     procedure DXDrawFinalize(Sender: TObject);
  247.     procedure DXDrawInitialize(Sender: TObject);
  248.     procedure FormCreate(Sender: TObject);
  249.     procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
  250.     procedure DXTimerActivate(Sender: TObject);
  251.     procedure DXTimerDeactivate(Sender: TObject);
  252.     procedure OptionFullScreenClick(Sender: TObject);
  253.     procedure DXDrawInitializing(Sender: TObject);
  254.     procedure GameStartClick(Sender: TObject);
  255.     procedure GamePauseClick(Sender: TObject);
  256.     procedure BeendenClick(Sender: TObject);
  257.     procedure OptionSoundClick(Sender: TObject);
  258.     procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  259.     procedure OptionMusicClick(Sender: TObject);
  260.     procedure SpielstandClick(Sender: TObject);
  261.     procedure NeustartClick(Sender: TObject);
  262.     procedure OptionBreitbildClick(Sender: TObject);
  263.     procedure LeichtClick(Sender: TObject);
  264.     procedure MittelClick(Sender: TObject);
  265.     procedure SchwerClick(Sender: TObject);
  266.     procedure FormShow(Sender: TObject);
  267.     procedure InformationenClick(Sender: TObject);
  268.     procedure CheatClick(Sender: TObject);
  269.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  270.     procedure FormDestroy(Sender: TObject);
  271.     procedure CheckUpdatesClick(Sender: TObject);
  272.     procedure MasterClick(Sender: TObject);
  273.   private
  274.     ProgrammGestartet: boolean;
  275.     FInterval: TGameInterval;
  276.     FScene: TGameScene;
  277.     FMusic: TMusicTrack;
  278.     FBlink: DWORD;
  279.     FBlinkTime: DWORD;
  280.     FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
  281.     PlayerSprite: TPlayerSprite;
  282.     TimerCS: TRTLCriticalSection;
  283.     procedure StartScene(Scene: TGameScene);
  284.     procedure EndScene;
  285.     procedure BlinkStart;
  286.     procedure BlinkUpdate;
  287.     procedure StartSceneTitle;
  288.     procedure SceneTitle;
  289.     procedure EndSceneTitle;
  290.     procedure StartSceneMain;
  291.     procedure SceneMain;
  292.     procedure EndSceneMain;
  293.     procedure StartSceneGameOver;
  294.     procedure SceneGameOver;
  295.     procedure EndSceneGameOver;
  296.     procedure StartSceneWin;
  297.     procedure SceneWin;
  298.     procedure EndSceneWin;
  299.     procedure StartSceneNewLevel;
  300.     procedure SceneNewLevel;
  301.     procedure EndSceneNewLevel;
  302.   public
  303.     FNextScene: TGameScene;
  304.     FScore: Integer;
  305.     FNotSave: boolean;
  306.     FLife: integer;
  307.     FLevel: integer;
  308.     FMenuItem: integer;
  309.     FBossLife: integer;
  310.     FRestEnemies: integer;
  311.     FCheat: boolean;
  312.     { VCL-Ersatz }
  313.     dxdraw: TDxDraw;
  314.     imagelist: TDxImageList;
  315.     spriteengine: tdxspriteengine;
  316.     dxsound: tdxsound;
  317.     wavelist: tdxwavelist;
  318.     dxinput: tdxinput;
  319.     dxtimer: tdxtimer;
  320.     { Level-Routinen }
  321.     procedure NewLevel(lev: integer);
  322.     procedure DeleteArray;
  323.     { MCI-Routinen }
  324.     function StatusMusic(Name: TMusicTrack): string;
  325.     procedure PlayMusic(Name: TMusicTrack);
  326.     //procedure StopMusic(Name: TMusicTrack);
  327.     procedure PauseMusic(Name: TMusicTrack);
  328.     procedure ResumeMusic(Name: TMusicTrack);
  329.     procedure DestroyMusic(Name: TMusicTrack);
  330.     procedure OpenMusic(Name: TMusicTrack);
  331.     { Sound-Routinen }
  332.     function SoundKarte: boolean;
  333.     procedure PlaySound(Name: string; Wait: Boolean);
  334.     { Initialisiations-Routinen }
  335.     procedure DXInit;
  336.     procedure SoundInit;
  337.     procedure MusicInit;
  338.     { Einstellungs-Routinen }
  339.     procedure LoadOptions;
  340.     procedure WriteOptions;
  341.     { Farb-Routinen }
  342.     function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  343.     procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
  344.   end;
  345.  
  346. var
  347.   MainForm: TMainForm;
  348.  
  349. implementation
  350.  
  351. uses
  352.   GamSplash, GamSpeicherung, ComInfo, GamCheat, Global;
  353.  
  354. const
  355.   // TODO: ini file
  356.   conleicht = 650 div 60; // 10
  357.   conmittel = 1000 div 60; // 16
  358.   conschwer = 1350 div 60; // 22
  359.   conmaster = 2000 div 60; // 33
  360.   lives = 6;
  361.  
  362.   // TODO: Auch für Enemies
  363.   PLAYER_MODE_NORMAL = 0;
  364.   PLAYER_MODE_DEAD = 1;
  365.   PLAYER_MODE_DEAD_VANISHED = 2;
  366.   PLAYER_MODE_FLYAWAY = 3;
  367.   PLAYER_MODE_ENTER = 4;
  368.  
  369.   DEFAULT_ANIMSPEED = 15/1000;
  370.  
  371. resourcestring
  372.   FileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
  373.  
  374. {$R *.DFM}
  375.  
  376. var // TODO: irgendwo hinpacken. irgendwo!!!
  377.   EnemyAdventTable: array of TEnemyAdvent;
  378.   Crash2, EnemyCounter: integer;
  379.   BossExists, Crash, crashsound: boolean;
  380.  
  381. const
  382.   DXInputButton = [isButton1, isButton2, isButton3,
  383.     isButton4, isButton5, isButton6, isButton7, isButton8, isButton9, isButton10, isButton11,
  384.     isButton12, isButton13, isButton14, isButton15, isButton16, isButton17, isButton18,
  385.     isButton19, isButton20, isButton21, isButton22, isButton23, isButton24, isButton25,
  386.     isButton26, isButton27, isButton28, isButton29, isButton30, isButton31, isButton32];
  387.  
  388. // TODO: Code komplett überarbeiten. Bessere Ableitungen machen
  389.  
  390. constructor TPlayerSprite.Create(AParent: TSprite);
  391. begin
  392.   inherited Create(AParent);
  393.   Image := MainForm.ImageList.Items.Find('Machine');
  394.   Width := Image.Width;
  395.   Height := Image.Height;
  396.   X := -70{20};
  397.   Y := mainform.dxdraw.surfaceHeight / 2 - (height / 2);
  398.   Z := 2;
  399.   AnimCount := Image.PatternCount;
  400.   AnimLooped := True;
  401.   AnimSpeed := DEFAULT_ANIMSPEED;
  402.   FMode := PLAYER_MODE_ENTER;
  403. end;
  404.  
  405. procedure TPlayerSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
  406. begin
  407.   if mainform.FCheat then exit;
  408.   if (Sprite is TEnemy) or (Sprite is TEnemyTama) then
  409.   begin
  410.     if not crash then
  411.     begin
  412.       dec(MainForm.FLife);
  413.       Crash := true;
  414.       if MainForm.Flife=0 then
  415.       begin
  416.         MainForm.PlaySound('Explosion', false);
  417.         Collisioned := false;
  418.         FCounter := 0;
  419.         FMode := PLAYER_MODE_DEAD;
  420.         Done := false;
  421.         Image := MainForm.ImageList.Items.Find('Explosion');
  422.         Width := Image.Width;
  423.         Height := Image.Height;
  424.         AnimCount := Image.PatternCount;
  425.         AnimLooped := False;
  426.         AnimSpeed := DEFAULT_ANIMSPEED;
  427.         AnimPos := 0;
  428.       end;
  429.     end
  430.     else
  431.     begin
  432.       if not crashsound then
  433.       begin
  434.         MainForm.PlaySound('Hit', False);
  435.         crashsound := true;
  436.       end;
  437.     end;
  438.   end;
  439. end;
  440.  
  441. procedure TPlayerSprite.DoMove(MoveCount: Integer);
  442. const
  443.   WegduesKonstante = 1.75;
  444. begin
  445.   inherited DoMove(MoveCount);
  446.   if FMode=PLAYER_MODE_NORMAL then
  447.   begin
  448.     if isUp in MainForm.DXInput.States then Y := Y - (250/1000)*MoveCount;
  449.     if isDown in MainForm.DXInput.States then Y := Y + (250/1000)*MoveCount;
  450.     if isLeft in MainForm.DXInput.States then X := X - (250/1000)*MoveCount;
  451.     if isRight in MainForm.DXInput.States then X := X + (250/1000)*MoveCount;
  452.     if X<0 then X := 0;
  453.     if X>mainform.dxdraw.surfacewidth-Width then X := mainform.dxdraw.surfacewidth-Width;
  454.     if Y<0 then Y := 0;
  455.     if Y>mainform.dxdraw.surfaceheight-Height then Y := mainform.dxdraw.surfaceheight-Height;
  456.     if isButton1 in MainForm.DXInput.States then
  457.     begin
  458.       if (FTamaCount<8) and (FCounter-FOldTamaTime>=100) then
  459.       begin
  460.         Inc(FTamaCount);
  461.         with TTamaSprite.Create(Engine) do
  462.         begin
  463.           FPlayerSprite := Self;
  464.           X := Self.X+Self.Width;
  465.           Y := Self.Y+Self.Height div 2-Height div 2;
  466.           Z := 10;
  467.         end;
  468.         FOldTamaTime := FCounter;
  469.       end;
  470.     end;
  471.     Collision;
  472.   end
  473.   else if FMode=PLAYER_MODE_DEAD then
  474.   begin
  475.     if FCounter>200 then
  476.     begin
  477.       FCounter := 0;
  478.       FMode := PLAYER_MODE_DEAD_VANISHED;
  479.       Visible := false;
  480.     end;
  481.   end
  482.   else if FMode=PLAYER_MODE_DEAD_VANISHED then
  483.   begin
  484.     if FCounter>1500 then
  485.     begin
  486.       MainForm.FNextScene := gsGameOver;
  487.       MainForm.PlaySound('SceneMov', false);
  488.       MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
  489.       Sleep(200);
  490.     end;
  491.   end
  492.   else if FMode=PLAYER_MODE_FLYAWAY then
  493.   begin
  494.     // FUT: "Wusch" sound?
  495.     X := X + MoveCount*(300/1000) * (X/MainForm.DXDraw.Width + WegduesKonstante);
  496.     if X > MainForm.DXDraw.Width+Width then
  497.     begin
  498.       Dead;
  499.       inc(mainform.FLevel);
  500.       MainForm.FNextScene := gsNewLevel;
  501.       MainForm.PlaySound('SceneMov', false);
  502.       MainForm.PalleteAnim(RGBQuad(0, 0, 0), 300);
  503.     end;
  504.   end
  505.   else if FMode = PLAYER_MODE_ENTER then
  506.   begin
  507.     X := X + MoveCount*(300/1000);
  508.     if X > 19 then FMode := PLAYER_MODE_NORMAL;
  509.   end;
  510.   inc(FCounter, MoveCount);
  511. end;
  512.  
  513. procedure TPlayerSprite.FlyAway;
  514. begin
  515.   FMode := PLAYER_MODE_FLYAWAY;
  516. end;
  517.  
  518. procedure TMainForm.DXInit;
  519. begin
  520.   try
  521.     Imagelist.Items.LoadFromFile(FDirectory+'DirectX\Graphic.dxg');
  522.     ImageList.Items.MakeColorTable;
  523.     DXDraw.ColorTable := ImageList.Items.ColorTable;
  524.     DXDraw.DefColorTable := ImageList.Items.ColorTable;
  525.     DXDraw.UpdatePalette;
  526.     OptionBreitBild.enabled := OptionFullScreen.checked;
  527.     DXDraw.Finalize;
  528.     if OptionFullScreen.Checked then
  529.     begin
  530.       if not (doFullScreen in DXDraw.Options) then StoreWindow;
  531.       DXDraw.Options := DXDraw.Options + [doFullScreen];
  532.     end
  533.     else
  534.     begin
  535.       if doFullScreen in DXDraw.Options then RestoreWindow;
  536.       DXDraw.Options := DXDraw.Options - [doFullScreen];
  537.     end;
  538.     if not OptionBreitBild.checked then
  539.     begin
  540.       dxdraw.autosize := false;
  541.       dxdraw.Top := 0;
  542.       dxdraw.Left := 0;
  543.       dxdraw.width := 640;    // TODO: besser die dimensionen des fensters
  544.       dxdraw.height := 480;
  545.       dxdraw.surfacewidth := 640;
  546.       dxdraw.surfaceheight := 480;
  547.     end
  548.     else dxdraw.autosize := true;
  549.     DXDraw.Initialize;
  550.   except
  551.     //Imagelist.Items.clear;
  552.     //application.terminate;
  553.   end;
  554. end;
  555.  
  556. constructor TTamaSprite.Create(AParent: TSprite);
  557. begin
  558.   inherited Create(AParent);
  559.   Image := MainForm.ImageList.Items.Find('Bounce');
  560.   Z := 2;
  561.   Width := Image.Width;
  562.   Height := Image.Height;
  563.   AnimCount := Image.PatternCount;
  564.   AnimLooped := True;
  565.   AnimSpeed := DEFAULT_ANIMSPEED;
  566.   MainForm.PlaySound('Shoot', False);
  567. end;
  568.  
  569. destructor TTamaSprite.Destroy;
  570. begin
  571.   inherited Destroy;
  572.   Dec(FPlayerSprite.FTamaCount);
  573. end;
  574.  
  575. procedure TTamaSprite.DoCollision(Sprite: TSprite; var Done: Boolean);
  576. begin
  577.   if (Sprite is TEnemy) and not (Sprite is TEnemyTama) then
  578.   begin
  579.     TEnemy(Sprite).Hit;
  580.     Dead;
  581.   end;
  582.   Done := False;
  583. end;
  584.  
  585. procedure TTamaSprite.DoMove(MoveCount: Integer);
  586. begin
  587.   inherited DoMove(MoveCount);
  588.   X := X+(800/1000)*MoveCount;
  589.   if X>=mainform.dxdraw.surfacewidth then Dead;
  590.   Collision;
  591. end;
  592.  
  593. procedure TBackground.DoMove(MoveCount: Integer);
  594. var
  595.   ran: integer;
  596. begin
  597.   inherited DoMove(MoveCount);
  598.   X := X - MoveCount*(60/1000)*FSpeed;
  599.   randomize;
  600.   ran := Random(1500);
  601.   if ran = 150 then
  602.   begin
  603.     with TBackgroundSpecial.Create(mainform.SpriteEngine.Engine) do
  604.     begin
  605.       SetMapSize(1, 1);
  606.       Image := mainform.ImageList.Items.Find('Background-Planet1');
  607.       Width := Image.Width;
  608.       Height := Image.Height;
  609.  
  610.       Y := random(mainform.dxdraw.height);
  611.       X := mainform.dxdraw.width;
  612.  
  613.       ran := Random(2);
  614.       if ran = 0 then
  615.       begin
  616.         Z := -20;
  617.         FSpeed := 1.8;
  618.       end
  619.       else if ran = 1 then
  620.       begin
  621.         Z := -40;
  622.         FSpeed := 0.8;
  623.       end
  624.       else if ran = 2 then
  625.       begin
  626.         Z := -60;
  627.         FSpeed := 0.3;
  628.       end;
  629.     end;
  630.   end
  631.   else if ran = 500 then
  632.   begin
  633.     with TBackgroundSpecial.Create(mainform.SpriteEngine.Engine) do
  634.     begin
  635.       SetMapSize(1, 1);
  636.       ran := Random(4);
  637.       if ran = 0 then
  638.         Image := mainform.ImageList.Items.Find('Background-Red')
  639.       else if ran = 1 then
  640.         Image := mainform.ImageList.Items.Find('Background-Blue')
  641.       else if ran = 2 then
  642.         Image := mainform.ImageList.Items.Find('Background-Yellow')
  643.       else if ran = 3 then
  644.         Image := mainform.ImageList.Items.Find('Hintergrund-Rot');
  645.       Width := Image.Width;
  646.       Height := Image.Height;
  647.  
  648.       Y := random(mainform.dxdraw.height);
  649.       X := mainform.dxdraw.width;
  650.  
  651.       { ran := Random(2);
  652.       if ran = 0 then
  653.       begin
  654.         Z := -20;
  655.         FSpeed := 1.8;
  656.       end
  657.       else if ran = 1 then
  658.       begin
  659.         Z := -40;
  660.         FSpeed := 0.8;
  661.       end
  662.       else if ran = 2 then
  663.       begin }
  664.         Z := -60;
  665.         FSpeed := 0.3;
  666.       { end; }
  667.     end;
  668.   end;
  669. end;
  670.  
  671. procedure TBackgroundSpecial.DoMove(MoveCount: Integer);
  672. begin
  673.   inherited DoMove(MoveCount);
  674.   X := X - MoveCount*(60/1000)*FSpeed;
  675.   if X<-Width then Dead;
  676. end;
  677.  
  678. constructor TExplosion.Create(AParent: TSprite);
  679. begin
  680.   inherited Create(AParent);
  681.   mainform.PlaySound('Explosion', false);
  682.   Image := MainForm.ImageList.Items.Find('Explosion');
  683.   Width := Image.Width;
  684.   Height := Image.Height;
  685.   AnimCount := Image.PatternCount;
  686.   AnimLooped := True;
  687.   AnimSpeed := DEFAULT_ANIMSPEED;
  688.   AnimPos := Random(AnimCount);
  689. end;
  690.  
  691. procedure TExplosion.DoMove(MoveCount: Integer);
  692. begin
  693.   inherited DoMove(MoveCount);
  694.   inc(FCounter, MoveCount);
  695.   if FCounter > 2999 then dead;
  696. end;
  697.  
  698. constructor TEnemyTama.Create(AParent: TSprite);
  699. begin
  700.   inherited Create(AParent);
  701.   Image := MainForm.ImageList.Items.Find('Bounce2');
  702.   Width := Image.Width;
  703.   Height := Image.Height;
  704.   AnimCount := Image.PatternCount;
  705.   AnimLooped := True;
  706.   AnimSpeed := DEFAULT_ANIMSPEED;
  707.   MainForm.PlaySound('Shoot', False);
  708. end;
  709.  
  710. procedure TEnemyTama.DoMove(MoveCount: Integer);
  711. begin
  712.   inherited DoMove(MoveCount);
  713.   X := X - MoveCount*(600/1000);
  714.   if X<-Width then Dead;
  715. end;
  716.  
  717. procedure TEnemy.Hit(AHitStrength: integer = 1);
  718. begin
  719.   Dec(FLife, AHitStrength);
  720.   if FLife<=0 then
  721.   begin
  722.     Collisioned := False;
  723.     HitEnemy(True);
  724.   end
  725.   else
  726.     HitEnemy(False);
  727. end;
  728.  
  729. procedure TEnemy.HitEnemy(ADead: Boolean);
  730. begin
  731.   if ADead then
  732.     MainForm.PlaySound('Explosion', False)
  733.   else
  734.     MainForm.PlaySound('Hit', False);
  735. end;
  736.  
  737. constructor TEnemyUFO.Create(AParent: TSprite; ALifes: integer);
  738. begin
  739.   inherited Create(AParent, ALifes);
  740.   Image := MainForm.ImageList.Items.Find('Enemy-disk');
  741.   Width := Image.Width;
  742.   Height := Image.Height;
  743.   AnimCount := Image.PatternCount;
  744.   AnimLooped := True;
  745.   AnimSpeed := DEFAULT_ANIMSPEED;
  746. end;
  747.  
  748. constructor TEnemy.Create(AParent: TSprite; ALifes: integer);
  749. begin
  750.   inherited Create(AParent);
  751.   FLife := ALifes;
  752.   inc(EnemyCounter);
  753. end;
  754.  
  755. destructor TEnemy.Destroy;
  756. begin
  757.   inherited Destroy;
  758.   dec(EnemyCounter);
  759. end;
  760.  
  761. procedure TEnemyUFO.HitEnemy(ADead: Boolean);
  762. begin
  763.   inherited HitEnemy(ADead);
  764.  
  765.   if ADead then
  766.   begin
  767.     FMode := 2;
  768.     FCounter := 0;
  769.     Inc(MainForm.FScore, 1000);
  770.     Image := MainForm.ImageList.Items.Find('Explosion');
  771.     Width := Image.Width;
  772.     Height := Image.Height;
  773.     AnimCount := Image.PatternCount;
  774.     AnimLooped := False;
  775.     AnimSpeed := DEFAULT_ANIMSPEED;
  776.     AnimPos := 0;
  777.   end
  778.   else
  779.   begin
  780.     Inc(MainForm.FScore, 100);
  781.   end;
  782. end;
  783.  
  784. procedure TEnemyUFO2.DoMove(MoveCount: Integer);
  785. begin
  786.   inherited DoMove(MoveCount);
  787.   if FMode=0 then
  788.   begin
  789.     X := X - MoveCount*(300/1000);
  790.     Y := Y + Cos256(FCounter div 15)*2;
  791.     if X<-Width then Dead;
  792.     if FCounter-FOldTamaTime>=100 then
  793.     begin
  794.       Inc(FTamaCount);
  795.       with TEnemyTama.Create(Engine) do
  796.       begin
  797.         FPlayerSprite := Self;
  798.         X := Self.X;
  799.         Y := Self.Y+Self.Height div 2-Height div 2;
  800.         Z := 10;
  801.       end;
  802.       FOldTamaTime := FCounter;
  803.     end;
  804.   end
  805.   else if FMode=2 then
  806.   begin
  807.     X := X - MoveCount*(300/1000);
  808.     if FCounter>200 then Dead;
  809.   end;
  810.   inc(FCounter, MoveCount);
  811. end;
  812.  
  813. procedure TEnemyUFO2.HitEnemy(ADead: Boolean);
  814. begin
  815.   inherited HitEnemy(ADead);
  816.  
  817.   if ADead then
  818.   begin
  819.     FMode := 2;
  820.     FCounter := 0;
  821.     Inc(MainForm.FScore, 1000);
  822.     Image := MainForm.ImageList.Items.Find('Explosion');
  823.     Width := Image.Width;
  824.     Height := Image.Height;
  825.     AnimCount := Image.PatternCount;
  826.     AnimLooped := False;
  827.     AnimSpeed := DEFAULT_ANIMSPEED;
  828.     AnimPos := 0;
  829.   end
  830.   else
  831.   begin
  832.     Inc(MainForm.FScore, 100);
  833.   end;
  834. end;
  835.  
  836. constructor TEnemyUFO2.Create(AParent: TSprite; ALifes: integer);
  837. begin
  838.   inherited Create(AParent, ALifes);
  839.   Image := MainForm.ImageList.Items.Find('Enemy-disk2');
  840.   Width := Image.Width;
  841.   Height := Image.Height;
  842.   AnimCount := Image.PatternCount;
  843.   AnimLooped := True;
  844.   AnimSpeed := DEFAULT_ANIMSPEED;
  845. end;
  846.  
  847. procedure TEnemyUFO.DoMove(MoveCount: Integer);
  848. begin
  849.   inherited DoMove(MoveCount);
  850.   if FMode=0 then
  851.   begin
  852.     X := X - MoveCount*(300/1000);
  853.     Y := Y + Cos256(FCounter div 15)*2;
  854.     if X<-Width then Dead;
  855.   end
  856.   else if FMode=2 then
  857.   begin
  858.     X := X - MoveCount*(300/1000);
  859.     if FCounter>200 then Dead;
  860.   end;
  861.   inc(FCounter, MoveCount);
  862. end;
  863.  
  864. constructor TEnemyAttacker.Create(AParent: TSprite; ALifes: integer);
  865. begin
  866.   inherited Create(AParent, ALifes);
  867.   Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
  868.   Width := Image.Width;
  869.   Height := Image.Height;
  870.   AnimCount := Image.PatternCount;
  871.   AnimLooped := True;
  872.   AnimSpeed := DEFAULT_ANIMSPEED;
  873.   PixelCheck := True;
  874. end;
  875.  
  876. procedure TEnemyAttacker.HitEnemy(ADead: Boolean);
  877. begin
  878.   inherited HitEnemy(ADead);
  879.  
  880.   if ADead then
  881.   begin
  882.     FMode := 2;
  883.     FCounter := 0;
  884.     Inc(MainForm.FScore, 1000);
  885.     Image := MainForm.ImageList.Items.Find('Explosion');
  886.     Width := Image.Width;
  887.     Height := Image.Height;
  888.     AnimCount := Image.PatternCount;
  889.     AnimLooped := False;
  890.     AnimSpeed := DEFAULT_ANIMSPEED;
  891.     AnimPos := 0;
  892.   end
  893.   else
  894.   begin
  895.     Inc(MainForm.FScore, 100);
  896.   end;
  897. end;
  898.  
  899. procedure TEnemyAttacker.DoMove(MoveCount: Integer);
  900. begin
  901.   inherited DoMove(MoveCount);
  902.   if FMode=0 then
  903.   begin
  904.     X := X - MoveCount*(300/1000)-FCounter div 128;
  905.     if X < -Width then Dead;
  906.   end
  907.   else if FMode=2 then
  908.   begin
  909.     X := X - MoveCount*(300/1000);
  910.     if FCounter>200 then Dead;
  911.   end;
  912.   inc(FCounter, MoveCount);
  913. end;
  914.  
  915. constructor TEnemyBoss.Create(AParent: TSprite; ALifes: integer);
  916. begin
  917.   inherited Create(AParent, ALifes);
  918.   Image := MainForm.ImageList.Items.Find('Enemy-boss');
  919.   Width := Image.Width;
  920.   Height := Image.Height;
  921.   BossExists := true;
  922.   MainForm.PlayMusic(mtBoss);
  923.   AnimCount := Image.PatternCount;
  924.   AnimLooped := True;
  925.   AnimSpeed := DEFAULT_ANIMSPEED;
  926.   PixelCheck := True;
  927.   Collisioned := False;
  928.   MainForm.FBossLife := FLife;
  929.   waiter1 := 0;
  930.   waiter2 := 0;
  931. end;
  932.  
  933. procedure TEnemyBoss.HitEnemy(ADead: Boolean);
  934. begin
  935.   inherited HitEnemy(ADead);
  936.  
  937.   if ADead then
  938.   begin
  939.     FMode := 2;
  940.     FCounter := 0;
  941.     Inc(MainForm.FScore, 100000);
  942.     BossExists := false;
  943.     dec(MainForm.FBossLife);
  944.   end
  945.   else
  946.   begin
  947.     Inc(MainForm.FScore, 100);
  948.     dec(MainForm.FBossLife);
  949.   end;
  950. end;
  951.  
  952. procedure TEnemyBoss.DoMove(MoveCount: Integer);
  953. begin
  954.   inherited DoMove(MoveCount);
  955.   if FMode=0 then
  956.   begin
  957.     if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/4)){450} then
  958.       X := X - MoveCount*(300/1000)
  959.     else
  960.     begin
  961.       Collisioned := True;
  962.       FMode := 1;
  963.       FPutTama := True;
  964.     end;
  965.     Y := Y + Cos256(FCounter div 15)*5;
  966.   end
  967.   else if FMode=1 then
  968.   begin
  969.     Y := Y + Cos256(FCounter div 15)*5;
  970.     if FPutTama then
  971.     begin
  972.       if FTamaT>100 then
  973.       begin
  974.         with TEnemyTama.Create(Engine) do
  975.         begin
  976.           FPlayerSprite := Self;
  977.           Z := 1;
  978.           X := Self.X-Width;
  979.           Y := Self.Y+Self.Height div 2-Height div 2;
  980.         end;
  981.         Inc(FTamaF);
  982.         if FTamaF>Random(30) then FPutTama := False;
  983.         FTamaT := 0;
  984.       end;
  985.       FTamaT := FTamaT + MoveCount;
  986.     end
  987.     else
  988.     begin
  989.       FTamaT := FTamaT + MoveCount;
  990.       if FTamaT>2000+Random(500) then
  991.       begin
  992.         FPutTama := True;
  993.         FTamaF := 0;
  994.         FTamaT := 0;
  995.       end;
  996.     end;
  997.   end
  998.   else if FMode=2 then
  999.   begin
  1000.     inc(waiter1);
  1001.     if waiter1 = 3 then
  1002.     begin
  1003.       waiter1 := 0;
  1004.       inc(waiter2);
  1005.       if waiter2 <= 20 then
  1006.       begin
  1007.         with TExplosion.Create(Engine) do
  1008.         begin
  1009.           Z := 10;
  1010.           X := Self.X+Random(Self.Width)-16;
  1011.           Y := Self.Y+Random(Self.Height)-16;
  1012.         end;
  1013.       end
  1014.       else
  1015.       begin
  1016.         Inc(MainForm.FScore, 1000);
  1017.         FMode := 3;
  1018.       end;
  1019.     end;
  1020.   end
  1021.   else if FMode=3 then
  1022.   begin
  1023.     if FCounter>4000 then Dead;
  1024.   end;
  1025.   inc(FCounter, MoveCount);
  1026. end;
  1027.  
  1028. constructor TEnemyAttacker2.Create(AParent: TSprite; ALifes: integer);
  1029. begin
  1030.   inherited Create(AParent, ALifes);
  1031.   Image := MainForm.ImageList.Items.Find('Enemy-Attacker2');
  1032.   Width := Image.Width;
  1033.   Height := Image.Height;
  1034.   AnimCount := Image.PatternCount;
  1035.   AnimLooped := True;
  1036.   AnimSpeed := DEFAULT_ANIMSPEED;
  1037.   PixelCheck := True;
  1038. end;
  1039.  
  1040. procedure TEnemyAttacker2.HitEnemy(ADead: Boolean);
  1041. begin
  1042.   inherited HitEnemy(ADead);
  1043.  
  1044.   if ADead then
  1045.   begin
  1046.     FMode := 2;
  1047.     FCounter := 0;
  1048.     Inc(MainForm.FScore, 5000);
  1049.     Image := MainForm.ImageList.Items.Find('Explosion');
  1050.     Width := Image.Width;
  1051.     Height := Image.Height;
  1052.     AnimCount := Image.PatternCount;
  1053.     AnimLooped := False;
  1054.     AnimSpeed := DEFAULT_ANIMSPEED;
  1055.     AnimPos := 0;
  1056.   end
  1057.   else
  1058.   begin
  1059.     Inc(MainForm.FScore, 100);
  1060.   end;
  1061. end;
  1062.  
  1063. procedure TEnemyAttacker2.DoMove(MoveCount: Integer);
  1064. begin
  1065.   inherited DoMove(MoveCount);
  1066.   if FMode=0 then
  1067.   begin
  1068.     if X>((mainform.dxdraw.width/4) + (mainform.dxdraw.width/2) - (width/2)){450} then
  1069.       X := X - MoveCount*(300/1000)
  1070.     else
  1071.     begin
  1072.       Collisioned := True;
  1073.       FMode := 1;
  1074.       FPutTama := True;
  1075.     end;
  1076.     Y := Y + Cos256(FCounter div 15)*5;
  1077.   end
  1078.   else if FMode=1 then
  1079.   begin
  1080.     Y := Y + Cos256(FCounter div 15)*5;
  1081.     if FPutTama then
  1082.     begin
  1083.       if FTamaT>100 then
  1084.       begin
  1085.         with TEnemyTama.Create(Engine) do
  1086.         begin
  1087.           FPlayerSprite := Self;
  1088.           Z := 1;
  1089.           X := Self.X-Width;
  1090.           Y := Self.Y+Self.Height div 2-Height div 2;
  1091.         end;
  1092.         Inc(FTamaF);
  1093.         if FTamaF>Random(30) then FPutTama := False;
  1094.         FTamaT := 0;
  1095.       end;
  1096.       FTamaT := FTamaT + MoveCount;
  1097.     end
  1098.     else
  1099.     begin
  1100.       FTamaT := FTamaT + MoveCount;
  1101.       if FTamaT>2000+Random(500) then
  1102.       begin
  1103.         FPutTama := True;
  1104.         FTamaF := 0;
  1105.         FTamaT := 0;
  1106.       end;
  1107.     end;
  1108.   end
  1109.   else if FMode=2 then
  1110.   begin
  1111.     if FCounter>200 then Dead;
  1112.   end;
  1113.   inc(FCounter, MoveCount);
  1114. end;
  1115.  
  1116. procedure TEnemyAttacker3.HitEnemy(ADead: Boolean);
  1117. begin
  1118.   inherited HitEnemy(ADead);
  1119.  
  1120.   if ADead then
  1121.   begin
  1122.     FMode := 1;
  1123.     FCounter := 0;
  1124.     Inc(MainForm.FScore, 5000);
  1125.     Image := MainForm.ImageList.Items.Find('Explosion');
  1126.     Width := Image.Width;
  1127.     Height := Image.Height;
  1128.     AnimCount := Image.PatternCount;
  1129.     AnimLooped := False;
  1130.     AnimSpeed := DEFAULT_ANIMSPEED;
  1131.     AnimPos := 0;
  1132.   end
  1133.   else
  1134.   begin
  1135.     Inc(MainForm.FScore, 100);
  1136.   end;
  1137. end;
  1138.  
  1139. procedure TEnemyAttacker3.DoMove(MoveCount: Integer);
  1140. begin
  1141.   inherited DoMove(MoveCount);
  1142.   if FMode=0 then
  1143.   begin
  1144.     X := X - (250/1000)*MoveCount;
  1145.     if X<-Width then Dead;
  1146.     if FCounter-FOldTamaTime>=100 then
  1147.     begin
  1148.       Inc(FTamaCount);
  1149.       with TEnemyTama.Create(Engine) do
  1150.       begin
  1151.         FPlayerSprite := Self;
  1152.         X := Self.X;
  1153.         Y := Self.Y+Self.Height div 2-Height div 2;
  1154.         Z := 10;
  1155.       end;
  1156.       FOldTamaTime := FCounter;
  1157.      end;
  1158.   end
  1159.   else if FMode=1 then
  1160.   begin
  1161.     if FCounter>200 then Dead;
  1162.   end;
  1163.   inc(FCounter, MoveCount);
  1164. end;
  1165.  
  1166. constructor TEnemyAttacker3.Create(AParent: TSprite; ALifes: integer);
  1167. begin
  1168.   inherited Create(AParent, ALifes);
  1169.   Image := MainForm.ImageList.Items.Find('Enemy-Attacker3');
  1170.   Width := Image.Width;
  1171.   Height := Image.Height;
  1172.   AnimCount := Image.PatternCount;
  1173.   AnimLooped := True;
  1174.   AnimSpeed := DEFAULT_ANIMSPEED;
  1175.   PixelCheck := True;
  1176. end;
  1177.  
  1178. function TMainForm.SoundKarte: boolean;
  1179. begin
  1180.   result := WaveOutGetNumDevs > 0;
  1181. end;
  1182.  
  1183. procedure TMainForm.FormCreate(Sender: TObject);
  1184. var
  1185.   Ergebnis: string;
  1186.   daten: textfile;
  1187.   ok: boolean;
  1188. begin
  1189.   { Beginne VCL-Ersatz }
  1190.   dxtimer := tdxtimer.Create(self);
  1191.   dxtimer.Interval := 33;
  1192.   dxtimer.OnActivate := DXTimerActivate;
  1193.   dxtimer.OnDeactivate := DXTimerDeactivate;
  1194.   dxtimer.OnTimer := DXTimerTimer;
  1195.   dxtimer.ActiveOnly := false;
  1196.   dxtimer.Enabled := false;
  1197.  
  1198.   dxdraw := tdxdraw.Create(self);
  1199.   dxdraw.Parent := self;
  1200.   dxdraw.Align := alClient;
  1201.   dxdraw.Left := 0;
  1202.   dxdraw.Top := 0;
  1203.   dxdraw.Width := 640;
  1204.   dxdraw.Height := 480;
  1205.   dxdraw.AutoInitialize := False;
  1206.   dxdraw.AutoSize := False;
  1207.   dxdraw.Color := clBlack;
  1208.   dxdraw.Display.BitCount := 24;
  1209.   dxdraw.Display.FixedBitCount := False;
  1210.   dxdraw.Display.FixedRatio := False;
  1211.   dxdraw.Display.FixedSize := False;
  1212.   dxdraw.Display.Height := 600;
  1213.   dxdraw.Display.Width := 800;
  1214.   dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
  1215.   dxdraw.TabOrder := 0;
  1216.   dxdraw.Visible := true;
  1217.   dxdraw.OnFinalize := DXDrawFinalize;
  1218.   dxdraw.OnInitialize := DXDrawInitialize;
  1219.   dxdraw.OnInitializing := DXDrawInitializing;
  1220.  
  1221.   dxsound := tdxsound.Create(self);
  1222.   dxsound.AutoInitialize := false;
  1223.  
  1224.   dxinput := tdxinput.Create(self);
  1225.   dxinput.Joystick.ForceFeedback := true;
  1226.   dxinput.Keyboard.ForceFeedback := true;
  1227.  
  1228.   wavelist := tdxwavelist.Create(self);
  1229.   wavelist.DXSound := dxsound;
  1230.  
  1231.   imagelist := tdximagelist.create(self);
  1232.   imagelist.DXDraw := dxdraw;
  1233.  
  1234.   spriteengine := tdxspriteengine.create(self);
  1235.   spriteengine.DXDraw := dxdraw;
  1236.  
  1237.   InitializeCriticalSection(TimerCS);
  1238.  
  1239.   { Ende VCL-Ersatz }
  1240.  
  1241.   Application.Title := 'SpaceMission '+ProgramVersion;
  1242.   LoadOptions;
  1243.   DXInit;
  1244.   SoundInit;
  1245.   MusicInit;
  1246.   DeleteArray;
  1247.   if (paramcount = 0) and (fileexists(paramstr(1))) then // (paramcount > 0)
  1248.   begin
  1249.     AssignFile(daten, paramstr(1));
  1250.     Reset(daten);
  1251.     ok := true;
  1252.     ReadLN(daten, Ergebnis);
  1253.     if Ergebnis <> '; SpaceMission '+ProgramVersion then ok := false;
  1254.     ReadLN(daten, Ergebnis);
  1255.     if ergebnis <> '; SAV-File' then ok := false;
  1256.     if not ok then
  1257.     begin
  1258.       showmessage(FileError);
  1259.       CloseFile(daten);
  1260.       GameStartClick(GameStart);
  1261.       exit;
  1262.     end;
  1263.     ReadLN(daten, mainform.FScore);
  1264.     ReadLN(daten, mainform.FLife);
  1265.     ReadLN(daten, mainform.Flevel);
  1266.     ReadLN(daten, mainform.FMenuItem);
  1267.     CloseFile(daten);
  1268.     mainform.FNextScene := gsNewLevel;
  1269.     exit;
  1270.   end;
  1271.   GameStartClick(GameStart);
  1272. end;
  1273.  
  1274. procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
  1275.   Shift: TShiftState);
  1276. begin
  1277.   if (ssAlt in Shift) and (Key=VK_RETURN) then
  1278.     OptionFullScreenClick(OptionFullScreen);
  1279. end;
  1280.  
  1281. procedure TMainForm.GameStartClick(Sender: TObject);
  1282. begin
  1283.   StartScene(gsTitle);
  1284. end;
  1285.  
  1286. procedure TMainForm.GamePauseClick(Sender: TObject);
  1287. begin
  1288.   GamePause.Checked := not GamePause.Checked;
  1289.   DXTimer.Enabled := not GamePause.Checked;
  1290.   if GamePause.Checked then
  1291.     PauseMusic(FMusic)
  1292.   else
  1293.     ResumeMusic(FMusic);
  1294. end;
  1295.  
  1296. // http://www.delphipraxis.net/post43515.html
  1297. Function GetHTML(AUrl: string): string;
  1298. var
  1299.   databuffer : array[0..4095] of char;
  1300.   ResStr : string;
  1301.   hSession, hfile: hInternet;
  1302.   dwindex,dwcodelen,dwread,dwNumber: cardinal;
  1303.   dwcode : array[1..20] of char;
  1304.   res    : pchar;
  1305.   Str    : pchar;
  1306. begin
  1307.   ResStr:='';
  1308.   if system.pos('http://',lowercase(AUrl))=0 then
  1309.      AUrl:='http://'+AUrl;
  1310.  
  1311.   // Hinzugefügt
  1312.   application.ProcessMessages;
  1313.  
  1314.   hSession:=InternetOpen('InetURL:/1.0',
  1315.                          INTERNET_OPEN_TYPE_PRECONFIG,
  1316.                          nil,
  1317.                          nil,
  1318.                          0);
  1319.   if assigned(hsession) then
  1320.   begin
  1321.     // Hinzugefügt
  1322.     application.ProcessMessages;
  1323.  
  1324.     hfile:=InternetOpenUrl(
  1325.            hsession,
  1326.            pchar(AUrl),
  1327.            nil,
  1328.            0,
  1329.            INTERNET_FLAG_RELOAD,
  1330.            0);
  1331.     dwIndex  := 0;
  1332.     dwCodeLen := 10;
  1333.  
  1334.     // Hinzugefügt
  1335.     application.ProcessMessages;
  1336.  
  1337.     HttpQueryInfo(hfile,
  1338.                   HTTP_QUERY_STATUS_CODE,
  1339.                   @dwcode,
  1340.                   dwcodeLen,
  1341.                   dwIndex);
  1342.     res := pchar(@dwcode);
  1343.     dwNumber := sizeof(databuffer)-1;
  1344.     if (res ='200') or (res ='302') then
  1345.     begin
  1346.       while (InternetReadfile(hfile,
  1347.                               @databuffer,
  1348.                               dwNumber,
  1349.                               DwRead)) do
  1350.       begin
  1351.  
  1352.         // Hinzugefügt
  1353.         application.ProcessMessages;
  1354.  
  1355.         if dwRead =0 then
  1356.           break;
  1357.         databuffer[dwread]:=#0;
  1358.         Str := pchar(@databuffer);
  1359.         resStr := resStr + Str;
  1360.       end;
  1361.     end
  1362.     else
  1363.       ResStr := 'Status:'+res;
  1364.     if assigned(hfile) then
  1365.       InternetCloseHandle(hfile);
  1366.   end;
  1367.  
  1368.   // Hinzugefügt
  1369.   application.ProcessMessages;
  1370.  
  1371.   InternetCloseHandle(hsession);
  1372.   Result := resStr;
  1373. end;
  1374.  
  1375. procedure TMainForm.CheckUpdatesClick(Sender: TObject);
  1376. var
  1377.   temp: string;
  1378. begin
  1379.   temp := GetHTML('http://www.viathinksoft.de/update/?id=spacemission');
  1380.   if copy(temp, 0, 7) = 'Status:' then
  1381.   begin
  1382.     Application.MessageBox('Ein Fehler ist aufgetreten. Wahrscheinlich ist keine Internetverbindung aufgebaut, oder der der ViaThinkSoft-Server temporär offline.', 'Fehler', MB_OK + MB_ICONERROR)
  1383.   end
  1384.   else
  1385.   begin
  1386.     if GetHTML('http://www.viathinksoft.de/update/?id=spacemission') <> ProgramVersion then
  1387.     begin
  1388.       if Application.MessageBox('Eine neue Programmversion ist vorhanden. Möchten Sie diese jetzt herunterladen?', 'Information', MB_YESNO + MB_ICONASTERISK) = ID_YES then
  1389.         shellexecute(application.handle, 'open', pchar('http://www.viathinksoft.de/update/?id=@spacemission'), '', '', sw_normal);
  1390.     end
  1391.     else
  1392.     begin
  1393.       Application.MessageBox('Es ist keine neue Programmversion vorhanden.', 'Information', MB_OK + MB_ICONASTERISK);
  1394.     end;
  1395.   end;
  1396. end;
  1397.  
  1398. procedure TMainForm.BeendenClick(Sender: TObject);
  1399. begin
  1400.   close;
  1401. end;
  1402.  
  1403. procedure TMainForm.OptionFullScreenClick(Sender: TObject);
  1404. begin
  1405.   OptionFullScreen.Checked := not OptionFullScreen.Checked;
  1406.   DXInit;
  1407.   writeoptions;
  1408. end;
  1409.  
  1410. procedure TMainForm.OptionSoundClick(Sender: TObject);
  1411. begin
  1412.   OptionSound.Checked := not OptionSound.Checked;
  1413.   SoundInit;
  1414.   WriteOptions;
  1415. end;
  1416.  
  1417. procedure TMainForm.SoundInit;
  1418. begin
  1419.   if OptionSound.Checked then
  1420.   begin
  1421.     if not DXSound.Initialized then
  1422.     begin
  1423.       try
  1424.         DXSound.Initialize;
  1425.         WaveList.Items.LoadFromFile(FDirectory+'DirectX\Sound.dxw');
  1426.       except
  1427.         OptionSound.enabled := False;
  1428.         WaveList.items.clear;
  1429.       end;
  1430.     end;
  1431.   end
  1432.   else DXSound.Finalize;
  1433. end;
  1434.  
  1435. procedure TMainForm.MusicInit;
  1436. begin
  1437.   optionmusic.enabled := SoundKarte;
  1438. end;
  1439.  
  1440. procedure TMainForm.DestroyMusic(Name: TMusicTrack);
  1441. begin
  1442.   if Name = mtBoss then
  1443.   begin
  1444.     MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
  1445.     MCISendString(pchar('close "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
  1446.   end;
  1447.   if Name = mtGame then
  1448.   begin
  1449.     MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
  1450.     MCISendString(pchar('close "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
  1451.   end;
  1452.   if Name = mtScene then
  1453.   begin
  1454.     MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
  1455.     MCISendString(pchar('close "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
  1456.   end;
  1457.   if Name = mtTitle then
  1458.   begin
  1459.     MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
  1460.     MCISendString(pchar('close "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
  1461.   end;
  1462. end;
  1463.  
  1464. procedure TMainForm.OpenMusic(Name: TMusicTrack);
  1465. begin
  1466.   if Name = mtBoss then
  1467.     MCISendString(pchar('open "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
  1468.   if Name = mtGame then
  1469.     MCISendString(pchar('open "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
  1470.   if Name = mtScene then
  1471.     MCISendString(pchar('open "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
  1472.   if Name = mtTitle then
  1473.     MCISendString(pchar('open "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
  1474. end;
  1475.  
  1476. procedure TMainForm.PauseMusic(Name: TMusicTrack);
  1477. begin
  1478.   if not OptionMusic.checked then exit;
  1479.   if Name = mtBoss then
  1480.     MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
  1481.   if Name = mtGame then
  1482.     MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
  1483.   if Name = mtScene then
  1484.     MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
  1485.   if Name = mtTitle then
  1486.     MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
  1487. end;
  1488.  
  1489. procedure TMainForm.DXDrawInitializing(Sender: TObject);
  1490. begin
  1491.   if doFullScreen in DXDraw.Options then
  1492.   begin
  1493.     BorderStyle := bsNone;
  1494.     DXDraw.Cursor := crNone;
  1495.   end
  1496.   else
  1497.   begin
  1498.     BorderStyle := bsSingle;
  1499.     DXDraw.Cursor := crDefault;
  1500.   end;
  1501. end;
  1502.  
  1503. procedure TMainForm.DXDrawInitialize(Sender: TObject);
  1504. begin
  1505.   DXTimer.Enabled := True;
  1506. end;
  1507.  
  1508. procedure TMainForm.DXDrawFinalize(Sender: TObject);
  1509. begin
  1510.   DXTimer.Enabled := False;
  1511. end;
  1512.  
  1513. procedure TMainForm.DXTimerActivate(Sender: TObject);
  1514. begin
  1515.   Caption := Application.Title;
  1516.   if not ProgrammGestartet then
  1517.   begin
  1518.     Programmgestartet := true;
  1519.     exit;
  1520.   end;
  1521.   ResumeMusic(FMusic);
  1522. end;
  1523.  
  1524. procedure TMainForm.DXTimerDeactivate(Sender: TObject);
  1525. begin
  1526.   Caption := Application.Title + ' [Pause]';
  1527.   PauseMusic(FMusic);
  1528. end;
  1529.  
  1530. function TMainForm.StatusMusic(Name: TMusicTrack): string;
  1531. var
  1532.   MCIStatus: array[0..255] of char;
  1533. begin
  1534.   if not OptionMusic.checked then exit;
  1535.   if FMusic = mtGame then
  1536.     MCISendString(pchar('status "'+FDirectory+'Musik\Game.mid" mode'), MCIStatus, 255, 0);
  1537.   if FMusic = mtBoss then
  1538.     MCISendString(pchar('status "'+FDirectory+'Musik\Boss.mid" mode'), MCIStatus, 255, 0);
  1539.   if FMusic = mtScene then
  1540.     MCISendString(pchar('status "'+FDirectory+'Musik\Scene.mid" mode'), MCIStatus, 255, 0);
  1541.   if FMusic = mtTitle then
  1542.     MCISendString(pchar('status "'+FDirectory+'Musik\Title.mid" mode'), MCIStatus, 255, 0);
  1543.   result := MCIStatus;
  1544. end;
  1545.  
  1546. procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
  1547. begin
  1548.   EnterCriticalSection(TimerCS);
  1549.   try
  1550.     if StatusMusic(FMusic) = 'stopped' then
  1551.       PlayMusic(FMusic); {...}
  1552.     if crash then
  1553.     begin
  1554.       inc(Crash2);
  1555.       if crash2 = 30 then
  1556.       begin
  1557.         Crash2 := 0;
  1558.         crash := false;
  1559.         crashsound := false;
  1560.       end;
  1561.     end;
  1562.     if not DXDraw.CanDraw then exit;
  1563.     DXInput.Update;
  1564.     case FScene of
  1565.       gsTitle   : SceneTitle;
  1566.       gsMain    : SceneMain;
  1567.       gsGameOver: SceneGameOver;
  1568.       gsWin     : SceneWin;
  1569.       gsNewLevel: SceneNewLevel;
  1570.     end;
  1571.     if FNextScene<>gsNone then
  1572.     begin
  1573.       StartScene(FNextScene);
  1574.       FNextScene := gsNone;
  1575.     end;
  1576.     DXDraw.Flip;
  1577.   finally
  1578.     LeaveCriticalSection(TimerCS);
  1579.   end;
  1580. end;
  1581.  
  1582. procedure TMainForm.BlinkStart;
  1583. begin
  1584.   FBlink := 0;
  1585.   FBlinkTime := GetTickCount;
  1586. end;
  1587.  
  1588. procedure TMainForm.WriteOptions;
  1589. var
  1590.   INIDatei: TIniFile;
  1591. begin
  1592.   INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
  1593.   try
  1594.     if OptionMusic.checked then INIDatei.WriteBool('Settings', 'Music', true)
  1595.       else INIDatei.WriteBool('Settings', 'Music', false);
  1596.     if OptionSound.checked then INIDatei.WriteBool('Settings', 'Sound', true)
  1597.       else INIDatei.WriteBool('Settings', 'Sound', false);
  1598.     if OptionFullScreen.checked then INIDatei.WriteBool('Settings', 'FullScreen', true)
  1599.       else INIDatei.WriteBool('Settings', 'FullScreen', false);
  1600.     if OptionBreitbild.checked then INIDatei.WriteBool('Settings', 'ScreenAutoSize', true)
  1601.       else INIDatei.WriteBool('Settings', 'ScreenAutoSize', false);
  1602.     if FInterval = giLeicht then INIDatei.WriteInteger('Settings', 'Speed', 1);
  1603.     if FInterval = giMittel then INIDatei.WriteInteger('Settings', 'Speed', 2);
  1604.     if FInterval = giSchwer then INIDatei.WriteInteger('Settings', 'Speed', 3);
  1605.     if FInterval = giMaster then INIDatei.WriteInteger('Settings', 'Speed', 4);
  1606.   finally
  1607.     INIDatei.Free;
  1608.   end;
  1609. end;
  1610.  
  1611. procedure TMainForm.LoadOptions;
  1612. var
  1613.   INIDatei: TIniFile;
  1614. begin
  1615.   INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
  1616.   try
  1617.     optionmusic.checked := INIDatei.ReadBool('Settings', 'Music', true);
  1618.     optionsound.checked := INIDatei.ReadBool('Settings', 'Sound', true);
  1619.     optionfullscreen.checked := INIDatei.ReadBool('Settings', 'fullscreen', false);
  1620.     OptionBreitBild.checked := INIDatei.ReadBool('Settings', 'ScreenAutoSize', true);
  1621.     if INIDatei.ReadInteger('Settings', 'Speed', 2) = 1 then
  1622.     begin
  1623.       FInterval := giLeicht;
  1624.       Leicht.checked := true;
  1625.     end;
  1626.     if INIDatei.ReadInteger('Settings', 'Speed', 2) = 2 then
  1627.     begin
  1628.       FInterval := giMittel;
  1629.       Mittel.checked := true;
  1630.     end;
  1631.     if INIDatei.ReadInteger('Settings', 'Speed', 2) = 3 then
  1632.     begin
  1633.       FInterval := giSchwer;
  1634.       Schwer.checked := true;
  1635.     end;
  1636.     if INIDatei.ReadInteger('Settings', 'Speed', 2) = 4 then
  1637.     begin
  1638.       FInterval := giMaster;
  1639.       Master.checked := true;
  1640.     end;
  1641.   finally
  1642.     INIDatei.Free;
  1643.   end;
  1644.   WriteOptions;
  1645. end;
  1646.  
  1647. procedure TMainForm.BlinkUpdate;
  1648. begin
  1649.   if GetTickCount<>FBlinkTime then
  1650.   begin
  1651.     FBlink := FBlink + (GetTickCount-FBlinkTime);
  1652.     FBlinkTime := GetTickCount;
  1653.   end;
  1654. end;
  1655.  
  1656. procedure TMainForm.PlaySound(Name: string; Wait: Boolean);
  1657. begin
  1658.   if (OptionSound.Checked) and (OptionSound.Enabled) then
  1659.     WaveList.Items.Find(Name).Play(Wait);
  1660. end;
  1661.  
  1662. procedure TMainForm.PlayMusic(Name: TMusicTrack);
  1663. begin
  1664.   if (not mainform.active) and (mainform.visible) then //1st Programmstart
  1665.     exit;
  1666.   if (OptionMusic.checked) and (OptionMusic.enabled) then
  1667.   begin
  1668.     DestroyMusic(FMusic);
  1669.     OpenMusic(Name);
  1670.     ResumeMusic(Name);
  1671.   end;
  1672.   FMusic := Name;
  1673. end;
  1674.  
  1675. function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  1676. begin
  1677.   with Result do
  1678.   begin
  1679.     rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
  1680.     rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
  1681.     rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
  1682.     rgbReserved := 0;
  1683.   end;
  1684. end;
  1685.  
  1686. procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
  1687. var
  1688.   i: Integer;
  1689.   t, t2: DWORD;
  1690.   ChangePalette: Boolean;
  1691.   c: Integer;
  1692. begin
  1693.   if DXDraw.Initialized then
  1694.   begin
  1695.     c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
  1696.     ChangePalette := False;
  1697.     if DXDraw.CanPaletteAnimation then
  1698.     begin
  1699.       t := GetTickCount;
  1700.       while Abs(GetTickCount-t)<Time do
  1701.       begin
  1702.         t2 := Trunc(Abs(GetTickCount-t)/Time*255);
  1703.         for i := 0 to 255 do
  1704.           DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
  1705.         DXDraw.UpdatePalette;
  1706.         ChangePalette := True;
  1707.       end;
  1708.     end
  1709.     else
  1710.     begin
  1711.       Sleep(Time);
  1712.     end;
  1713.     for i := 0 to 4 do
  1714.     begin
  1715.       DXDraw.Surface.Fill(c);
  1716.       DXDraw.Flip;
  1717.     end;
  1718.     if ChangePalette then
  1719.     begin
  1720.       DXDraw.ColorTable := DXDraw.DefColorTable;
  1721.       DXDraw.UpdatePalette;
  1722.     end;
  1723.     DXDraw.Surface.Fill(c);
  1724.     DXDraw.Flip;
  1725.   end;
  1726. end;
  1727.  
  1728. procedure TMainForm.StartScene(Scene: TGameScene);
  1729. begin
  1730.   EndScene;
  1731.   DXInput.States := DXInput.States - DXInputButton;
  1732.   FScene := Scene;
  1733.   BlinkStart;
  1734.   case FScene of
  1735.     gsTitle   : StartSceneTitle;
  1736.     gsMain    : StartSceneMain;
  1737.     gsGameOver: StartSceneGameOver;
  1738.     gsWin     : StartSceneWin;
  1739.     gsNewLevel: StartSceneNewLevel;
  1740.   end;
  1741. end;
  1742.  
  1743. procedure TMainForm.StartSceneTitle;
  1744. begin
  1745.   sleep(500);
  1746.   FCheat := false;
  1747.   BossExists := false;
  1748.   FLife := Lives;
  1749.   FLevel := 0;
  1750.   FScore := 0;
  1751.   FNotSave := true;
  1752.   Cheat.enabled := false;
  1753.   Neustart.enabled := false;
  1754.   GamePause.enabled := false;
  1755.   GameStart.enabled := false;
  1756.   Spielgeschwindigkeit.enabled := false;
  1757.   mainform.Visible := true;
  1758.   PlayMusic(mtTitle);
  1759. end;
  1760.  
  1761. procedure TMainForm.StartSceneMain;
  1762. {var
  1763.   i, j: Integer;}
  1764. begin
  1765.   sleep(500);
  1766.   FCounter := 0;
  1767.   NewLevel(FLevel);
  1768.   BossExists := false;
  1769.   PlayMusic(mtGame);
  1770.   FEnemyAdventPos := 0;
  1771.   FFrame := -4;
  1772.   PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
  1773.   with TBackground.Create(SpriteEngine.Engine) do
  1774.   begin
  1775.     SetMapSize(1, 1);
  1776.     Image := mainform.ImageList.Items.Find('Star3');
  1777.     Z := -13;
  1778.     Y := 40;
  1779.     FSpeed := 1 / 2;
  1780.     Tile := True;
  1781.   end;
  1782.   with TBackground.Create(SpriteEngine.Engine) do
  1783.   begin
  1784.     SetMapSize(1, 1);
  1785.     Image := mainform.ImageList.Items.Find('Star2');
  1786.     Z := -12;
  1787.     Y := 30;
  1788.     FSpeed := 1;
  1789.     Tile := True;
  1790.   end;
  1791.   with TBackground.Create(SpriteEngine.Engine) do
  1792.   begin
  1793.     SetMapSize(1, 1);
  1794.     Image := mainform.ImageList.Items.Find('Star1');
  1795.     Z := -11;
  1796.     Y := 10;
  1797.     FSpeed := 2;
  1798.     Tile := True;
  1799.   end;
  1800.   {with TBackground.Create(SpriteEngine.Engine) do
  1801.   begin
  1802.     SetMapSize(200, 10);
  1803.     Y := 10;
  1804.     Z := -13;
  1805.     FSpeed := 1 / 2;
  1806.     Tile := True;
  1807.     for i := 0 to MapHeight-1 do
  1808.     begin
  1809.       for j := 0 to MapWidth-1 do
  1810.       begin
  1811.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
  1812.         if Random(100)<95 then Chips[j, i] := -1;
  1813.       end;
  1814.     end;
  1815.   end;
  1816.   with TBackground.Create(SpriteEngine.Engine) do
  1817.   begin
  1818.     SetMapSize(200, 10);
  1819.     Y := 30;
  1820.     Z := -12;
  1821.     FSpeed := 1;
  1822.     Tile := True;
  1823.     for i := 0 to MapHeight-1 do
  1824.     begin
  1825.       for j := 0 to MapWidth-1 do
  1826.       begin
  1827.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
  1828.         if Random(100)<95 then Chips[j, i] := -1;
  1829.       end;
  1830.     end;
  1831.   end;
  1832.   with TBackground.Create(SpriteEngine.Engine) do
  1833.   begin
  1834.     SetMapSize(200, 10);
  1835.     Y := 40;
  1836.     Z := -11;
  1837.     FSpeed := 2;
  1838.     Tile := True;
  1839.     for i := 0 to MapHeight-1 do
  1840.     begin
  1841.       for j := 0 to MapWidth-1 do
  1842.       begin
  1843.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
  1844.         if Random(100)<95 then Chips[j, i] := -1;
  1845.       end;
  1846.     end;
  1847.   end;}
  1848.   FNotSave := false;
  1849.   Cheat.enabled := true;
  1850.   Neustart.enabled := true;
  1851.   GamePause.enabled := true;
  1852.   GameStart.enabled := true;
  1853.   Spielgeschwindigkeit.enabled := true;
  1854. end;
  1855.  
  1856. procedure TMainForm.StartSceneGameOver;
  1857. begin
  1858.   sleep(500);
  1859.   FNotSave := true;
  1860.   Cheat.enabled := false;
  1861.   Spielgeschwindigkeit.enabled := false;
  1862.   Neustart.enabled := false;
  1863.   GamePause.enabled := false;
  1864.   PlayMusic(mtScene);
  1865.   BossExists := false;
  1866. end;
  1867.  
  1868. procedure TMainForm.StartSceneWin;
  1869. begin
  1870.   sleep(500);
  1871.   FNotSave := true;
  1872.   Cheat.enabled := false;
  1873.   Spielgeschwindigkeit.enabled := false;
  1874.   Neustart.enabled := false;
  1875.   GamePause.enabled := false;
  1876.   PlayMusic(mtScene);
  1877.   BossExists := false;
  1878. end;
  1879.  
  1880. procedure TMainForm.EndScene;
  1881. begin
  1882.   case FScene of
  1883.     gsTitle   : EndSceneTitle;
  1884.     gsMain    : EndSceneMain;
  1885.     gsGameOver: EndSceneGameOver;
  1886.     gsWin     : EndSceneWin;
  1887.     gsNewLevel: EndSceneNewLevel;
  1888.   end;
  1889. end;
  1890.  
  1891. procedure TMainForm.EndSceneTitle;
  1892. begin
  1893.   {  Ende Title  }
  1894. end;
  1895.  
  1896. procedure TMainForm.EndSceneMain;
  1897. begin
  1898.   SpriteEngine.Engine.Clear;
  1899. end;
  1900.  
  1901. procedure TMainForm.EndSceneGameOver;
  1902. begin
  1903.   {  Ende GameOver  }
  1904. end;
  1905.  
  1906. procedure TMainForm.EndSceneWin;
  1907. begin
  1908.   {  Ende Win  }
  1909. end;
  1910.  
  1911. procedure TMainForm.DeleteArray();
  1912. begin
  1913.   SetLength(EnemyAdventTable, 0);
  1914.   FRestEnemies := 0;
  1915. end;
  1916.  
  1917. const
  1918.   ADDITIONAL_ENEMIES_PER_LEVEL = 75;
  1919.  
  1920. function GetLevelFileName(lev: integer): string;
  1921. begin
  1922.   result := FDirectory+'Levels\Level '+inttostr(lev)+'.lev';
  1923. end;
  1924.  
  1925. procedure TMainForm.NewLevel(lev: integer);
  1926. resourcestring
  1927.   LNG_LEVEL_INVALID = 'Das Level Nr. %d ist ungültig!'+#13#10+'Das Programm wird beendet.';
  1928. var
  1929.   act: integer;
  1930.   filex: textfile;
  1931.   ergebniss: string;
  1932.   Enemies: array[1..27] of TEnemyClass;
  1933.   e: TEnemyAdvent;
  1934. begin
  1935.   DeleteArray;
  1936.   if FMenuItem = 2 then
  1937.   begin
  1938.     Enemies[1] := TEnemyAttacker;
  1939.     Enemies[2] := TEnemyMeteor;
  1940.     Enemies[3] := TEnemyUFO;
  1941.     Enemies[4] := TEnemyAttacker;
  1942.     Enemies[5] := TEnemyMeteor;
  1943.     Enemies[6] := TEnemyUFO;
  1944.     Enemies[7] := TEnemyAttacker;
  1945.     Enemies[8] := TEnemyMeteor;
  1946.     Enemies[9] := TEnemyUFO;
  1947.     Enemies[10] := TEnemyAttacker;
  1948.     Enemies[11] := TEnemyMeteor;
  1949.     Enemies[12] := TEnemyUFO;
  1950.     Enemies[13] := TEnemyAttacker;
  1951.     Enemies[14] := TEnemyMeteor;
  1952.     Enemies[15] := TEnemyUFO;
  1953.     Enemies[16] := TEnemyAttacker3;
  1954.     Enemies[17] := TEnemyAttacker;
  1955.     Enemies[18] := TEnemyMeteor;
  1956.     Enemies[19] := TEnemyUFO;
  1957.     Enemies[20] := TEnemyUFO2;
  1958.     Enemies[21] := TEnemyAttacker;
  1959.     Enemies[22] := TEnemyMeteor;
  1960.     Enemies[23] := TEnemyUFO;
  1961.     Enemies[24] := TEnemyAttacker2;
  1962.     Enemies[25] := TEnemyMeteor;
  1963.     Enemies[26] := TEnemyUFO;
  1964.     Enemies[27] := TEnemyAttacker;
  1965.     randomize;
  1966.     FRestEnemies := lev*ADDITIONAL_ENEMIES_PER_LEVEL+1;
  1967.     SetLength(EnemyAdventTable, FRestEnemies);
  1968.     for act := 0 to lev*ADDITIONAL_ENEMIES_PER_LEVEL-1 do
  1969.     begin
  1970.       e.spriteClass := Enemies[min(random(lev+2)+1, High(Enemies))];
  1971.       if e.spriteClass = TEnemyAttacker2 then
  1972.       begin
  1973.         e.spriteClass := Enemies[min(random(lev+2)+1, High(Enemies))]; {O_o}
  1974.       end;
  1975.       e.x := act*30 + random(85-(lev+(random(lev))*2)){O_o};
  1976.       e.y := random(dxdraw.surfaceheight);
  1977.       if e.spriteClass = TEnemyAttacker2 then
  1978.       begin
  1979.         e.lifes := random(6)+1{O_o};
  1980.       end
  1981.       else
  1982.       begin
  1983.         e.lifes := random(lev)+1;
  1984.       end;
  1985.  
  1986.       EnemyAdventTable[act] := e;
  1987.     end;
  1988.     e.spriteClass := TEnemyBoss;
  1989.     e.x := lev*75*30{O_o} div lev;
  1990.     e.y := (dxdraw.surfaceheight div 2) - (MainForm.ImageList.Items.Find('Enemy-boss').height div 2);
  1991.     e.lifes := lev*5;
  1992.     EnemyAdventTable[lev*ADDITIONAL_ENEMIES_PER_LEVEL] := e;
  1993.   end
  1994.   else
  1995.   begin
  1996.     Enemies[1] := TEnemyAttacker;
  1997.     Enemies[2] := TEnemyAttacker2;
  1998.     Enemies[3] := TEnemyAttacker3;
  1999.     Enemies[4] := TEnemyMeteor;
  2000.     Enemies[5] := TEnemyUFO;
  2001.     Enemies[6] := TEnemyUFO2;
  2002.     Enemies[7] := TEnemyBoss;
  2003.     if fileexists(GetLevelFileName(lev)) then
  2004.     begin
  2005.       assignfile(filex, GetLevelFileName(lev));
  2006.       reset(filex);
  2007.       try
  2008.         readln(filex, ergebniss);
  2009.         Assert(ergebniss = '; SpaceMission '+FCompVersion);
  2010.         readln(filex, ergebniss);
  2011.         Assert(ergebniss = '; LEV-File');
  2012.  
  2013.         readln(filex); // Länge der Karte
  2014.  
  2015.         while not seekEoF(filex) do
  2016.         begin
  2017.           readln(filex, ergebniss);
  2018.           e.spriteClass := Enemies[strtoint(ergebniss)];
  2019.           readln(filex, ergebniss);
  2020.           e.x := strtoint(ergebniss);
  2021.           readln(filex, ergebniss);
  2022.           e.y := strtoint(ergebniss);
  2023.           readln(filex, ergebniss);
  2024.           e.lifes := strtoint(ergebniss);
  2025.  
  2026.           inc(FRestEnemies);
  2027.           SetLength(EnemyAdventTable, FRestEnemies);
  2028.           EnemyAdventTable[FRestEnemies-1] := e;
  2029.         end;
  2030.       except
  2031.         showmessage(Format(LNG_LEVEL_INVALID, [lev]));
  2032.         DeleteArray;
  2033.       end;
  2034.       closefile(filex);
  2035.     end;
  2036.   end;
  2037.   Assert(FRestEnemies = Length(EnemyAdventTable));
  2038. end;
  2039.  
  2040. procedure TMainForm.SceneTitle;
  2041. var
  2042.   Logo: TPictureCollectionItem;
  2043. begin
  2044.   DXDraw.Surface.Fill(0);
  2045.   Logo := ImageList.Items.Find('Logo');
  2046.   {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
  2047.     Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
  2048.   Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
  2049.     2, 80, Fangle * 4);
  2050.   inc(Fangle);
  2051.   with DXDraw.Surface.Canvas do
  2052.   begin
  2053.     if (isDown in MainForm.DXInput.States) and (FMenuItem=1) then FMenuItem := 2;
  2054.     if ((isUp in MainForm.DXInput.States) and (FMenuItem=2)) or (FMenuItem=0) then FMenuItem := 1;
  2055.     Brush.Style := bsClear;
  2056.     Font.Size := 30;
  2057.     if FMenuItem = 1 then
  2058.     begin
  2059.       Font.Color := clMaroon;
  2060.       Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
  2061.       Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-52, '>');
  2062.       Font.Color := clRed;
  2063.       Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
  2064.       Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
  2065.       Font.Color := clOlive;
  2066.       Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
  2067.       Font.Color := clYellow;
  2068.       Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
  2069.     end
  2070.     else
  2071.     begin
  2072.       Font.Color := clOlive;
  2073.       Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
  2074.       Font.Color := clYellow;
  2075.       Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
  2076.       Font.Color := clMaroon;
  2077.       Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
  2078.       Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
  2079.       Font.Color := clRed;
  2080.       Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
  2081.       Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
  2082.     end;
  2083.     { if (FBlink div 300) mod 2=0 then
  2084.     begin
  2085.       Font.Color := clGreen;
  2086.       Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
  2087.       Font.Color := clLime;
  2088.       Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
  2089.     end; }
  2090.     BlinkUpdate;
  2091.     Release;
  2092.   end;
  2093.   // Weiter mit Leertaste oder Enter
  2094.   if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
  2095.   begin
  2096.     FLevel := 1;
  2097.     if ((FMenuItem=1) and not fileexists(GetLevelFileName(FLevel))) or ((FMenuItem=2) and (FLevel > 20)) then
  2098.     begin
  2099.       //PlaySound('Frage', False);
  2100.       exit;
  2101.     end;
  2102.     NewLevel(FLevel);
  2103.     PlaySound('SceneMov', False);
  2104.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  2105.     Sleep(200);
  2106.     StartScene(gsMain);
  2107.   end;
  2108. end;
  2109.  
  2110. procedure TMainForm.SceneMain;
  2111. var
  2112.   Enemy: TSprite;
  2113. begin
  2114.   case FInterval of
  2115.     giMittel: SpriteEngine.Move(conleicht);
  2116.     giLeicht: SpriteEngine.Move(conmittel);
  2117.     giSchwer: SpriteEngine.Move(conschwer);
  2118.     giMaster: SpriteEngine.Move(conmaster);
  2119.   end;
  2120.   SpriteEngine.Dead;
  2121.   while (FEnemyAdventPos >= Low(EnemyAdventTable)) and
  2122.     (FEnemyAdventPos <= High(EnemyAdventTable)) and
  2123.     ((EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
  2124.     (FRestEnemies > 0) do
  2125.   begin
  2126.     Dec(FRestEnemies);
  2127.     with EnemyAdventTable[FEnemyAdventPos] do
  2128.     begin
  2129.       Enemy := spriteClass.Create(SpriteEngine.Engine, lifes);
  2130.       Enemy.x := dxdraw.surfacewidth;
  2131.       //Enemy.y := y;
  2132.       if y <> 0 then
  2133.         Enemy.y := dxdraw.surfaceheight / (480{maximale Bandbreite im alten Format} / y)
  2134.       else
  2135.         Enemy.y := 0;
  2136.     end;
  2137.     Inc(FEnemyAdventPos);
  2138.   end;
  2139.   Inc(FFrame);
  2140.   DXDraw.Surface.Fill(0);
  2141.   if FNextScene=gsNone then
  2142.   begin
  2143.     SpriteEngine.Draw;
  2144.     if MainForm.flife > 0 then
  2145.     begin
  2146.       with DXDraw.Surface.Canvas do
  2147.       begin
  2148.         Brush.Style := bsClear;
  2149.         Font.Size := 20;
  2150.         Font.Color := clOlive;
  2151.         Textout(9, 9, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
  2152.         Font.Color := clYellow;
  2153.         Textout(10, 10, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
  2154.         Font.Color := clMaroon;
  2155.         Textout(dxdraw.surfacewidth-141, 9, 'Level: ' + IntToStr(MainForm.flevel));
  2156.         Font.Color := clRed;
  2157.         Textout(dxdraw.surfacewidth-140, 10, 'Level: ' + IntToStr(MainForm.flevel));
  2158.         if FLife<0 then mainform.FLife := 0;
  2159.         if FCheat then
  2160.         begin
  2161.           Font.Color := clPurple;
  2162.           Textout(9, dxdraw.surfaceheight-41, 'Leben: ?');
  2163.           Font.Color := clFuchsia;
  2164.           Textout(10, dxdraw.surfaceheight-40, 'Leben: ?');
  2165.         end
  2166.         else
  2167.         begin
  2168.           if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
  2169.           begin
  2170.             Font.Color := clPurple;
  2171.             Textout(9, dxdraw.surfaceheight-41, 'Leben: ' + IntToStr(MainForm.flife));
  2172.             Font.Color := clFuchsia;
  2173.             Textout(10, dxdraw.surfaceheight-40, 'Leben: ' + IntToStr(MainForm.flife));
  2174.           end;
  2175.           if Flife = 1 then BlinkUpdate;
  2176.         end;
  2177.         {if BossExists and (FBossLife>0) then
  2178.         begin
  2179.           Font.Color := clPurple;
  2180.           Textout(449, 439, 'Boss: ' + IntToStr(FBossLife));
  2181.           Font.Color := clFuchsia;
  2182.           Textout(450, 440, 'Boss: ' + IntToStr(FBossLife));
  2183.         end
  2184.         else
  2185.           if RestlicheEinheiten>0 then
  2186.           begin
  2187.             Font.Color := clPurple;
  2188.             Textout(449, 439, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
  2189.             Font.Color := clFuchsia;
  2190.             Textout(450, 440, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
  2191.           end;}
  2192.         if BossExists and (FBossLife>0) then
  2193.         begin
  2194.           if (FRestEnemies>0) then
  2195.           begin
  2196.             Font.Color := clGreen;
  2197.             Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, 'Boss: ' + IntToStr(FBossLife));
  2198.             Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
  2199.             Font.Color := clLime;
  2200.             Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, 'Boss: ' + IntToStr(FBossLife));
  2201.             Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
  2202.           end;
  2203.           if (FRestEnemies<1) then
  2204.           begin
  2205.             Font.Color := clGreen;
  2206.             Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Boss: ' + IntToStr(FBossLife));
  2207.             Font.Color := clLime;
  2208.             Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Boss: ' + IntToStr(FBossLife));
  2209.           end;
  2210.         end;
  2211.         if (FRestEnemies>0) and not Bossexists then
  2212.         begin
  2213.           Font.Color := clGreen;
  2214.           Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
  2215.           Font.Color := clLime;
  2216.           Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
  2217.         end;
  2218.         Release;
  2219.       end;
  2220.     end
  2221.     else
  2222.     begin
  2223.       DXDraw.Surface.Canvas.Font.Color := clGreen; // Grüne schrift bei gescheitert? FIXME
  2224.       DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission gescheitert!');
  2225.       DXDraw.Surface.Canvas.Font.Color := clLime;
  2226.       DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission gescheitert!');
  2227.       DXDraw.Surface.Canvas.Release;
  2228.     end;
  2229.     if (EnemyCounter=0) and (FRestEnemies=0){ and (SpielerFliegtFort = false)}
  2230.     and ((BossExists and (FBossLife=0)) or not BossExists) then
  2231.     begin
  2232.       DXDraw.Surface.Canvas.Font.Color := clGreen;
  2233.       DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission erfolgreich!');
  2234.       DXDraw.Surface.Canvas.Font.Color := clLime;
  2235.       DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission erfolgreich!');
  2236.       DXDraw.Surface.Canvas.Release;
  2237.       Sleep(1);
  2238.       inc(FCounter);
  2239.       if FCounter>150{200} then PlayerSprite.FlyAway;
  2240.     end;
  2241.   end;
  2242. end;
  2243.  
  2244. procedure TMainForm.SceneGameOver;
  2245. begin
  2246.   DXDraw.Surface.Fill(0);
  2247.   with DXDraw.Surface.Canvas do
  2248.   begin
  2249.     FNotSave := true;
  2250.     Cheat.enabled := false;
  2251.     GamePause.enabled := false;
  2252.     Neustart.enabled := false;
  2253.     Brush.Style := bsClear;
  2254.     Font.Size := 35;
  2255.     Font.Color := clMaroon;
  2256.     Textout((dxdraw.surfacewidth div 2)-127, 98, 'Game Over!');
  2257.     Font.Color := clRed;
  2258.     Textout((dxdraw.surfacewidth div 2)-125, 100, 'Game Over!');
  2259.     if (FBlink div 300) mod 2=0 then
  2260.     begin
  2261.       Font.Size := 30;
  2262.       Font.Color := clOlive;
  2263.       Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
  2264.       Font.Color := clYellow;
  2265.       Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
  2266.     end;
  2267.     BlinkUpdate;
  2268.     Release;
  2269.   end;
  2270.   if isButton1 in DXInput.States then
  2271.   begin
  2272.     PlaySound('SceneMov', False);
  2273.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  2274.     Sleep(200);
  2275.     StartScene(gsTitle);
  2276.   end;
  2277. end;
  2278.  
  2279. procedure TMainForm.SceneWin;
  2280. begin
  2281.   DXDraw.Surface.Fill(0);
  2282.   with DXDraw.Surface.Canvas do
  2283.   begin
  2284.     FNotSave := true;
  2285.     Cheat.enabled := false;
  2286.     GamePause.enabled := false;
  2287.     Neustart.enabled := false;
  2288.     Brush.Style := bsClear;
  2289.     Font.Size := 35;
  2290.     Font.Color := clMaroon;
  2291.     Textout((dxdraw.surfaceWidth div 2)-127, 98, 'Gewonnen!');
  2292.     Font.Color := clRed;
  2293.     Textout((dxdraw.surfaceWidth div 2)-125, 100, 'Gewonnen!');
  2294.     if (FBlink div 300) mod 2=0 then
  2295.     begin
  2296.       Font.Size := 30;
  2297.       Font.Color := clOlive;
  2298.       Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
  2299.       Font.Color := clYellow;
  2300.       Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
  2301.     end;
  2302.     BlinkUpdate;
  2303.     Release;
  2304.   end;
  2305.   if isButton1 in DXInput.States then
  2306.   begin
  2307.     PlaySound('SceneMov', False);
  2308.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  2309.     Sleep(200);
  2310.     StartScene(gsTitle);
  2311.   end;
  2312. end;
  2313.  
  2314. procedure TMainForm.StartSceneNewLevel;
  2315. begin
  2316.   sleep(500);
  2317.   FNotSave := false;
  2318.   Cheat.enabled := false;
  2319.   Neustart.enabled := false;
  2320.   GamePause.enabled := false;
  2321.   GameStart.enabled := true;
  2322.   Spielgeschwindigkeit.enabled := false;
  2323.   BossExists := false;
  2324.   Spielgeschwindigkeit.enabled := false;
  2325.   if ((FMenuItem=1) and (not fileexists(FDirectory+'Levels\Level '+inttostr(FLevel)+'.lev'))) or ((FMenuItem=2) and (FLevel > 25)) then
  2326.   begin
  2327.     //PlaySound('SceneMov', False);
  2328.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  2329.     Sleep(200);
  2330.     StartScene(gsWin);
  2331.     exit;
  2332.   end;
  2333.   PlayMusic(mtScene);
  2334. end;
  2335.  
  2336. procedure TMainForm.EndSceneNewLevel;
  2337. begin
  2338.   {  Ende NewLevel  }
  2339. end;
  2340.  
  2341. procedure TMainForm.SceneNewLevel;
  2342. begin
  2343.   DXDraw.Surface.Fill(0);
  2344.   with DXDraw.Surface.Canvas do
  2345.   begin
  2346.     Brush.Style := bsClear;
  2347.     Font.Size := 40;
  2348.     Font.Color := clMaroon;
  2349.     Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, 'Level '+inttostr(flevel));
  2350.     Font.Color := clRed;
  2351.     Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, 'Level '+inttostr(flevel));
  2352.     if (FBlink div 300) mod 2=0 then
  2353.     begin
  2354.       Font.Size := 30;
  2355.       Font.Color := clOlive;
  2356.       Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
  2357.       Font.Color := clYellow;
  2358.       Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
  2359.     end;
  2360.     BlinkUpdate;
  2361.     Release;
  2362.   end;
  2363.   if isButton1 in DXInput.States then
  2364.   begin
  2365.     PlaySound('SceneMov', False);
  2366.     PalleteAnim(RGBQuad(0, 0, 0), 300);
  2367.     Sleep(200);
  2368.     StartScene(gsMain);
  2369.   end;
  2370. end;
  2371.  
  2372. procedure TMainForm.OptionMusicClick(Sender: TObject);
  2373. begin
  2374.   OptionMusic.Checked := not OptionMusic.Checked;
  2375.   if OptionMusic.Checked then
  2376.   begin
  2377.     PlayMusic(FMusic)
  2378.   end
  2379.   else
  2380.   begin
  2381.     DestroyMusic(FMusic);
  2382.   end;
  2383.   WriteOptions;
  2384. end;
  2385.  
  2386. procedure TMainForm.MasterClick(Sender: TObject);
  2387. begin
  2388.   master.checked := true;
  2389.   FInterval := giMaster;
  2390.   writeoptions;
  2391. end;
  2392.  
  2393. procedure TEnemyMeteor.DoMove(MoveCount: Integer);
  2394. begin
  2395.   X := X - MoveCount*(250/1000);
  2396.   if X < -Width then Dead;
  2397. end;
  2398.  
  2399. procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
  2400. begin
  2401.   inherited HitEnemy(False);
  2402.  
  2403.   if ADead then Collisioned := True;
  2404. end;
  2405.  
  2406. {procedure TMainForm.StopMusic;
  2407. begin
  2408.   PauseMusic(FMusic);
  2409.   MCISendString(pchar('seek "'+FDirectory+'Musik\Boss.mid" to start'), nil, 255, 0);
  2410.   MCISendString(pchar('seek "'+FDirectory+'Musik\Game.mid" to start'), nil, 255, 0);
  2411.   MCISendString(pchar('seek "'+FDirectory+'Musik\Title.mid" to start'), nil, 255, 0);
  2412.   MCISendString(pchar('seek "'+FDirectory+'Musik\Scene.mid" to start'), nil, 255, 0);
  2413. end;}
  2414.  
  2415. procedure TMainForm.ResumeMusic(Name: TMusicTrack);
  2416. begin
  2417.   if not OptionMusic.checked then exit;
  2418.   if Name = mtBoss then
  2419.     MCISendString(pchar('play "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
  2420.   if Name = mtGame then
  2421.     MCISendString(pchar('play "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
  2422.   if Name = mtScene then
  2423.     MCISendString(pchar('play "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
  2424.   if Name = mtTitle then
  2425.     MCISendString(pchar('play "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
  2426. end;
  2427.  
  2428. constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
  2429. begin
  2430.   inherited Create(AParent, ALifes);
  2431.   Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
  2432.   Width := Image.Width;
  2433.   Height := Image.Height;
  2434.   AnimCount := Image.PatternCount;
  2435.   AnimLooped := True;
  2436.   AnimSpeed := DEFAULT_ANIMSPEED;
  2437.   PixelCheck := True;
  2438. end;
  2439.  
  2440. procedure TMainForm.SpielstandClick(Sender: TObject);
  2441. begin
  2442.   speicherungform.showmodal;
  2443. end;
  2444.  
  2445. procedure TMainForm.NeustartClick(Sender: TObject);
  2446. begin
  2447.   FLife := Lives;
  2448.   FLevel := 1; // ???
  2449.   FScore := 0;
  2450.   EnemyCounter := 0;
  2451.   StartScene(gsMain);
  2452.   PlayMusic(mtGame);
  2453. end;
  2454.  
  2455. procedure TMainForm.OptionBreitbildClick(Sender: TObject);
  2456. begin
  2457.   OptionBreitbild.Checked := not OptionBreitbild.Checked;
  2458.   DXInit;
  2459.   writeoptions;
  2460. end;
  2461.  
  2462. procedure TMainForm.LeichtClick(Sender: TObject);
  2463. begin
  2464.   leicht.checked := true;
  2465.   FInterval := giLeicht;
  2466.   writeoptions;
  2467. end;
  2468.  
  2469. procedure TMainForm.MittelClick(Sender: TObject);
  2470. begin
  2471.   mittel.checked := true;
  2472.   FInterval := giMittel;
  2473.   writeoptions;
  2474. end;
  2475.  
  2476. procedure TMainForm.SchwerClick(Sender: TObject);
  2477. begin
  2478.   schwer.checked := true;
  2479.   FInterval := giSchwer;
  2480.   writeoptions;
  2481. end;
  2482.  
  2483. procedure TMainForm.FormShow(Sender: TObject);
  2484. begin
  2485.   if Assigned(SplashForm) then
  2486.   begin
  2487.     SplashForm.Hide;
  2488.     FreeAndNil(SplashForm);
  2489.   end;
  2490.  
  2491.   dxtimer.Enabled := true;
  2492.   dxtimer.ActiveOnly := true;
  2493. end;
  2494.  
  2495. procedure TMainForm.InformationenClick(Sender: TObject);
  2496. begin
  2497.   dxtimer.enabled := false;
  2498.   InfoForm.showmodal;
  2499.   if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
  2500. end;
  2501.  
  2502. procedure TMainForm.CheatClick(Sender: TObject);
  2503. begin
  2504.   CheatForm.showmodal;
  2505. end;
  2506.  
  2507. procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
  2508. begin
  2509.   if optionMusic.checked then DestroyMusic(FMusic);
  2510.   SpriteEngine.Engine.Clear;
  2511.   dxsound.Finalize;
  2512.   dxinput.Destroy;
  2513.   DXTimer.Enabled := False;
  2514. end;
  2515.  
  2516. procedure TMainForm.FormDestroy(Sender: TObject);
  2517. begin
  2518.   imagelist.Free;
  2519.   spriteengine.Free;
  2520.   dxdraw.Free;
  2521.   wavelist.Free;
  2522.   dxsound.Free;
  2523.   //dxinput.Free;
  2524.   dxtimer.Free;
  2525.   DeleteCriticalSection(TimerCS);
  2526. end;
  2527.  
  2528. end.
  2529.  
  2530.