Subversion Repositories spacemission

Rev

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