Subversion Repositories spacemission

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

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