Subversion Repositories spacemission

Rev

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