Subversion Repositories spacemission

Rev

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