Subversion Repositories spacemission

Rev

Rev 42 | Rev 54 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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