Subversion Repositories spacemission

Rev

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