Subversion Repositories spacemission

Rev

Rev 7 | Rev 14 | 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
 
11 daniel-mar 3
// TODO: 2024 Quellcode optimieren und klassen-namen überdenken
4
// TODO: 2024 Form Screen center anstelle Desktop Center => OK!
5
// TODO: 2024 Vollbild entf.
6
// TODO: 2024 DPlayX.dll auskommentieren => OK!
7
// TODO: 2024 Software-Update routine prüfen
8
// TODO: 2024 EV CodeSign
9
// TODO: 2024 Spielstände usw. "Spiele" Ordner speichern, Config in Registry sichern, etc.
10
// TODO: 2024 Neue Einheiten => Medikit, Ufo das im Kreis fliegt und nicht weggeht
11
// TODO: 2024 Bei Pause => Entweder alles grau werden lassen, oder irgendwo "Pause" hinschreiben (nur Not in die Form Caption)
12
// TODO: 2024 Alle Notizen durchschauen
13
// TODO: 2024 Boss schwieriger machen: Er soll auch nach links und rechts gehen?
14
// TODO: 2024 Cooldown für Laser?
15
// TODO: 2024 Musik und Sounds optimieren
16
// TODO: 2024 Pausiertes Spiel: Fenster bewegen lässt das Spiel wieder starten
17
// TODO: 2024 Zwei Fenster in Taskleiste
18
// TODO: 2024 "Doku" in Hilfemenü einbinden, ggf. auch den Leveleditor ins Menü machen
19
// TODO: 2024 Highscore Liste
20
 
3 daniel-mar 21
interface
22
 
23
uses
24
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, MMSystem, Dialogs,
6 daniel-mar 25
  StdCtrls, ExtCtrls, Menus, DIB, DXClass, DXSprite, DXDraws, DXInput, DXSounds,
11 daniel-mar 26
  INIFiles, ShellAPI, wininet, DirectX;
3 daniel-mar 27
 
28
type
29
  TGameScene = (
30
    gsNone,
31
    gsTitle,
32
    gsMain,
33
    gsGameOver,
34
    gsNewLevel,
35
    gsWin
36
  );
37
 
38
  TGameInterval = (
39
    giMittel,
40
    giLeicht,
41
    giSchwer,
42
    giMaster
43
  );
44
 
45
  TMusicTrack = (
46
    mtNone,
47
    mtGame,
48
    mtBoss,
49
    mtScene,
50
    mtTitle
51
  );
52
 
53
  {TSoundFile = (
54
    sfNone,
55
    sfSceneMov,
56
    sfExplosion,
57
    sfHit,
58
    sfShoot,
59
    sfDanger,
60
    sfEnde,
61
    sfFrage,
62
    sfLevIntro
63
  );}
64
 
65
  TBackground = class(TBackgroundSprite)
66
  private
67
    FSpeed: Double;
68
  protected
69
    procedure DoMove(MoveCount: Integer); override;
70
  end;
71
 
72
  TBackgroundSpecial = class(TBackgroundSprite)
73
  private
74
    FSpeed: Double;
75
  protected
76
    procedure DoMove(MoveCount: Integer); override;
77
  end;
78
 
79
  TExplosion = class(TImageSprite)
80
  private
81
    FCounter: Integer;
82
  protected
83
    procedure DoMove(MoveCount: Integer); override;
84
  public
85
    constructor Create(AParent: TSprite); override;
86
  end;
87
 
88
  TPlayerSprite = class(TImageSprite)
89
  private
90
    FCounter: Integer;
91
    FMode: Integer;
92
    FTamaCount: Integer;
93
    FOldTamaTime: Integer;
94
  protected
95
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
96
    procedure DoMove(MoveCount: Integer); override;
97
  public
98
    constructor Create(AParent: TSprite); override;
99
    procedure FlyAway;
100
  end;
101
 
102
  TTamaSprite = class(TImageSprite)
103
  private
104
    FPlayerSprite: TPlayerSprite;
105
  protected
106
    procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
107
    procedure DoMove(MoveCount: Integer); override;
108
  public
109
    constructor Create(AParent: TSprite); override;
110
    destructor Destroy; override;
111
  end;
112
 
7 daniel-mar 113
  TEnemyClass = class of TEnemy;
3 daniel-mar 114
  TEnemy = class(TImageSprite)
115
  private
116
    FCounter: Integer;
117
    FLife: integer;
118
    FMode: Integer;
119
  protected
120
    procedure HitEnemy(ADead: Boolean); virtual;
121
  public
7 daniel-mar 122
    procedure Hit(AHitStrength: integer = 1);
11 daniel-mar 123
    constructor Create(AParent: TSprite; ALifes: integer); reintroduce; virtual;
3 daniel-mar 124
    destructor Destroy; override;
125
  end;
126
 
127
  TEnemyTama = class(TImageSprite)
128
  private
129
    FPlayerSprite: TSprite;
130
  protected
131
    procedure DoMove(MoveCount: Integer); override;
132
  public
133
    constructor Create(AParent: TSprite); override;
134
  end;
135
 
136
  TEnemyMeteor = class(TEnemy)
137
  protected
138
    procedure DoMove(MoveCount: Integer); override;
139
    procedure HitEnemy(ADead: Boolean); override;
140
  public
7 daniel-mar 141
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 142
  end;
143
 
144
  TEnemyUFO = class(TEnemy)
145
  protected
146
    procedure DoMove(MoveCount: Integer); override;
147
    procedure HitEnemy(ADead: Boolean); override;
148
  public
7 daniel-mar 149
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 150
  end;
151
 
152
  TEnemyUFO2 = class(TEnemy)
153
  private
154
    FCounter: Integer;
155
    FTamaCount: Integer;
156
    FOldTamaTime: Integer;
157
  protected
158
    procedure DoMove(MoveCount: Integer); override;
159
    procedure HitEnemy(ADead: Boolean); override;
160
  public
7 daniel-mar 161
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 162
  end;
163
 
164
  TEnemyAttacker = class(TEnemy)
165
  protected
166
    procedure DoMove(MoveCount: Integer); override;
167
    procedure HitEnemy(ADead: Boolean); override;
168
  public
7 daniel-mar 169
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 170
  end;
171
 
172
  TEnemyAttacker2 = class(TEnemy)
173
  private
174
    FCounter: Integer;
175
    FTamaF: Integer;
176
    FTamaT: Integer;
177
    FPutTama: Boolean;
178
  protected
179
    procedure DoMove(MoveCount: Integer); override;
180
    procedure HitEnemy(ADead: Boolean); override;
181
  public
7 daniel-mar 182
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 183
  end;
184
 
185
  TEnemyAttacker3 = class(TEnemy)
186
  private
187
    FCounter: Integer;
188
    FTamaCount: Integer;
189
    FOldTamaTime: Integer;
190
  protected
191
    procedure DoMove(MoveCount: Integer); override;
192
    procedure HitEnemy(ADead: Boolean); override;
193
  public
7 daniel-mar 194
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 195
  end;
196
 
197
  TEnemyBoss = class(TEnemy)
198
  private
199
    FCounter: Integer;
200
    FTamaF: Integer;
201
    FTamaT: Integer;
202
    FPutTama: Boolean;
203
    waiter1, waiter2: integer;
204
  protected
205
    procedure DoMove(MoveCount: Integer); override;
206
    procedure HitEnemy(ADead: Boolean); override;
207
  public
7 daniel-mar 208
    constructor Create(AParent: TSprite; ALifes: integer); override;
3 daniel-mar 209
  end;
210
 
211
  TEnemyAdvent = record
7 daniel-mar 212
    spriteClass: TEnemyClass;
3 daniel-mar 213
    x: extended;
214
    y: extended;
215
    lifes: integer;
216
  end;
217
 
218
  TMainForm = class(TDXForm)
219
    MainMenu: TMainMenu;
220
    Spiel: TMenuItem;
221
    GameStart: TMenuItem;
222
    GamePause: TMenuItem;
223
    Beenden: TMenuItem;
224
    Einstellungen: TMenuItem;
225
    OptionFullScreen: TMenuItem;
226
    OptionMusic: TMenuItem;
227
    Leer2: TMenuItem;
228
    Leer4: TMenuItem;
229
    Hilfe: TMenuItem;
230
    OptionSound: TMenuItem;
231
    Leer3: TMenuItem;
