Subversion Repositories spacemission

Rev

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