Subversion Repositories spacemission

Rev

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