232
    Spielstand: TMenuItem;
233
    Leer5: TMenuItem;
234
    Neustart: TMenuItem;
235
    OptionBreitbild: TMenuItem;
236
    Spielgeschwindigkeit: TMenuItem;
237
    Leicht: TMenuItem;
238
    Mittel: TMenuItem;
239
    Schwer: TMenuItem;
240
    Informationen: TMenuItem;
241
    Leer6: TMenuItem;
242
    Leer1: TMenuItem;
243
    Cheat: TMenuItem;
244
    CheckUpdates: TMenuItem;
245
    Master: TMenuItem;
246
    procedure DXDrawFinalize(Sender: TObject);
247
    procedure DXDrawInitialize(Sender: TObject);
248
    procedure FormCreate(Sender: TObject);
249
    procedure DXTimerTimer(Sender: TObject; LagCount: Integer);
250
    procedure DXTimerActivate(Sender: TObject);
251
    procedure DXTimerDeactivate(Sender: TObject);
252
    procedure OptionFullScreenClick(Sender: TObject);
253
    procedure DXDrawInitializing(Sender: TObject);
254
    procedure GameStartClick(Sender: TObject);
255
    procedure GamePauseClick(Sender: TObject);
256
    procedure BeendenClick(Sender: TObject);
257
    procedure OptionSoundClick(Sender: TObject);
258
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
259
    procedure OptionMusicClick(Sender: TObject);
260
    procedure SpielstandClick(Sender: TObject);
261
    procedure NeustartClick(Sender: TObject);
262
    procedure OptionBreitbildClick(Sender: TObject);
263
    procedure LeichtClick(Sender: TObject);
264
    procedure MittelClick(Sender: TObject);
265
    procedure SchwerClick(Sender: TObject);
266
    procedure FormShow(Sender: TObject);
267
    procedure InformationenClick(Sender: TObject);
268
    procedure CheatClick(Sender: TObject);
269
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
270
    procedure FormDestroy(Sender: TObject);
271
    procedure CheckUpdatesClick(Sender: TObject);
272
    procedure MasterClick(Sender: TObject);
273
  private
274
    ProgrammGestartet: boolean;
275
    FInterval: TGameInterval;
276
    FScene: TGameScene;
277
    FMusic: TMusicTrack;
278
    FBlink: DWORD;
279
    FBlinkTime: DWORD;
280
    FFrame, FAngle, FCounter, FEnemyAdventPos: Integer;
281
    PlayerSprite: TPlayerSprite;
7 daniel-mar 282
    TimerCS: TRTLCriticalSection;
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;
308
    FMenuItem: integer;
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;
317
    wavelist: tdxwavelist;
318
    dxinput: tdxinput;
319
    dxtimer: tdxtimer;
320
    { Level-Routinen }
321
    procedure NewLevel(lev: integer);
322
    procedure DeleteArray;
323
    { MCI-Routinen }
324
    function StatusMusic(Name: TMusicTrack): string;
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
    function SoundKarte: boolean;
333
    procedure PlaySound(Name: string; Wait: Boolean);
334
    { Initialisiations-Routinen }
335
    procedure DXInit;
336
    procedure SoundInit;
337
    procedure MusicInit;
338
    { Einstellungs-Routinen }
339
    procedure LoadOptions;
340
    procedure WriteOptions;
341
    { Farb-Routinen }
342
    function ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
343
    procedure PalleteAnim(Col: TRGBQuad; Time: Integer);
344
  end;
345
 
346
var
347
  MainForm: TMainForm;
348
 
7 daniel-mar 349
implementation
350
 
351
uses
352
  GamSplash, GamSpeicherung, ComInfo, GamCheat, Global;
353
 
3 daniel-mar 354
const
4 daniel-mar 355
  // TODO: ini file
3 daniel-mar 356
  conleicht = 650 div 60; // 10
357
  conmittel = 1000 div 60; // 16
358
  conschwer = 1350 div 60; // 22
359
  conmaster = 2000 div 60; // 33
360
  lives = 6;
361
 
7 daniel-mar 362
  // TODO: Auch für Enemies
363
  PLAYER_MODE_NORMAL = 0;
364
  PLAYER_MODE_DEAD = 1;
365
  PLAYER_MODE_DEAD_VANISHED = 2;
366
  PLAYER_MODE_FLYAWAY = 3;
367
  PLAYER_MODE_ENTER = 4;
3 daniel-mar 368
 
7 daniel-mar 369
  DEFAULT_ANIMSPEED = 15/1000;
3 daniel-mar 370
 
371
resourcestring
372
  FileError = 'Die Datei kann von SpaceMission nicht geöffnet werden!';
373
 
374
{$R *.DFM}
375
 
376
var // TODO: irgendwo hinpacken. irgendwo!!!
7 daniel-mar 377
  EnemyAdventTable: array of TEnemyAdvent;
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
1185
  Ergebnis: string;
1186
  daten: textfile;
1187
  ok: boolean;
1188
begin
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;
1246
  DeleteArray;
1247
  if (paramcount = 0) and (fileexists(paramstr(1))) then // (paramcount > 0)
1248
  begin
1249
    AssignFile(daten, paramstr(1));
1250
    Reset(daten);
1251
    ok := true;
1252
    ReadLN(daten, Ergebnis);
1253
    if Ergebnis <> '; SpaceMission '+ProgramVersion then ok := false;
1254
    ReadLN(daten, Ergebnis);
1255
    if ergebnis <> '; SAV-File' then ok := false;
1256
    if not ok then
1257
    begin
1258
      showmessage(FileError);
1259
      CloseFile(daten);
1260
      GameStartClick(GameStart);
1261
      exit;
1262
    end;
1263
    ReadLN(daten, mainform.FScore);
1264
    ReadLN(daten, mainform.FLife);
1265
    ReadLN(daten, mainform.Flevel);
1266
    ReadLN(daten, mainform.FMenuItem);
1267
    CloseFile(daten);
1268
    mainform.FNextScene := gsNewLevel;
1269
    exit;
1270
  end;
1271
  GameStartClick(GameStart);
1272
end;
1273
 
1274
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
1275
  Shift: TShiftState);
1276
begin
1277
  if (ssAlt in Shift) and (Key=VK_RETURN) then
1278
    OptionFullScreenClick(OptionFullScreen);
1279
end;
1280
 
1281
procedure TMainForm.GameStartClick(Sender: TObject);
1282
begin
1283
  StartScene(gsTitle);
1284
end;
1285
 
1286
procedure TMainForm.GamePauseClick(Sender: TObject);
1287
begin
1288
  GamePause.Checked := not GamePause.Checked;
1289
  DXTimer.Enabled := not GamePause.Checked;
7 daniel-mar 1290
  if GamePause.Checked then
1291
    PauseMusic(FMusic)
1292
  else
3 daniel-mar 1293
    ResumeMusic(FMusic);
1294
end;
1295
 
1296
// http://www.delphipraxis.net/post43515.html
1297
Function GetHTML(AUrl: string): string;
1298
var
1299
  databuffer : array[0..4095] of char;
1300
  ResStr : string;
1301
  hSession, hfile: hInternet;
1302
  dwindex,dwcodelen,dwread,dwNumber: cardinal;
1303
  dwcode : array[1..20] of char;
1304
  res    : pchar;
1305
  Str    : pchar;
1306
begin
1307
  ResStr:='';
1308
  if system.pos('http://',lowercase(AUrl))=0 then
1309
     AUrl:='http://'+AUrl;
1310
 
1311
  // Hinzugefügt
1312
  application.ProcessMessages;
1313
 
1314
  hSession:=InternetOpen('InetURL:/1.0',
1315
                         INTERNET_OPEN_TYPE_PRECONFIG,
1316
                         nil,
1317
                         nil,
1318
                         0);
1319
  if assigned(hsession) then
1320
  begin
1321
    // Hinzugefügt
1322
    application.ProcessMessages;
1323
 
1324
    hfile:=InternetOpenUrl(
1325
           hsession,
1326
           pchar(AUrl),
1327
           nil,
1328
           0,
1329
           INTERNET_FLAG_RELOAD,
1330
           0);
1331
    dwIndex  := 0;
1332
    dwCodeLen := 10;
1333
 
1334
    // Hinzugefügt
1335
    application.ProcessMessages;
1336
 
