Subversion Repositories spacemission

Rev

Rev 22 | Rev 24 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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