Subversion Repositories spacemission

Rev

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

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