1337
    HttpQueryInfo(hfile,
1338
                  HTTP_QUERY_STATUS_CODE,
1339
                  @dwcode,
1340
                  dwcodeLen,
1341
                  dwIndex);
1342
    res := pchar(@dwcode);
1343
    dwNumber := sizeof(databuffer)-1;
1344
    if (res ='200') or (res ='302') then
1345
    begin
1346
      while (InternetReadfile(hfile,
1347
                              @databuffer,
1348
                              dwNumber,
1349
                              DwRead)) do
1350
      begin
1351
 
1352
        // Hinzugefügt
1353
        application.ProcessMessages;
1354
 
1355
        if dwRead =0 then
1356
          break;
1357
        databuffer[dwread]:=#0;
1358
        Str := pchar(@databuffer);
1359
        resStr := resStr + Str;
1360
      end;
1361
    end
1362
    else
1363
      ResStr := 'Status:'+res;
1364
    if assigned(hfile) then
1365
      InternetCloseHandle(hfile);
1366
  end;
1367
 
1368
  // Hinzugefügt
1369
  application.ProcessMessages;
1370
 
1371
  InternetCloseHandle(hsession);
1372
  Result := resStr;
1373
end;
1374
 
1375
procedure TMainForm.CheckUpdatesClick(Sender: TObject);
1376
var
1377
  temp: string;
1378
begin
1379
  temp := GetHTML('http://www.viathinksoft.de/update/?id=spacemission');
1380
  if copy(temp, 0, 7) = 'Status:' then
1381
  begin
1382
    Application.MessageBox('Ein Fehler ist aufgetreten. Wahrscheinlich ist keine Internetverbindung aufgebaut, oder der der ViaThinkSoft-Server temporär offline.', 'Fehler', MB_OK + MB_ICONERROR)
1383
  end
1384
  else
1385
  begin
1386
    if GetHTML('http://www.viathinksoft.de/update/?id=spacemission') <> ProgramVersion then
1387
    begin
1388
      if Application.MessageBox('Eine neue Programmversion ist vorhanden. Möchten Sie diese jetzt herunterladen?', 'Information', MB_YESNO + MB_ICONASTERISK) = ID_YES then
1389
        shellexecute(application.handle, 'open', pchar('http://www.viathinksoft.de/update/?id=@spacemission'), '', '', sw_normal);
1390
    end
1391
    else
1392
    begin
1393
      Application.MessageBox('Es ist keine neue Programmversion vorhanden.', 'Information', MB_OK + MB_ICONASTERISK);
1394
    end;
1395
  end;
1396
end;
1397
 
1398
procedure TMainForm.BeendenClick(Sender: TObject);
1399
begin
1400
  close;
1401
end;
1402
 
1403
procedure TMainForm.OptionFullScreenClick(Sender: TObject);
1404
begin
1405
  OptionFullScreen.Checked := not OptionFullScreen.Checked;
1406
  DXInit;
1407
  writeoptions;
1408
end;
1409
 
1410
procedure TMainForm.OptionSoundClick(Sender: TObject);
1411
begin
1412
  OptionSound.Checked := not OptionSound.Checked;
1413
  SoundInit;
1414
  WriteOptions;
1415
end;
1416
 
1417
procedure TMainForm.SoundInit;
1418
begin
1419
  if OptionSound.Checked then
1420
  begin
1421
    if not DXSound.Initialized then
1422
    begin
1423
      try
1424
        DXSound.Initialize;
1425
        WaveList.Items.LoadFromFile(FDirectory+'DirectX\Sound.dxw');
1426
      except
1427
        OptionSound.enabled := False;
1428
        WaveList.items.clear;
1429
      end;
1430
    end;
1431
  end
1432
  else DXSound.Finalize;
1433
end;
1434
 
1435
procedure TMainForm.MusicInit;
1436
begin
1437
  optionmusic.enabled := SoundKarte;
1438
end;
1439
 
1440
procedure TMainForm.DestroyMusic(Name: TMusicTrack);
1441
begin
1442
  if Name = mtBoss then
1443
  begin
