Subversion Repositories spacemission

Rev

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