Subversion Repositories spacemission

Rev

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

  1. unit LevMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem,
  7.   Dialogs, StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws,
  8.   DXSounds, Spin, ComCtrls{$IF CompilerVersion >= 23.0}, System.UITypes,
  9.   WinAPI.DirectDraw{$ENDIF}, DirectX, ComLevelReader;
  10.  
  11. type
  12.   TMainForm = class(TDXForm)
  13.     MainMenu: TMainMenu;
  14.     Spiel: TMenuItem;
  15.     Beenden: TMenuItem;
  16.     Hilfe: TMenuItem;
  17.     Leer1: TMenuItem;
  18.     Level: TMenuItem;
  19.     Informationen: TMenuItem;
  20.     Enemy1: TRadioButton;
  21.     Enemy2: TRadioButton;
  22.     Enemy3: TRadioButton;
  23.     Enemy4: TRadioButton;
  24.     Enemy5: TRadioButton;
  25.     Enemy6: TRadioButton;
  26.     Enemy7: TRadioButton;
  27.     ScrollBar: TScrollBar;
  28.     Bevel1: TBevel;
  29.     Bevel2: TBevel;
  30.     SelLabel: TLabel;
  31.     SelPanel: TPanel;
  32.     Bevel3: TBevel;
  33.     SLabel1a: TLabel;
  34.     SLabel2a: TLabel;
  35.     SLabel1b: TLabel;
  36.     SLabel2b: TLabel;
  37.     SLabel0: TLabel;
  38.     Neu: TMenuItem;
  39.     Image1: TImage;
  40.     SLabel3a: TLabel;
  41.     SLabel3b: TLabel;
  42.     SLabel4a: TLabel;
  43.     SLabel4b: TLabel;
  44.     LivesLabel: TLabel;
  45.     StatusBar: TStatusBar;
  46.     N1: TMenuItem;
  47.     Spielfelderweitern1: TMenuItem;
  48.     SidePanel: TPanel;
  49.     LivesEdit: TSpinEdit;
  50.     procedure DXDrawFinalize(Sender: TObject);
  51.     procedure DXDrawInitialize(Sender: TObject);
  52.     procedure FormCreate(Sender: TObject);
  53.     procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
  54.     procedure BeendenClick(Sender: TObject);
  55.     procedure FormDestroy(Sender: TObject);
  56.     procedure LevelClick(Sender: TObject);
  57.     procedure FormShow(Sender: TObject);
  58.     procedure InformationenClick(Sender: TObject);
  59.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  60.     procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
  61.       Shift: TShiftState; X, Y: Integer);
  62.     procedure EnemyClick(Sender: TObject);
  63.     procedure NeuClick(Sender: TObject);
  64.     procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
  65.       Y: Integer);
  66.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  67.     procedure Spielfelderweitern1Click(Sender: TObject);
  68.     procedure ScrollBarScroll(Sender: TObject; ScrollCode: TScrollCode;
  69.       var ScrollPos: Integer);
  70.   public
  71.     { VCL-Ersatz }
  72.     spriteengine: tdxspriteengine;
  73.     dxtimer: tdxtimer;
  74.     imagelist: tdximagelist;
  75.     dxdraw: tdxdraw;
  76.     { Variablen }
  77.     FMenuItem: integer;
  78.     LevData: TLevelData;
  79.     ScrollP: integer;
  80.     AltScrollPos: integer;
  81.     Boss: boolean;
  82.     LevChanged: boolean;
  83.     NumEnemys: integer;
  84.     function SelectedEnemyType: TEnemyType;
  85.     { Level-Routinen }
  86.     procedure EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
  87.     procedure DestroyLevel;
  88.     procedure AnzeigeAct;
  89.     { Initialisiations-Routinen }
  90.     procedure DXInit;
  91.     procedure ProgramInit;
  92.     { Farb-Routinen }
  93.     function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  94.     procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
  95.   end;
  96.  
  97. var
  98.   MainForm: TMainForm;
  99.  
  100. implementation
  101.  
  102. uses
  103.   Global, LevSplash, LevSpeicherung, ComInfo, LevOptions;
  104.  
  105. const
  106.   RasterW = 48;
  107.   RasterH = 32;
  108.  
  109. {$R *.DFM}
  110.  
  111. type
  112.   TBackground = class(TBackgroundSprite)
  113.   strict protected
  114.     procedure DoMove(MoveCount: Integer); override;
  115.   end;
  116.  
  117.   TEnemy = class(TImageSprite)
  118.   strict private
  119.     FLives: integer;
  120.     FEnemyType: TEnemyType;
  121.     FXCor: integer;
  122.     FCorInit: boolean;
  123.   strict protected
  124.     procedure DoMove(MoveCount: Integer); override;
  125.   public
  126.     constructor Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer); reintroduce;
  127.   end;
  128.  
  129. { TBackground }
  130.  
  131. procedure TBackground.DoMove(MoveCount: Integer);
  132. begin
  133.   X := -(MainForm.ScrollP * RasterW);
  134. end;
  135.  
  136. { TEnemy }
  137.  
  138. procedure TEnemy.DoMove(MoveCount: Integer);
  139. begin
  140.   if not FCorInit then
  141.   begin
  142.     FXCor := trunc(x) + (MainForm.ScrollP * RasterW);
  143.     FCorInit := true;
  144.   end;
  145.   if MainForm.LevData.IndexOfEnemy(FXCor, integer(round(Y)), FEnemyType, FLives) = -1 then dead;
  146.   X := FXCor - (MainForm.ScrollP * RasterW);
  147. end;
  148.  
  149. constructor TEnemy.Create(AParent: TSprite; AEnemyType: TEnemyType; ALives: Integer);
  150. begin
  151.   inherited Create(AParent);
  152.   if AEnemyType = etEnemyAttacker then Image := MainForm.ImageList.Items.Find('Enemy-Attacker');
  153.   if AEnemyType = etEnemyAttacker2 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker2');
  154.   if AEnemyType = etEnemyAttacker3 then Image := MainForm.ImageList.Items.Find('Enemy-Attacker3');
  155.   if AEnemyType = etEnemyMeteor then Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
  156.   if AEnemyType = etEnemyUFO then Image := MainForm.ImageList.Items.Find('Enemy-Disk');
  157.   if AEnemyType = etEnemyUFO2 then Image := MainForm.ImageList.Items.Find('Enemy-Disk2');
  158.   if AEnemyType = etEnemyBoss then Image := MainForm.ImageList.Items.Find('Enemy-Boss');
  159.  
  160.   if AEnemyType = etEnemyMeteor then FLives := 0 else FLives := ALives;
  161.   FEnemyType := AEnemyType;
  162.   Width := Image.Width;
  163.   Height := Image.Height;
  164.   PixelCheck := True;
  165. end;
  166.  
  167. { TMainForm }
  168.  
  169. procedure TMainForm.DXInit;
  170. begin
  171.   Imagelist.Items.LoadFromFile(FDirectory+'DirectX\Graphic.dxg');
  172.   ImageList.Items.MakeColorTable;
  173.   DXDraw.ColorTable := ImageList.Items.ColorTable;
  174.   DXDraw.DefColorTable := ImageList.Items.ColorTable;
  175.   DXDraw.UpdatePalette;
  176.   DXDraw.Initialize;
  177. end;
  178.  
  179. procedure TMainForm.FormCreate(Sender: TObject);
  180. resourcestring
  181.   SFileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
  182. var
  183.   LevelData: TLevelData;
  184. begin
  185.   { VCL-Ersatz start }
  186.   dxtimer := tdxtimer.create(self);
  187.   dxtimer.Interval := 100;
  188.   dxtimer.ActiveOnly := false;
  189.   dxtimer.Enabled := false;
  190.   dxtimer.OnTimer := DxTimerTimer;
  191.  
  192.   dxdraw := tdxdraw.Create(self);
  193.   dxdraw.Parent := self;
  194.   dxdraw.Left := 0;
  195.   dxdraw.Top := 0;
  196.   dxdraw.Width := SidePanel.Left;
  197.   dxdraw.Height := ScrollBar.Top;
  198.   dxdraw.AutoInitialize := False;
  199.   dxdraw.AutoSize := False;
  200.   dxdraw.Color := clBlack;
  201.   (*
  202.   dxdraw.Display.BitCount := 24;
  203.   dxdraw.Display.FixedBitCount := False;
  204.   dxdraw.Display.FixedRatio := False;
  205.   dxdraw.Display.FixedSize := False;
  206.   dxdraw.Display.Height := 600;
  207.   dxdraw.Display.Width := 800;
  208.   *)
  209.   dxdraw.Options := [doAllowReboot, doWaitVBlank, doAllowPalette256, doCenter, {doRetainedMode,} doHardware, doSelectDriver];
  210.   dxdraw.OnFinalize := DXDrawFinalize;
  211.   dxdraw.OnInitialize := DXDrawInitialize;
  212.   dxdraw.ParentShowHint := False;
  213.   dxdraw.ShowHint := False;
  214.   dxdraw.TabOrder := 0;
  215.   dxdraw.OnMouseDown := DXDrawMouseDown;
  216.   dxdraw.OnMouseMove := DXDrawMouseMove;
  217.  
  218.   spriteengine := tdxspriteengine.create(self);
  219.   spriteengine.DXDraw := dxdraw;
  220.  
  221.   imagelist := tdximagelist.create(self);
  222.   imagelist.DXDraw := dxdraw;
  223.  
  224.   { VCL-Ersatz ende }
  225.  
  226.   Enemy1.Checked := true;
  227.   EnemyClick(Enemy1);
  228.   // Leeres Level am Anfang braucht keine Beenden-Bestätigung.
  229.   // LevChanged := true;
  230.  
  231.   //Application.Title := 'SpaceMission '+ProgramVersion+' - Leveleditor';
  232.   Caption := 'SpaceMission '+ProgramVersion+' - Leveleditor';
  233.   DXInit;
  234.   if (paramcount > 0) and (fileexists(paramstr(1))) then
  235.   begin
  236.     LevelData := TLevelData.Create;
  237.     try
  238.       try
  239.         LevelData.Load(paramstr(1));
  240.       except
  241.         showmessage(SFileError);
  242.         ProgramInit;
  243.         exit;
  244.       end;
  245.     finally
  246.       FreeAndNil(LevelData);
  247.     end;
  248.     { Laden }
  249.     exit;
  250.   end;
  251.   ProgramInit;
  252. end;
  253.  
  254. procedure TMainForm.FormDestroy(Sender: TObject);
  255. begin
  256.   LevData.Free;
  257.   //spriteengine.Free;
  258.   dxtimer.Free;
  259.   imagelist.Free;
  260.   dxdraw.free;
  261. end;
  262.  
  263. procedure TMainForm.BeendenClick(Sender: TObject);
  264. begin
  265.   close;
  266. end;
  267.  
  268. procedure TMainForm.DXDrawInitialize(Sender: TObject);
  269. begin
  270.   DXTimer.Enabled := True;
  271. end;
  272.  
  273. procedure TMainForm.DXDrawFinalize(Sender: TObject);
  274. begin
  275.   DXTimer.Enabled := False;
  276. end;
  277.  
  278. procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
  279. begin
  280.   if not DXDraw.CanDraw then exit;
  281.   LagCount := 1000 div 60;
  282.   SpriteEngine.Move(LagCount);
  283.   SpriteEngine.Dead;
  284.   DxDraw.Surface.Fill(0);
  285.   SpriteEngine.Draw;
  286.   DXDraw.Flip;
  287. end;
  288.  
  289. function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
  290. begin
  291.   with Result do
  292.   begin
  293.     rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
  294.     rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
  295.     rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
  296.     rgbReserved := 0;
  297.   end;
  298. end;
  299.  
  300. procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
  301. var
  302.   i: Integer;
  303.   t, t2: DWORD;
  304.   ChangePalette: Boolean;
  305.   c: Integer;
  306. begin
  307.   if DXDraw.Initialized then
  308.   begin
  309.     c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
  310.     ChangePalette := False;
  311.     if DXDraw.CanPaletteAnimation then
  312.     begin
  313.       t := GetTickCount;
  314.       while Abs(GetTickCount-t)<Time do
  315.       begin
  316.         t2 := Trunc(Abs(GetTickCount-t)/Time*255);
  317.         for i := 0 to 255 do
  318.           DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
  319.         DXDraw.UpdatePalette;
  320.         ChangePalette := True;
  321.       end;
  322.     end else
  323.       Sleep(Time);
  324.     for i := 0 to 4 do
  325.     begin
  326.       DXDraw.Surface.Fill(c);
  327.       DXDraw.Flip;
  328.     end;
  329.     if ChangePalette then
  330.     begin
  331.       DXDraw.ColorTable := DXDraw.DefColorTable;
  332.       DXDraw.UpdatePalette;
  333.     end;
  334.     DXDraw.Surface.Fill(c);
  335.     DXDraw.Flip;
  336.   end;
  337. end;
  338.  
  339. procedure TMainForm.ProgramInit;
  340. {var
  341.   i, j: Integer;}
  342. begin
  343.   LevData := TLevelData.create;
  344.   sleep(500);
  345.   //PlayerSprite
  346.   with TBackground.Create(SpriteEngine.Engine) do
  347.   begin
  348.     SetMapSize(1, 1);
  349.     Image := mainform.ImageList.Items.Find('Star3');
  350.     Z := -13;
  351.     Y := 40;
  352.     Tile := True;
  353.   end;
  354.   with TBackground.Create(SpriteEngine.Engine) do
  355.   begin
  356.     SetMapSize(1, 1);
  357.     Image := mainform.ImageList.Items.Find('Star2');
  358.     Z := -12;
  359.     Y := 30;
  360.     Tile := True;
  361.   end;
  362.   with TBackground.Create(SpriteEngine.Engine) do
  363.   begin
  364.     SetMapSize(1, 1);
  365.     Image := mainform.ImageList.Items.Find('Star1');
  366.     Z := -11;
  367.     Y := 10;
  368.     Tile := True;
  369.   end;
  370.   with TBackground.Create(SpriteEngine.Engine) do
  371.   begin
  372.     SetMapSize(1, 1);
  373.     Image := mainform.ImageList.Items.Find('Matrix');
  374.     Z := -10;
  375.     Tile := True;
  376.   end;
  377.   {with TBackground.Create(SpriteEngine.Engine) do
  378.   begin
  379.     SetMapSize(200, 10);
  380.     Y := 10;
  381.     Z := -13;
  382.     FSpeed := 1 / 2;
  383.     Tile := True;
  384.     for i := 0 to MapHeight-1 do
  385.     begin
  386.       for j := 0 to MapWidth-1 do
  387.       begin
  388.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
  389.         if Random(100)<95 then Chips[j, i] := -1;
  390.       end;
  391.     end;
  392.   end;
  393.   with TBackground.Create(SpriteEngine.Engine) do
  394.   begin
  395.     SetMapSize(200, 10);
  396.     Y := 30;
  397.     Z := -12;
  398.     FSpeed := 1;
  399.     Tile := True;
  400.     for i := 0 to MapHeight-1 do
  401.     begin
  402.       for j := 0 to MapWidth-1 do
  403.       begin
  404.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
  405.         if Random(100)<95 then Chips[j, i] := -1;
  406.       end;
  407.     end;
  408.   end;
  409.   with TBackground.Create(SpriteEngine.Engine) do
  410.   begin
  411.     SetMapSize(200, 10);
  412.     Y := 40;
  413.     Z := -11;
  414.     FSpeed := 2;
  415.     Tile := True;
  416.     for i := 0 to MapHeight-1 do
  417.     begin
  418.       for j := 0 to MapWidth-1 do
  419.       begin
  420.         Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
  421.         if Random(100)<95 then Chips[j, i] := -1;
  422.       end;
  423.     end;
  424.   end;}
  425.   PalleteAnim(RGBQuad(0, 0, 0), 300);
  426.   mainform.Visible := true;
  427. end;
  428.  
  429. procedure TMainForm.LevelClick(Sender: TObject);
  430. begin
  431.   speicherungform.showmodal;
  432. end;
  433.  
  434. procedure TMainForm.FormShow(Sender: TObject);
  435. begin
  436.   SplashForm.Hide;
  437.   SplashForm.Free;
  438.  
  439.   dxtimer.Enabled := true;
  440.   dxtimer.ActiveOnly := true;
  441. end;
  442.  
  443. procedure TMainForm.InformationenClick(Sender: TObject);
  444. begin
  445.   mainform.dxtimer.enabled := false;
  446.   InfoForm.showmodal;
  447.   mainform.dxtimer.enabled := true;
  448. end;
  449.  
  450. procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
  451. begin
  452.   SpriteEngine.Engine.Clear;
  453.   DXTimer.Enabled := False;
  454. end;
  455.  
  456. procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
  457.   Shift: TShiftState; X, Y: Integer);
  458. var
  459.   i, j, k, l, ex, ey: integer;
  460.   ok, breaked: boolean;
  461. begin
  462.   ex := trunc(x/RasterW) * RasterW;
  463.   ey := trunc(y/RasterH) * RasterH;
  464.   EnemyCreateSprite(ex, ey, SelectedEnemyType, LivesEdit.Value);
  465.   breaked := false;
  466.   { Setzen }
  467.   if Button = mbLeft then
  468.   begin
  469.     ok := true;
  470.     if (SelectedEnemyType = etEnemyBoss) and boss then
  471.       ok := false // boss already exists
  472.     else
  473.     begin
  474.       for i := 1 to NumEnemyTypes do
  475.       begin
  476.         for j := 0 to 999 do
  477.         begin
  478.           if boss then
  479.           begin
  480.             for k := 0 to 3 do
  481.             begin
  482.               for l := 0 to 1 do
  483.               begin
  484.                 if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), etEnemyBoss, j) <> -1 then
  485.                 begin
  486.                   ok := false;
  487.                   break;
  488.                 end;
  489.               end;
  490.               if not ok then break;
  491.             end;
  492.             if not ok then break;
  493.           end;
  494.           if LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1 then
  495.           begin
  496.             ok := false;
  497.             break;
  498.           end;
  499.         end;
  500.         if not ok then break;
  501.       end;
  502.     end;
  503.     if ok then
  504.     begin
  505.       if SelectedEnemyType <> etEnemyMeteor then
  506.         LevData.AddEnemy(ex + (ScrollP * RasterW), ey, SelectedEnemyType, LivesEdit.Value)
  507.       else
  508.         LevData.AddEnemy(ex + (ScrollP * RasterW), ey, SelectedEnemyType, 0);
  509.       inc(NumEnemys);
  510.       if SelectedEnemyType = etEnemyBoss then boss := true;
  511.     end
  512.     else beep;
  513.   end
  514.   { Löschen }
  515.   else if Button = mbRight then
  516.   begin
  517.     for i := 1 to NumEnemyTypes do
  518.     begin
  519.       for j := 0 to 999 do
  520.       begin
  521.         if boss and (TEnemyType(i) = etEnemyBoss) then
  522.         begin
  523.           for k := 0 to 3 do
  524.           begin
  525.             for l := 0 to 1 do
  526.             begin
  527.               if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j) <> -1 then
  528.               begin
  529.                 LevData.DeleteEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j);
  530.                 Boss := false;
  531.                 dec(NumEnemys);
  532.                 breaked := true;
  533.                 break;
  534.               end;
  535.             end;
  536.             if breaked then break;
  537.           end;
  538.         end;
  539.         if LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1 then
  540.         begin
  541.           LevData.DeleteEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j);
  542.           if TEnemyType(i) = etEnemyBoss then Boss := false;
  543.           dec(NumEnemys);
  544.           breaked := true;
  545.           break;
  546.         end;
  547.       end;
  548.       if breaked then break;
  549.     end;
  550.   end;
  551.   LevChanged := true;
  552.   AnzeigeAct;
  553. end;
  554.  
  555. procedure TMainForm.EnemyClick(Sender: TObject);
  556. var
  557.   et: TEnemyType;
  558. begin
  559.   et := SelectedEnemyType;
  560.   Image1.Left := -(87 * (Ord(et) - 1)) + 1;
  561.   LivesEdit.Enabled := et <> etEnemyMeteor;
  562.   LivesLabel.Enabled := et <> etEnemyMeteor;
  563. end;
  564.  
  565. procedure TMainForm.EnemyCreateSprite(x, y: integer; AEnemyType: TEnemyType; ALives: integer);
  566. var
  567.   Enemy: TSprite;
  568. begin
  569.   Enemy := TEnemy.Create(SpriteEngine.Engine, AEnemyType, ALives);
  570.   Enemy.x := x;
  571.   Enemy.y := y;
  572. end;
  573.  
  574. procedure TMainForm.DestroyLevel;
  575. begin
  576.   ScrollBar.Position := 0; // this doesn't call ScrollBarScroll()
  577.   ScrollP := 0;
  578.   LevData.Clear;
  579.   ScrollBar.Max := MainForm.LevData.LevelEditorLength;
  580.   NumEnemys := 0;
  581.   Boss := false;
  582.   LevChanged := true;
  583.   LivesEdit.Value := 1;
  584.   Enemy1.Checked := true;
  585.   EnemyClick(Enemy1);
  586.   AnzeigeAct;
  587. end;
  588.  
  589. procedure TMainForm.AnzeigeAct;
  590. begin
  591.   SLabel1b.Caption := inttostr(NumEnemys);
  592.   if Boss then SLabel2b.Caption := 'Ja' else SLabel2b.Caption := 'Nein';
  593.   SLabel3b.Caption := inttostr(ScrollBar.Max);
  594.   if LevChanged then
  595.   begin
  596.     SLabel4a.Font.Color := $00000096;
  597.     SLabel4b.Font.Color := $00000096;
  598.     SLabel4b.Caption := 'Nein';
  599.   end
  600.   else
  601.   begin
  602.     SLabel4a.Font.Color := $00009600;
  603.     SLabel4b.Font.Color := $00009600;
  604.     SLabel4b.Caption := 'Ja';
  605.   end;
  606. end;
  607.  
  608. procedure TMainForm.NeuClick(Sender: TObject);
  609. begin
  610.   if MessageDlg('Level wirklich löschen?', mtConfirmation, mbYesNoCancel, 0) = mrYes then
  611.     DestroyLevel;
  612. end;
  613.  
  614. procedure TMainForm.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
  615.   Y: Integer);
  616. resourcestring
  617.   status_info = 'Zeigen Sie mit dem Mauszeiger auf eine Einheit, um deren Eigenschaften anzuzeigen...';
  618.   status_lives = 'Leben: ';
  619.   status_nolives = 'Einheit hat keine Lebensangabe';
  620. var
  621.   ex, ey, i, j, k, l: integer;
  622.   lifes: integer;
  623.   enemyType: TEnemyType;
  624.   enemyName: string;
  625.   breaked: boolean;
  626. begin
  627.   if sender <> DxDraw then
  628.   begin
  629.     StatusBar.SimpleText := ' ' + status_info;
  630.     exit;
  631.   end;
  632.   ex := trunc(x/RasterW) * RasterW;
  633.   ey := trunc(y/RasterH) * RasterH;
  634.   lifes := -1;
  635.   enemyType := etUnknown;
  636.   breaked := false;
  637.   for i := 1 to NumEnemyTypes do
  638.   begin
  639.     for j := 0 to 999 do
  640.     begin
  641.       if boss and (TEnemyType(i) = etEnemyBoss) then
  642.       begin
  643.         for k := 0 to 3 do
  644.         begin
  645.           for l := 0 to 1 do
  646.           begin
  647.             if LevData.IndexOfEnemy(ex + ((ScrollP - k) * RasterW), ey - (RasterH * l), TEnemyType(i), j) <> -1 then
  648.             begin
  649.               lifes := j;
  650.               breaked := true;
  651.               break;
  652.             end;
  653.           end;
  654.           if breaked then break;
  655.         end;
  656.       end;
  657.       if (breaked = false) and (LevData.IndexOfEnemy(ex + (ScrollP * RasterW), ey, TEnemyType(i), j) <> -1) then
  658.       begin
  659.         lifes := j;
  660.         enemyType := TEnemyType(i);
  661.         breaked := true;
  662.         break;
  663.       end;
  664.     end;
  665.     if breaked then break;
  666.   end;
  667.   if lifes <> -1 then
  668.   begin
  669.     if Ord(enemyType) = 1 then enemyName := Enemy1.Caption
  670.     else if Ord(enemyType) = 2 then enemyName := Enemy2.Caption
  671.     else if Ord(enemyType) = 3 then enemyName := Enemy3.Caption
  672.     else if Ord(enemyType) = 4 then enemyName := Enemy4.Caption
  673.     else if Ord(enemyType) = 5 then enemyName := Enemy5.Caption
  674.     else if Ord(enemyType) = 6 then enemyName := Enemy6.Caption
  675.     else if Ord(enemyType) = 7 then enemyName := Enemy7.Caption
  676.     else enemyName := '???';
  677.     if lifes > 0 then
  678.       StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_lives + inttostr(lifes)
  679.     else
  680.       StatusBar.SimpleText := ' ' + enemyName + ' - ' + status_nolives;
  681.   end
  682.   else
  683.     StatusBar.SimpleText := ' ' + status_info;
  684. end;
  685.  
  686. procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  687. begin
  688.   if LevChanged then
  689.     CanClose := MessageDlg('Beenden ohne abspeichern?', mtConfirmation, mbYesNoCancel, 0) = mrYes;
  690. end;
  691.  
  692. procedure TMainForm.Spielfelderweitern1Click(Sender: TObject);
  693. begin
  694.   LevelForm.Aktualisieren;
  695.   LevelForm.showmodal;
  696. end;
  697.  
  698. procedure TMainForm.ScrollBarScroll(Sender: TObject;
  699.   ScrollCode: TScrollCode; var ScrollPos: Integer);
  700. begin
  701.   ScrollP := ScrollPos;
  702. end;
  703.  
  704. function TMainForm.SelectedEnemyType: TEnemyType;
  705. begin
  706.   if Enemy1.Checked then result := etEnemyAttacker
  707.   else if Enemy2.Checked then result := etEnemyAttacker2
  708.   else if Enemy3.Checked then result := etEnemyAttacker3
  709.   else if Enemy4.Checked then result := etEnemyMeteor
  710.   else if Enemy5.Checked then result := etEnemyUFO
  711.   else if Enemy6.Checked then result := etEnemyUFO2
  712.   else if Enemy7.Checked then result := etEnemyBoss
  713.   else result := etUnknown;
  714. end;
  715.  
  716. end.
  717.  
  718.