1444
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1445
    MCISendString(pchar('close "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1446
  end;
1447
  if Name = mtGame then
1448
  begin
1449
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1450
    MCISendString(pchar('close "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1451
  end;
1452
  if Name = mtScene then
1453
  begin
1454
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1455
    MCISendString(pchar('close "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1456
  end;
1457
  if Name = mtTitle then
1458
  begin
1459
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1460
    MCISendString(pchar('close "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1461
  end;
1462
end;
1463
 
1464
procedure TMainForm.OpenMusic(Name: TMusicTrack);
1465
begin
1466
  if Name = mtBoss then
1467
    MCISendString(pchar('open "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1468
  if Name = mtGame then
1469
    MCISendString(pchar('open "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1470
  if Name = mtScene then
1471
    MCISendString(pchar('open "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1472
  if Name = mtTitle then
1473
    MCISendString(pchar('open "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1474
end;
1475
 
1476
procedure TMainForm.PauseMusic(Name: TMusicTrack);
1477
begin
1478
  if not OptionMusic.checked then exit;
1479
  if Name = mtBoss then
1480
    MCISendString(pchar('stop "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
1481
  if Name = mtGame then
1482
    MCISendString(pchar('stop "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
1483
  if Name = mtScene then
1484
    MCISendString(pchar('stop "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
1485
  if Name = mtTitle then
1486
    MCISendString(pchar('stop "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
1487
end;
1488
 
1489
procedure TMainForm.DXDrawInitializing(Sender: TObject);
1490
begin
1491
  if doFullScreen in DXDraw.Options then
1492
  begin
1493
    BorderStyle := bsNone;
1494
    DXDraw.Cursor := crNone;
7 daniel-mar 1495
  end
1496
  else
3 daniel-mar 1497
  begin
1498
    BorderStyle := bsSingle;
1499
    DXDraw.Cursor := crDefault;
1500
  end;
1501
end;
1502
 
1503
procedure TMainForm.DXDrawInitialize(Sender: TObject);
1504
begin
1505
  DXTimer.Enabled := True;
1506
end;
1507
 
1508
procedure TMainForm.DXDrawFinalize(Sender: TObject);
1509
begin
1510
  DXTimer.Enabled := False;
1511
end;
1512
 
1513
procedure TMainForm.DXTimerActivate(Sender: TObject);
1514
begin
1515
  Caption := Application.Title;
1516
  if not ProgrammGestartet then
1517
  begin
1518
    Programmgestartet := true;
1519
    exit;
1520
  end;
1521
  ResumeMusic(FMusic);
1522
end;
1523
 
1524
procedure TMainForm.DXTimerDeactivate(Sender: TObject);
1525
begin
1526
  Caption := Application.Title + ' [Pause]';
1527
  PauseMusic(FMusic);
1528
end;
1529
 
1530
function TMainForm.StatusMusic(Name: TMusicTrack): string;
1531
var
1532
  MCIStatus: array[0..255] of char;
1533
begin
1534
  if not OptionMusic.checked then exit;
1535
  if FMusic = mtGame then
1536
    MCISendString(pchar('status "'+FDirectory+'Musik\Game.mid" mode'), MCIStatus, 255, 0);
1537
  if FMusic = mtBoss then
1538
    MCISendString(pchar('status "'+FDirectory+'Musik\Boss.mid" mode'), MCIStatus, 255, 0);
1539
  if FMusic = mtScene then
1540
    MCISendString(pchar('status "'+FDirectory+'Musik\Scene.mid" mode'), MCIStatus, 255, 0);
1541
  if FMusic = mtTitle then
1542
    MCISendString(pchar('status "'+FDirectory+'Musik\Title.mid" mode'), MCIStatus, 255, 0);
1543
  result := MCIStatus;
1544
end;
1545
 
1546
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
1547
begin
7 daniel-mar 1548
  EnterCriticalSection(TimerCS);
1549
  try
1550
    if StatusMusic(FMusic) = 'stopped' then
1551
      PlayMusic(FMusic); {...}
1552
    if crash then
3 daniel-mar 1553
    begin
7 daniel-mar 1554
      inc(Crash2);
1555
      if crash2 = 30 then
1556
      begin
1557
        Crash2 := 0;
1558
        crash := false;
1559
        crashsound := false;
1560
      end;
3 daniel-mar 1561
    end;
7 daniel-mar 1562
    if not DXDraw.CanDraw then exit;
1563
    DXInput.Update;
1564
    case FScene of
1565
      gsTitle   : SceneTitle;
1566
      gsMain    : SceneMain;
1567
      gsGameOver: SceneGameOver;
1568
      gsWin     : SceneWin;
1569
      gsNewLevel: SceneNewLevel;
1570
    end;
1571
    if FNextScene<>gsNone then
1572
    begin
1573
      StartScene(FNextScene);
1574
      FNextScene := gsNone;
1575
    end;
1576
    DXDraw.Flip;
1577
  finally
1578
    LeaveCriticalSection(TimerCS);
3 daniel-mar 1579
  end;
1580
end;
1581
 
1582
procedure TMainForm.BlinkStart;
1583
begin
1584
  FBlink := 0;
1585
  FBlinkTime := GetTickCount;
1586
end;
1587
 
1588
procedure TMainForm.WriteOptions;
1589
var
1590
  INIDatei: TIniFile;
1591
begin
1592
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1593
  try
1594
    if OptionMusic.checked then INIDatei.WriteBool('Settings', 'Music', true)
1595
      else INIDatei.WriteBool('Settings', 'Music', false);
1596
    if OptionSound.checked then INIDatei.WriteBool('Settings', 'Sound', true)
1597
      else INIDatei.WriteBool('Settings', 'Sound', false);
1598
    if OptionFullScreen.checked then INIDatei.WriteBool('Settings', 'FullScreen', true)
1599
      else INIDatei.WriteBool('Settings', 'FullScreen', false);
1600
    if OptionBreitbild.checked then INIDatei.WriteBool('Settings', 'ScreenAutoSize', true)
1601
      else INIDatei.WriteBool('Settings', 'ScreenAutoSize', false);
1602
    if FInterval = giLeicht then INIDatei.WriteInteger('Settings', 'Speed', 1);
1603
    if FInterval = giMittel then INIDatei.WriteInteger('Settings', 'Speed', 2);
1604
    if FInterval = giSchwer then INIDatei.WriteInteger('Settings', 'Speed', 3);
1605
    if FInterval = giMaster then INIDatei.WriteInteger('Settings', 'Speed', 4);
1606
  finally
1607
    INIDatei.Free;
1608
  end;
3 daniel-mar 1609
end;
1610
 
1611
procedure TMainForm.LoadOptions;
1612
var
1613
  INIDatei: TIniFile;
1614
begin
1615
  INIDatei := TIniFile.Create(FDirectory+'Einstellungen\SpaceMission.ini');
7 daniel-mar 1616
  try
1617
    optionmusic.checked := INIDatei.ReadBool('Settings', 'Music', true);
1618
    optionsound.checked := INIDatei.ReadBool('Settings', 'Sound', true);
1619
    optionfullscreen.checked := INIDatei.ReadBool('Settings', 'fullscreen', false);
1620
    OptionBreitBild.checked := INIDatei.ReadBool('Settings', 'ScreenAutoSize', true);
1621
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 1 then
1622
    begin
1623
      FInterval := giLeicht;
1624
      Leicht.checked := true;
1625
    end;
1626
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 2 then
1627
    begin
1628
      FInterval := giMittel;
1629
      Mittel.checked := true;
1630
    end;
1631
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 3 then
1632
    begin
1633
      FInterval := giSchwer;
1634
      Schwer.checked := true;
1635
    end;
1636
    if INIDatei.ReadInteger('Settings', 'Speed', 2) = 4 then
1637
    begin
1638
      FInterval := giMaster;
1639
      Master.checked := true;
1640
    end;
1641
  finally
1642
    INIDatei.Free;
3 daniel-mar 1643
  end;
1644
  WriteOptions;
1645
end;
1646
 
1647
procedure TMainForm.BlinkUpdate;
1648
begin
1649
  if GetTickCount<>FBlinkTime then
1650
  begin
1651
    FBlink := FBlink + (GetTickCount-FBlinkTime);
1652
    FBlinkTime := GetTickCount;
1653
  end;
1654
end;
1655
 
1656
procedure TMainForm.PlaySound(Name: string; Wait: Boolean);
1657
begin
1658
  if (OptionSound.Checked) and (OptionSound.Enabled) then
1659
    WaveList.Items.Find(Name).Play(Wait);
1660
end;
1661
 
1662
procedure TMainForm.PlayMusic(Name: TMusicTrack);
1663
begin
1664
  if (not mainform.active) and (mainform.visible) then //1st Programmstart
1665
    exit;
1666
  if (OptionMusic.checked) and (OptionMusic.enabled) then
1667
  begin
1668
    DestroyMusic(FMusic);
1669
    OpenMusic(Name);
1670
    ResumeMusic(Name);
1671
  end;
1672
  FMusic := Name;
1673
end;
1674
 
1675
function TMainForm.ComposeColor(Dest, Src: TRGBQuad; Percent: Integer): TRGBQuad;
1676
begin
1677
  with Result do
1678
  begin
1679
    rgbRed := Src.rgbRed+((Dest.rgbRed-Src.rgbRed)*Percent div 256);
1680
    rgbGreen := Src.rgbGreen+((Dest.rgbGreen-Src.rgbGreen)*Percent div 256);
1681
    rgbBlue := Src.rgbBlue+((Dest.rgbBlue-Src.rgbBlue)*Percent div 256);
1682
    rgbReserved := 0;
1683
  end;
1684
end;
1685
 
1686
procedure TMainForm.PalleteAnim(Col: TRGBQuad; Time: Integer);
1687
var
1688
  i: Integer;
1689
  t, t2: DWORD;
1690
  ChangePalette: Boolean;
1691
  c: Integer;
1692
begin
1693
  if DXDraw.Initialized then
1694
  begin
1695
    c := DXDraw.Surface.ColorMatch(RGB(Col.rgbRed, Col.rgbGreen, Col.rgbBlue));
1696
    ChangePalette := False;
1697
    if DXDraw.CanPaletteAnimation then
1698
    begin
1699
      t := GetTickCount;
1700
      while Abs(GetTickCount-t)<Time do
1701
      begin
1702
        t2 := Trunc(Abs(GetTickCount-t)/Time*255);
1703
        for i := 0 to 255 do
1704
          DXDraw.ColorTable[i] := ComposeColor(Col, DXDraw.DefColorTable[i], t2);
1705
        DXDraw.UpdatePalette;
1706
        ChangePalette := True;
1707
      end;
7 daniel-mar 1708
    end
1709
    else
1710
    begin
3 daniel-mar 1711
      Sleep(Time);
7 daniel-mar 1712
    end;
3 daniel-mar 1713
    for i := 0 to 4 do
1714
    begin
1715
      DXDraw.Surface.Fill(c);
1716
      DXDraw.Flip;
1717
    end;
1718
    if ChangePalette then
1719
    begin
1720
      DXDraw.ColorTable := DXDraw.DefColorTable;
1721
      DXDraw.UpdatePalette;
1722
    end;
1723
    DXDraw.Surface.Fill(c);
1724
    DXDraw.Flip;
1725
  end;
1726
end;
1727
 
1728
procedure TMainForm.StartScene(Scene: TGameScene);
1729
begin
1730
  EndScene;
1731
  DXInput.States := DXInput.States - DXInputButton;
1732
  FScene := Scene;
1733
  BlinkStart;
1734
  case FScene of
1735
    gsTitle   : StartSceneTitle;
1736
    gsMain    : StartSceneMain;
1737
    gsGameOver: StartSceneGameOver;
1738
    gsWin     : StartSceneWin;
1739
    gsNewLevel: StartSceneNewLevel;
1740
  end;
1741
end;
1742
 
1743
procedure TMainForm.StartSceneTitle;
1744
begin
1745
  sleep(500);
1746
  FCheat := false;
1747
  BossExists := false;
1748
  FLife := Lives;
1749
  FLevel := 0;
1750
  FScore := 0;
1751
  FNotSave := true;
1752
  Cheat.enabled := false;
1753
  Neustart.enabled := false;
1754
  GamePause.enabled := false;
1755
  GameStart.enabled := false;
1756
  Spielgeschwindigkeit.enabled := false;
1757
  mainform.Visible := true;
1758
  PlayMusic(mtTitle);
1759
end;
1760
 
1761
procedure TMainForm.StartSceneMain;
1762
{var
1763
  i, j: Integer;}
1764
begin
1765
  sleep(500);
1766
  FCounter := 0;
1767
  NewLevel(FLevel);
1768
  BossExists := false;
1769
  PlayMusic(mtGame);
7 daniel-mar 1770
  FEnemyAdventPos := 0;
3 daniel-mar 1771
  FFrame := -4;
1772
  PlayerSprite := TPlayerSprite.Create(SpriteEngine.Engine);
1773
  with TBackground.Create(SpriteEngine.Engine) do
1774
  begin
1775
    SetMapSize(1, 1);
1776
    Image := mainform.ImageList.Items.Find('Star3');
1777
    Z := -13;
1778
    Y := 40;
1779
    FSpeed := 1 / 2;
1780
    Tile := True;
1781
  end;
1782
  with TBackground.Create(SpriteEngine.Engine) do
1783
  begin
1784
    SetMapSize(1, 1);
1785
    Image := mainform.ImageList.Items.Find('Star2');
1786
    Z := -12;
1787
    Y := 30;
1788
    FSpeed := 1;
1789
    Tile := True;
1790
  end;
1791
  with TBackground.Create(SpriteEngine.Engine) do
1792
  begin
1793
    SetMapSize(1, 1);
1794
    Image := mainform.ImageList.Items.Find('Star1');
1795
    Z := -11;
1796
    Y := 10;
1797
    FSpeed := 2;
1798
    Tile := True;
1799
  end;
1800
  {with TBackground.Create(SpriteEngine.Engine) do
1801
  begin
1802
    SetMapSize(200, 10);
1803
    Y := 10;
1804
    Z := -13;
1805
    FSpeed := 1 / 2;
1806
    Tile := True;
1807
    for i := 0 to MapHeight-1 do
1808
    begin
1809
      for j := 0 to MapWidth-1 do
1810
      begin
1811
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 8);
1812
        if Random(100)<95 then Chips[j, i] := -1;
1813
      end;
1814
    end;
1815
  end;
1816
  with TBackground.Create(SpriteEngine.Engine) do
1817
  begin
1818
    SetMapSize(200, 10);
1819
    Y := 30;
1820
    Z := -12;
1821
    FSpeed := 1;
1822
    Tile := True;
1823
    for i := 0 to MapHeight-1 do
1824
    begin
1825
      for j := 0 to MapWidth-1 do
1826
      begin
1827
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 4);
1828
        if Random(100)<95 then Chips[j, i] := -1;
1829
      end;
1830
    end;
1831
  end;
1832
  with TBackground.Create(SpriteEngine.Engine) do
1833
  begin
1834
    SetMapSize(200, 10);
1835
    Y := 40;
1836
    Z := -11;
1837
    FSpeed := 2;
1838
    Tile := True;
1839
    for i := 0 to MapHeight-1 do
1840
    begin
1841
      for j := 0 to MapWidth-1 do
1842
      begin
1843
        Chips[j, i] := Image.PatternCount-Random(Image.PatternCount div 2);
1844
        if Random(100)<95 then Chips[j, i] := -1;
1845
      end;
1846
    end;
1847
  end;}
1848
  FNotSave := false;
1849
  Cheat.enabled := true;
1850
  Neustart.enabled := true;
1851
  GamePause.enabled := true;
1852
  GameStart.enabled := true;
1853
  Spielgeschwindigkeit.enabled := true;
1854
end;
1855
 
1856
procedure TMainForm.StartSceneGameOver;
1857
begin
1858
  sleep(500);
1859
  FNotSave := true;
1860
  Cheat.enabled := false;
1861
  Spielgeschwindigkeit.enabled := false;
1862
  Neustart.enabled := false;
1863
  GamePause.enabled := false;
1864
  PlayMusic(mtScene);
1865
  BossExists := false;
1866
end;
1867
 
1868
procedure TMainForm.StartSceneWin;
1869
begin
1870
  sleep(500);
1871
  FNotSave := true;
1872
  Cheat.enabled := false;
1873
  Spielgeschwindigkeit.enabled := false;
1874
  Neustart.enabled := false;
1875
  GamePause.enabled := false;
1876
  PlayMusic(mtScene);
1877
  BossExists := false;
1878
end;
1879
 
1880
procedure TMainForm.EndScene;
1881
begin
1882
  case FScene of
1883
    gsTitle   : EndSceneTitle;
1884
    gsMain    : EndSceneMain;
1885
    gsGameOver: EndSceneGameOver;
1886
    gsWin     : EndSceneWin;
1887
    gsNewLevel: EndSceneNewLevel;
1888
  end;
1889
end;
1890
 
1891
procedure TMainForm.EndSceneTitle;
1892
begin
1893
  {  Ende Title  }
1894
end;
1895
 
1896
procedure TMainForm.EndSceneMain;
1897
begin
1898
  SpriteEngine.Engine.Clear;
1899
end;
1900
 
1901
procedure TMainForm.EndSceneGameOver;
1902
begin
1903
  {  Ende GameOver  }
1904
end;
1905
 
1906
procedure TMainForm.EndSceneWin;
1907
begin
1908
  {  Ende Win  }
1909
end;
1910
 
1911
procedure TMainForm.DeleteArray();
1912
begin
7 daniel-mar 1913
  SetLength(EnemyAdventTable, 0);
1914
  FRestEnemies := 0;
3 daniel-mar 1915
end;
1916
 
7 daniel-mar 1917
const
1918
  ADDITIONAL_ENEMIES_PER_LEVEL = 75;
1919
 
1920
function GetLevelFileName(lev: integer): string;
1921
begin
1922
  result := FDirectory+'Levels\Level '+inttostr(lev)+'.lev';
1923
end;
1924
 
3 daniel-mar 1925
procedure TMainForm.NewLevel(lev: integer);
1926
resourcestring
1927
  LNG_LEVEL_INVALID = 'Das Level Nr. %d ist ungültig!'+#13#10+'Das Programm wird beendet.';
1928
var
1929
  act: integer;
1930
  filex: textfile;
1931
  ergebniss: string;
7 daniel-mar 1932
  Enemies: array[1..27] of TEnemyClass;
1933
  e: TEnemyAdvent;
3 daniel-mar 1934
begin
1935
  DeleteArray;
1936
  if FMenuItem = 2 then
1937
  begin
7 daniel-mar 1938
    Enemies[1] := TEnemyAttacker;
1939
    Enemies[2] := TEnemyMeteor;
1940
    Enemies[3] := TEnemyUFO;
1941
    Enemies[4] := TEnemyAttacker;
1942
    Enemies[5] := TEnemyMeteor;
1943
    Enemies[6] := TEnemyUFO;
1944
    Enemies[7] := TEnemyAttacker;
1945
    Enemies[8] := TEnemyMeteor;
1946
    Enemies[9] := TEnemyUFO;
1947
    Enemies[10] := TEnemyAttacker;
1948
    Enemies[11] := TEnemyMeteor;
1949
    Enemies[12] := TEnemyUFO;
1950
    Enemies[13] := TEnemyAttacker;
1951
    Enemies[14] := TEnemyMeteor;
1952
    Enemies[15] := TEnemyUFO;
1953
    Enemies[16] := TEnemyAttacker3;
1954
    Enemies[17] := TEnemyAttacker;
1955
    Enemies[18] := TEnemyMeteor;
1956
    Enemies[19] := TEnemyUFO;
1957
    Enemies[20] := TEnemyUFO2;
1958
    Enemies[21] := TEnemyAttacker;
1959
    Enemies[22] := TEnemyMeteor;
1960
    Enemies[23] := TEnemyUFO;
1961
    Enemies[24] := TEnemyAttacker2;
1962
    Enemies[25] := TEnemyMeteor;
1963
    Enemies[26] := TEnemyUFO;
1964
    Enemies[27] := TEnemyAttacker;
3 daniel-mar 1965
    randomize;
7 daniel-mar 1966
    FRestEnemies := lev*ADDITIONAL_ENEMIES_PER_LEVEL+1;
1967
    SetLength(EnemyAdventTable, FRestEnemies);
1968
    for act := 0 to lev*ADDITIONAL_ENEMIES_PER_LEVEL-1 do
3 daniel-mar 1969
    begin
7 daniel-mar 1970
      e.spriteClass := Enemies[min(random(lev+2)+1, High(Enemies))];
1971
      if e.spriteClass = TEnemyAttacker2 then
1972
      begin
1973
        e.spriteClass := Enemies[min(random(lev+2)+1, High(Enemies))]; {O_o}
1974
      end;
1975
      e.x := act*30 + random(85-(lev+(random(lev))*2)){O_o};
1976
      e.y := random(dxdraw.surfaceheight);
1977
      if e.spriteClass = TEnemyAttacker2 then
1978
      begin
1979
        e.lifes := random(6)+1{O_o};
1980
      end
1981
      else
1982
      begin
1983
        e.lifes := random(lev)+1;
1984
      end;
1985
 
1986
      EnemyAdventTable[act] := e;
3 daniel-mar 1987
    end;
7 daniel-mar 1988
    e.spriteClass := TEnemyBoss;
1989
    e.x := lev*75*30{O_o} div lev;
1990
    e.y := (dxdraw.surfaceheight div 2) - (MainForm.ImageList.Items.Find('Enemy-boss').height div 2);
1991
    e.lifes := lev*5;
1992
    EnemyAdventTable[lev*ADDITIONAL_ENEMIES_PER_LEVEL] := e;
3 daniel-mar 1993
  end
1994
  else
1995
  begin
7 daniel-mar 1996
    Enemies[1] := TEnemyAttacker;
1997
    Enemies[2] := TEnemyAttacker2;
1998
    Enemies[3] := TEnemyAttacker3;
1999
    Enemies[4] := TEnemyMeteor;
2000
    Enemies[5] := TEnemyUFO;
2001
    Enemies[6] := TEnemyUFO2;
2002
    Enemies[7] := TEnemyBoss;
2003
    if fileexists(GetLevelFileName(lev)) then
3 daniel-mar 2004
    begin
7 daniel-mar 2005
      assignfile(filex, GetLevelFileName(lev));
3 daniel-mar 2006
      reset(filex);
7 daniel-mar 2007
      try
2008
        readln(filex, ergebniss);
2009
        Assert(ergebniss = '; SpaceMission '+FCompVersion);
2010
        readln(filex, ergebniss);
2011
        Assert(ergebniss = '; LEV-File');
2012
 
2013
        readln(filex); // Länge der Karte
2014
 
2015
        while not seekEoF(filex) do
3 daniel-mar 2016
        begin
2017
          readln(filex, ergebniss);
7 daniel-mar 2018
          e.spriteClass := Enemies[strtoint(ergebniss)];
3 daniel-mar 2019
          readln(filex, ergebniss);
7 daniel-mar 2020
          e.x := strtoint(ergebniss);
2021
          readln(filex, ergebniss);
2022
          e.y := strtoint(ergebniss);
2023
          readln(filex, ergebniss);
2024
          e.lifes := strtoint(ergebniss);
2025
 
2026
          inc(FRestEnemies);
2027
          SetLength(EnemyAdventTable, FRestEnemies);
2028
          EnemyAdventTable[FRestEnemies-1] := e;
3 daniel-mar 2029
        end;
7 daniel-mar 2030
      except
2031
        showmessage(Format(LNG_LEVEL_INVALID, [lev]));
2032
        DeleteArray;
3 daniel-mar 2033
      end;
2034
      closefile(filex);
2035
    end;
2036
  end;
7 daniel-mar 2037
  Assert(FRestEnemies = Length(EnemyAdventTable));
3 daniel-mar 2038
end;
2039
 
2040
procedure TMainForm.SceneTitle;
2041
var
2042
  Logo: TPictureCollectionItem;
2043
begin
2044
  DXDraw.Surface.Fill(0);
2045
  Logo := ImageList.Items.Find('Logo');
2046
  {Logo.DrawWaveX(DXDraw.Surface, (dxdraw.surfaceWidth div 2) - 181, 65, Logo.Width, Logo.Height, 0,
2047
    Trunc(16 - Cos256(FBlink div 60) * 16), 32, -FBlink div 5);}
2048
  Logo.DrawWaveX(DXDraw.Surface, trunc((dxdraw.surfaceWidth / 2) - (Logo.Width / 2)), 65, Logo.Width, Logo.Height, 0,
2049
    2, 80, Fangle * 4);
2050
  inc(Fangle);
2051
  with DXDraw.Surface.Canvas do
2052
  begin
2053
    if (isDown in MainForm.DXInput.States) and (FMenuItem=1) then FMenuItem := 2;
2054
    if ((isUp in MainForm.DXInput.States) and (FMenuItem=2)) or (FMenuItem=0) then FMenuItem := 1;
2055
    Brush.Style := bsClear;
2056
    Font.Size := 30;
2057
    if FMenuItem = 1 then
2058
    begin
2059
      Font.Color := clMaroon;
2060
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2061
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-52, '>');
2062
      Font.Color := clRed;
2063
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2064
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2)-50, '>');
2065
      Font.Color := clOlive;
2066
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2067
      Font.Color := clYellow;
2068
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2069
    end
2070
    else
2071
    begin
2072
      Font.Color := clOlive;
2073
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-52, 'Normales Spiel');
2074
      Font.Color := clYellow;
2075
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2)-50, 'Normales Spiel');
2076
      Font.Color := clMaroon;
2077
      Textout((dxdraw.surfaceWidth div 2)-152, (dxdraw.surfaceheight div 2)-2, 'Zufallslevel');
2078
      Textout((dxdraw.surfaceWidth div 2)-187, (dxdraw.surfaceheight div 2)-2, '>');
2079
      Font.Color := clRed;
2080
      Textout((dxdraw.surfaceWidth div 2)-150, (dxdraw.surfaceheight div 2), 'Zufallslevel');
2081
      Textout((dxdraw.surfaceWidth div 2)-185, (dxdraw.surfaceheight div 2), '>');
2082
    end;
2083
    { if (FBlink div 300) mod 2=0 then
2084
    begin
2085
      Font.Color := clGreen;
2086
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2087
      Font.Color := clLime;
2088
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2089
    end; }
2090
    BlinkUpdate;
2091
    Release;
2092
  end;
2093
  // Weiter mit Leertaste oder Enter
2094
  if (isButton1 in DXInput.States) or (isButton2 in DXInput.States) then
2095
  begin
2096
    FLevel := 1;
7 daniel-mar 2097
    if ((FMenuItem=1) and not fileexists(GetLevelFileName(FLevel))) or ((FMenuItem=2) and (FLevel > 20)) then
3 daniel-mar 2098
    begin
2099
      //PlaySound('Frage', False);
2100
      exit;
2101
    end;
2102
    NewLevel(FLevel);
2103
    PlaySound('SceneMov', False);
2104
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2105
    Sleep(200);
2106
    StartScene(gsMain);
2107
  end;
2108
end;
2109
 
2110
procedure TMainForm.SceneMain;
2111
var
2112
  Enemy: TSprite;
2113
begin
7 daniel-mar 2114
  case FInterval of
2115
    giMittel: SpriteEngine.Move(conleicht);
2116
    giLeicht: SpriteEngine.Move(conmittel);
2117
    giSchwer: SpriteEngine.Move(conschwer);
2118
    giMaster: SpriteEngine.Move(conmaster);
2119
  end;
3 daniel-mar 2120
  SpriteEngine.Dead;
7 daniel-mar 2121
  while (FEnemyAdventPos >= Low(EnemyAdventTable)) and
2122
    (FEnemyAdventPos <= High(EnemyAdventTable)) and
2123
    ((EnemyAdventTable[FEnemyAdventPos].x / 4) <= FFrame) and
2124
    (FRestEnemies > 0) do
3 daniel-mar 2125
  begin
7 daniel-mar 2126
    Dec(FRestEnemies);
2127
    with EnemyAdventTable[FEnemyAdventPos] do
3 daniel-mar 2128
    begin
7 daniel-mar 2129
      Enemy := spriteClass.Create(SpriteEngine.Engine, lifes);
2130
      Enemy.x := dxdraw.surfacewidth;
2131
      //Enemy.y := y;
2132
      if y <> 0 then
2133
        Enemy.y := dxdraw.surfaceheight / (480{maximale Bandbreite im alten Format} / y)
2134
      else
2135
        Enemy.y := 0;
3 daniel-mar 2136
    end;
2137
    Inc(FEnemyAdventPos);
2138
  end;
2139
  Inc(FFrame);
2140
  DXDraw.Surface.Fill(0);
2141
  if FNextScene=gsNone then
2142
  begin
2143
    SpriteEngine.Draw;
2144
    if MainForm.flife > 0 then
2145
    begin
2146
      with DXDraw.Surface.Canvas do
2147
      begin
2148
        Brush.Style := bsClear;
2149
        Font.Size := 20;
2150
        Font.Color := clOlive;
2151
        Textout(9, 9, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2152
        Font.Color := clYellow;
2153
        Textout(10, 10, 'Punkte: ' + FloatToStrF(FScore,ffNumber,14,0));
2154
        Font.Color := clMaroon;
2155
        Textout(dxdraw.surfacewidth-141, 9, 'Level: ' + IntToStr(MainForm.flevel));
2156
        Font.Color := clRed;
2157
        Textout(dxdraw.surfacewidth-140, 10, 'Level: ' + IntToStr(MainForm.flevel));
2158
        if FLife<0 then mainform.FLife := 0;
2159
        if FCheat then
2160
        begin
2161
          Font.Color := clPurple;
2162
          Textout(9, dxdraw.surfaceheight-41, 'Leben: ?');
2163
          Font.Color := clFuchsia;
2164
          Textout(10, dxdraw.surfaceheight-40, 'Leben: ?');
2165
        end
2166
        else
2167
        begin
2168
          if ((Flife = 1) and ((FBlink div 300) mod 2=0)) or (Flife <> 1) then
2169
          begin
2170
            Font.Color := clPurple;
2171
            Textout(9, dxdraw.surfaceheight-41, 'Leben: ' + IntToStr(MainForm.flife));
2172
            Font.Color := clFuchsia;
2173
            Textout(10, dxdraw.surfaceheight-40, 'Leben: ' + IntToStr(MainForm.flife));
2174
          end;
2175
          if Flife = 1 then BlinkUpdate;
2176
        end;
2177
        {if BossExists and (FBossLife>0) then
2178
        begin
2179
          Font.Color := clPurple;
2180
          Textout(449, 439, 'Boss: ' + IntToStr(FBossLife));
2181
          Font.Color := clFuchsia;
2182
          Textout(450, 440, 'Boss: ' + IntToStr(FBossLife));
2183
        end
2184
        else
2185
          if RestlicheEinheiten>0 then
2186
          begin
2187
            Font.Color := clPurple;
2188
            Textout(449, 439, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2189
            Font.Color := clFuchsia;
2190
            Textout(450, 440, 'Einheiten: ' + IntToStr(RestlicheEinheiten));
2191
          end;}
2192
        if BossExists and (FBossLife>0) then
2193
        begin
7 daniel-mar 2194
          if (FRestEnemies>0) then
3 daniel-mar 2195
          begin
2196
            Font.Color := clGreen;
2197
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-81, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2198
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2199
            Font.Color := clLime;
2200
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-80, 'Boss: ' + IntToStr(FBossLife));
7 daniel-mar 2201
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2202
          end;
7 daniel-mar 2203
          if (FRestEnemies<1) then
3 daniel-mar 2204
          begin
2205
            Font.Color := clGreen;
2206
            Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Boss: ' + IntToStr(FBossLife));
2207
            Font.Color := clLime;
2208
            Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Boss: ' + IntToStr(FBossLife));
2209
          end;
2210
        end;
7 daniel-mar 2211
        if (FRestEnemies>0) and not Bossexists then
3 daniel-mar 2212
        begin
2213
          Font.Color := clGreen;
7 daniel-mar 2214
          Textout(dxdraw.surfacewidth-191, dxdraw.surfaceheight-41, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2215
          Font.Color := clLime;
7 daniel-mar 2216
          Textout(dxdraw.surfacewidth-190, dxdraw.surfaceheight-40, 'Einheiten: ' + IntToStr(FRestEnemies));
3 daniel-mar 2217
        end;
2218
        Release;
2219
      end;
2220
    end
2221
    else
2222
    begin
2223
      DXDraw.Surface.Canvas.Font.Color := clGreen; // Grüne schrift bei gescheitert? FIXME
2224
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission gescheitert!');
2225
      DXDraw.Surface.Canvas.Font.Color := clLime;
2226
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission gescheitert!');
2227
      DXDraw.Surface.Canvas.Release;
2228
    end;
7 daniel-mar 2229
    if (EnemyCounter=0) and (FRestEnemies=0){ and (SpielerFliegtFort = false)}
3 daniel-mar 2230
    and ((BossExists and (FBossLife=0)) or not BossExists) then
2231
    begin
2232
      DXDraw.Surface.Canvas.Font.Color := clGreen;
2233
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-251, dxdraw.surfaceheight-41, 'Mission erfolgreich!');
2234
      DXDraw.Surface.Canvas.Font.Color := clLime;
2235
      DXDraw.Surface.Canvas.Textout(dxdraw.surfacewidth-250, dxdraw.surfaceheight-40, 'Mission erfolgreich!');
2236
      DXDraw.Surface.Canvas.Release;
2237
      Sleep(1);
2238
      inc(FCounter);
2239
      if FCounter>150{200} then PlayerSprite.FlyAway;
2240
    end;
2241
  end;
2242
end;
2243
 
2244
procedure TMainForm.SceneGameOver;
2245
begin
2246
  DXDraw.Surface.Fill(0);
2247
  with DXDraw.Surface.Canvas do
2248
  begin
2249
    FNotSave := true;
2250
    Cheat.enabled := false;
2251
    GamePause.enabled := false;
2252
    Neustart.enabled := false;
2253
    Brush.Style := bsClear;
2254
    Font.Size := 35;
2255
    Font.Color := clMaroon;
11 daniel-mar 2256
    Textout((dxdraw.surfacewidth div 2)-127, 98, 'Game Over!');
3 daniel-mar 2257
    Font.Color := clRed;
11 daniel-mar 2258
    Textout((dxdraw.surfacewidth div 2)-125, 100, 'Game Over!');
3 daniel-mar 2259
    if (FBlink div 300) mod 2=0 then
2260
    begin
2261
      Font.Size := 30;
2262
      Font.Color := clOlive;
2263
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2264
      Font.Color := clYellow;
2265
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2266
    end;
2267
    BlinkUpdate;
2268
    Release;
2269
  end;
2270
  if isButton1 in DXInput.States then
2271
  begin
2272
    PlaySound('SceneMov', False);
2273
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2274
    Sleep(200);
2275
    StartScene(gsTitle);
2276
  end;
2277
end;
2278
 
2279
procedure TMainForm.SceneWin;
2280
begin
2281
  DXDraw.Surface.Fill(0);
2282
  with DXDraw.Surface.Canvas do
2283
  begin
2284
    FNotSave := true;
2285
    Cheat.enabled := false;
2286
    GamePause.enabled := false;
2287
    Neustart.enabled := false;
2288
    Brush.Style := bsClear;
2289
    Font.Size := 35;
2290
    Font.Color := clMaroon;
2291
    Textout((dxdraw.surfaceWidth div 2)-127, 98, 'Gewonnen!');
2292
    Font.Color := clRed;
2293
    Textout((dxdraw.surfaceWidth div 2)-125, 100, 'Gewonnen!');
2294
    if (FBlink div 300) mod 2=0 then
2295
    begin
2296
      Font.Size := 30;
2297
      Font.Color := clOlive;
2298
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2299
      Font.Color := clYellow;
2300
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2301
    end;
2302
    BlinkUpdate;
2303
    Release;
2304
  end;
2305
  if isButton1 in DXInput.States then
2306
  begin
2307
    PlaySound('SceneMov', False);
2308
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2309
    Sleep(200);
2310
    StartScene(gsTitle);
2311
  end;
2312
end;
2313
 
2314
procedure TMainForm.StartSceneNewLevel;
2315
begin
2316
  sleep(500);
2317
  FNotSave := false;
2318
  Cheat.enabled := false;
2319
  Neustart.enabled := false;
2320
  GamePause.enabled := false;
2321
  GameStart.enabled := true;
2322
  Spielgeschwindigkeit.enabled := false;
2323
  BossExists := false;
2324
  Spielgeschwindigkeit.enabled := false;
2325
  if ((FMenuItem=1) and (not fileexists(FDirectory+'Levels\Level '+inttostr(FLevel)+'.lev'))) or ((FMenuItem=2) and (FLevel > 25)) then
2326
  begin
2327
    //PlaySound('SceneMov', False);
2328
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2329
    Sleep(200);
2330
    StartScene(gsWin);
2331
    exit;
2332
  end;
2333
  PlayMusic(mtScene);
2334
end;
2335
 
2336
procedure TMainForm.EndSceneNewLevel;
2337
begin
2338
  {  Ende NewLevel  }
2339
end;
2340
 
2341
procedure TMainForm.SceneNewLevel;
2342
begin
2343
  DXDraw.Surface.Fill(0);
2344
  with DXDraw.Surface.Canvas do
2345
  begin
2346
    Brush.Style := bsClear;
2347
    Font.Size := 40;
2348
    Font.Color := clMaroon;
2349
    Textout((dxdraw.surfaceWidth div 2)-(83+(length(inttostr(flevel))*22)), 98, 'Level '+inttostr(flevel));
2350
    Font.Color := clRed;
2351
    Textout((dxdraw.surfaceWidth div 2)-(81+(length(inttostr(flevel))*22)), 100, 'Level '+inttostr(flevel));
2352
    if (FBlink div 300) mod 2=0 then
2353
    begin
2354
      Font.Size := 30;
2355
      Font.Color := clOlive;
2356
      Textout((dxdraw.surfaceWidth div 2)-187, dxdraw.surfaceheight-117, 'Weiter mit Leertaste');
2357
      Font.Color := clYellow;
2358
      Textout((dxdraw.surfaceWidth div 2)-185, dxdraw.surfaceheight-115, 'Weiter mit Leertaste');
2359
    end;
2360
    BlinkUpdate;
2361
    Release;
2362
  end;
2363
  if isButton1 in DXInput.States then
2364
  begin
2365
    PlaySound('SceneMov', False);
2366
    PalleteAnim(RGBQuad(0, 0, 0), 300);
2367
    Sleep(200);
2368
    StartScene(gsMain);
2369
  end;
2370
end;
2371
 
2372
procedure TMainForm.OptionMusicClick(Sender: TObject);
2373
begin
2374
  OptionMusic.Checked := not OptionMusic.Checked;
2375
  if OptionMusic.Checked then
2376
  begin
2377
    PlayMusic(FMusic)
2378
  end
2379
  else
2380
  begin
2381
    DestroyMusic(FMusic);
2382
  end;
2383
  WriteOptions;
2384
end;
2385
 
2386
procedure TMainForm.MasterClick(Sender: TObject);
2387
begin
2388
  master.checked := true;
2389
  FInterval := giMaster;
2390
  writeoptions;
2391
end;
2392
 
2393
procedure TEnemyMeteor.DoMove(MoveCount: Integer);
2394
begin
2395
  X := X - MoveCount*(250/1000);
2396
  if X < -Width then Dead;
2397
end;
2398
 
2399
procedure TEnemyMeteor.HitEnemy(ADead: Boolean);
2400
begin
7 daniel-mar 2401
  inherited HitEnemy(False);
2402
 
3 daniel-mar 2403
  if ADead then Collisioned := True;
2404
end;
2405
 
2406
{procedure TMainForm.StopMusic;
2407
begin
2408
  PauseMusic(FMusic);
2409
  MCISendString(pchar('seek "'+FDirectory+'Musik\Boss.mid" to start'), nil, 255, 0);
2410
  MCISendString(pchar('seek "'+FDirectory+'Musik\Game.mid" to start'), nil, 255, 0);
2411
  MCISendString(pchar('seek "'+FDirectory+'Musik\Title.mid" to start'), nil, 255, 0);
2412
  MCISendString(pchar('seek "'+FDirectory+'Musik\Scene.mid" to start'), nil, 255, 0);
2413
end;}
2414
 
2415
procedure TMainForm.ResumeMusic(Name: TMusicTrack);
2416
begin
2417
  if not OptionMusic.checked then exit;
2418
  if Name = mtBoss then
2419
    MCISendString(pchar('play "'+FDirectory+'Musik\Boss.mid"'), nil, 255, 0);
2420
  if Name = mtGame then
2421
    MCISendString(pchar('play "'+FDirectory+'Musik\Game.mid"'), nil, 255, 0);
2422
  if Name = mtScene then
2423
    MCISendString(pchar('play "'+FDirectory+'Musik\Scene.mid"'), nil, 255, 0);
2424
  if Name = mtTitle then
2425
    MCISendString(pchar('play "'+FDirectory+'Musik\Title.mid"'), nil, 255, 0);
2426
end;
2427
 
7 daniel-mar 2428
constructor TEnemyMeteor.Create(AParent: TSprite; ALifes: integer);
3 daniel-mar 2429
begin
7 daniel-mar 2430
  inherited Create(AParent, ALifes);
3 daniel-mar 2431
  Image := MainForm.ImageList.Items.Find('Enemy-Meteor');
2432
  Width := Image.Width;
2433
  Height := Image.Height;
2434
  AnimCount := Image.PatternCount;
2435
  AnimLooped := True;
4 daniel-mar 2436
  AnimSpeed := DEFAULT_ANIMSPEED;
3 daniel-mar 2437
  PixelCheck := True;
2438
end;
2439
 
2440
procedure TMainForm.SpielstandClick(Sender: TObject);
2441
begin
2442
  speicherungform.showmodal;
2443
end;
2444
 
2445
procedure TMainForm.NeustartClick(Sender: TObject);
2446
begin
2447
  FLife := Lives;
2448
  FLevel := 1; // ???
2449
  FScore := 0;
7 daniel-mar 2450
  EnemyCounter := 0;
3 daniel-mar 2451
  StartScene(gsMain);
2452
  PlayMusic(mtGame);
2453
end;
2454
 
2455
procedure TMainForm.OptionBreitbildClick(Sender: TObject);
2456
begin
2457
  OptionBreitbild.Checked := not OptionBreitbild.Checked;
2458
  DXInit;
2459
  writeoptions;
2460
end;
2461
 
2462
procedure TMainForm.LeichtClick(Sender: TObject);
2463
begin
2464
  leicht.checked := true;
2465
  FInterval := giLeicht;
2466
  writeoptions;
2467
end;
2468
 
2469
procedure TMainForm.MittelClick(Sender: TObject);
2470
begin
2471
  mittel.checked := true;
2472
  FInterval := giMittel;
2473
  writeoptions;
2474
end;
2475
 
2476
procedure TMainForm.SchwerClick(Sender: TObject);
2477
begin
2478
  schwer.checked := true;
2479
  FInterval := giSchwer;
2480
  writeoptions;
2481
end;
2482
 
2483
procedure TMainForm.FormShow(Sender: TObject);
2484
begin
7 daniel-mar 2485
  if Assigned(SplashForm) then
2486
  begin
2487
    SplashForm.Hide;
2488
    FreeAndNil(SplashForm);
2489
  end;
3 daniel-mar 2490
 
2491
  dxtimer.Enabled := true;
2492
  dxtimer.ActiveOnly := true;
2493
end;
2494
 
2495
procedure TMainForm.InformationenClick(Sender: TObject);
2496
begin
2497
  dxtimer.enabled := false;
2498
  InfoForm.showmodal;
2499
  if not mainform.gamepause.checked then mainform.dxtimer.enabled := true;
2500
end;
2501
 
2502
procedure TMainForm.CheatClick(Sender: TObject);
2503
begin
2504
  CheatForm.showmodal;
2505
end;
2506
 
2507
procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
2508
begin
2509
  if optionMusic.checked then DestroyMusic(FMusic);
2510
  SpriteEngine.Engine.Clear;
2511
  dxsound.Finalize;
2512
  dxinput.Destroy;
2513
  DXTimer.Enabled := False;
2514
end;
2515
 
2516
procedure TMainForm.FormDestroy(Sender: TObject);
2517
begin
7 daniel-mar 2518
  imagelist.Free;
2519
  spriteengine.Free;
3 daniel-mar 2520
  dxdraw.Free;
7 daniel-mar 2521
  wavelist.Free;
2522
  dxsound.Free;
2523
  //dxinput.Free;
3 daniel-mar 2524
  dxtimer.Free;
7 daniel-mar 2525
  DeleteCriticalSection(TimerCS);
3 daniel-mar 2526
end;
2527
 
2528
end.
2529