Subversion Repositories spacemission

Rev

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

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