Subversion Repositories spacemission

Rev

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