Changeset 23 for trunk/UCore.pas


Ignore:
Timestamp:
Sep 28, 2011, 8:34:06 PM (13 years ago)
Author:
george
Message:
  • Added: Introduced player pool for selection of players for new game.
  • Fixed: Deadlock on program exit during threads termination.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UCore.pas

    r22 r23  
    88  Dialogs, Classes, SysUtils, Contnrs, Graphics, SpecializedMatrix, SpecializedList,
    99  IntfGraphics, FPImage, LCLType, SpecializedBitmap, GraphType, Math, URectangle,
    10   Syncobjs, UThreading;
     10  Syncobjs, UThreading, Forms;
    1111
    1212const
     
    173173    IntfImage: TLazIntfImage;
    174174    ClearBackground: Boolean;
    175     function GetPlayerCount: Integer;
    176175    procedure SetActive(const AValue: Boolean);
    177176    procedure SetBitmap(const AValue: TBitmap);
    178     procedure SetPlayerCount(const AValue: Integer);
    179177    procedure Redraw;
    180178    function IsInsideHouses(Pos: TPoint): Boolean;
    181179    procedure DoDrawToBitmap;
     180    procedure InitPlayerPool;
    182181  public
    183182    Keyboard: TKeyboard;
    184183    World: TWorld;
     184    PlayerPool: TListObject; // TListObject<TPlayer>
    185185    Players: TListObject; // TListObject<TPlayer>
    186186    Lock: TCriticalSection;
     
    189189    procedure ResizePlayerFrames;
    190190    procedure Tick;
    191     procedure Draw;
     191    procedure Draw(Thread: TVirtualThread);
    192192    procedure NewGame;
    193     property PlayerCount: Integer read GetPlayerCount write SetPlayerCount;
    194193    property Bitmap: TBitmap read FBitmap write SetBitmap;
    195194    property Active: Boolean read FActive write SetActive;
     
    213212implementation
    214213
     214resourcestring
     215  SPlayer = 'Player';
     216
     217
    215218function SwapBRComponent(Value: Integer): Integer;
    216219begin
     
    236239begin
    237240  repeat
    238     Engine.Draw;
     241    Engine.Draw(Self);
    239242    Sleep(50);
    240243  until Terminated;
     
    589592var
    590593  I: Integer;
     594  P: Integer;
    591595  Pos: TPoint;
    592596  D: Real;
     
    660664          end;
    661665        end else begin
    662           if (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer1TankBody)) or
    663           (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer1TankBody2)) then
    664             with TPlayer(Engine.Players[0]) do begin
    665               Shield := Shield - 1 / ShieldSteps;
    666             end;
    667           if (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer2Tankbody)) or
    668           (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer2TankBody2)) then
    669             with TPlayer(Engine.Players[1]) do begin
    670               Shield := Shield - 1 / ShieldSteps;
    671             end;
    672           if (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer3TankBody)) or
    673           (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer3TankBody2)) then
    674             with TPlayer(Engine.Players[2]) do begin
    675               Shield := Shield - 1 / ShieldSteps;
    676             end;
    677           if (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer4TankBody)) or
    678           (ItemsXY[Pos.X, Pos.Y] = Byte(miPlayer4TankBody2)) then
    679             with TPlayer(Engine.Players[3]) do begin
    680               Shield := Shield - 1 / ShieldSteps;
    681             end;
     666          for P := 0 to Engine.Players.Count - 1 do
     667          with TPlayer(Engine.Players[P]) do
     668          if Enabled and (TMatter(Engine.World.Matter[ItemsXY[Pos.X, Pos.Y]]).Kind = mkTankBody) then
     669            Shield := Shield - 1 / ShieldSteps;
    682670          if StopByDirt then Explosion(LastPos, BulletExplosionRange);
    683671          Bullets.Delete(I);
     
    753741      not (((Y = 0) or (Y = (HouseSize - 1))) and (X > ((HouseSize - DoorSize) div 2)) and
    754742      (X < ((HouseSize - 1 + DoorSize) div 2)))
    755       then Matter := Byte(miPlayer1Cannon) + Id * 4
     743      then Matter := Byte(miPlayer1Home) + Id * 4
    756744        else Matter := Byte(miSpace);
    757745      Engine.World.Surface.ItemsXY[House.Left + X,
     
    965953{ TEngine }
    966954
    967 function TEngine.GetPlayerCount: Integer;
    968 begin
    969   Result := Players.Count;
    970 end;
    971 
    972955procedure TEngine.SetActive(const AValue: Boolean);
    973956begin
     
    986969    FSystemThread.Start;
    987970  end else begin
     971    FDrawThread.Terminate;
     972    Application.ProcessMessages;
    988973    FreeAndNil(FDrawThread);
    989974    FreeAndNil(FSystemThread);
     
    994979begin
    995980  FBitmap := AValue;
    996   ResizePlayerFrames;
    997 end;
    998 
    999 procedure TEngine.SetPlayerCount(const AValue: Integer);
    1000 var
    1001   NewPlayer: TPlayer;
    1002   I: Integer;
    1003 begin
    1004   if Players.Count < AValue then begin
    1005     for I := Players.Count to AValue - 1 do begin
    1006       NewPlayer := TPlayer.Create;
    1007       NewPlayer.Engine := Self;
    1008       NewPlayer.Id := I;
    1009       NewPlayer.Name := 'Player ' + IntToStr(I);
    1010       NewPlayer.InitTanks;
    1011       Players.Add(NewPlayer);
    1012     end;
    1013   end else
    1014   if Players.Count > AValue then begin
    1015     for I := Players.Count - 1 downto AValue do
    1016       Players.Delete(I);
    1017   end;
    1018981  ResizePlayerFrames;
    1019982end;
     
    11251088end;
    11261089
     1090procedure TEngine.InitPlayerPool;
     1091var
     1092  I: Integer;
     1093begin
     1094  PlayerPool.Clear;
     1095  with TPlayer(PlayerPool.AddNew(TPlayer.Create)) do begin
     1096    Keys.Left := 65;
     1097    Keys.Down := 83;
     1098    Keys.Right := 68;
     1099    Keys.Up := 87;
     1100    Keys.Shoot := 69;
     1101    Enabled := True;
     1102  end;
     1103  with TPlayer(PlayerPool.AddNew(TPlayer.Create)) do begin
     1104    Keys.Left := 37;
     1105    Keys.Down := 40;
     1106    Keys.Right := 39;
     1107    Keys.Up := 38;
     1108    Keys.Shoot := 17;
     1109    Enabled := True;
     1110  end;
     1111  with TPlayer(PlayerPool.AddNew(TPlayer.Create)) do begin
     1112    Keys.Left := 76;
     1113    Keys.Down := 186;
     1114    Keys.Right := 222;
     1115    Keys.Up := 80;
     1116    Keys.Shoot := 191;
     1117  end;
     1118  with TPlayer(PlayerPool.AddNew(TPlayer.Create)) do begin
     1119    Keys.Left := 100;
     1120    Keys.Down := 98;
     1121    Keys.Right := 102;
     1122    Keys.Up := 104;
     1123    Keys.Shoot := 105;
     1124  end;
     1125  for I := 0 to PlayerPool.Count - 1 do
     1126  with TPlayer(PlayerPool[I]) do begin
     1127    Engine := Self;
     1128    Id := I;
     1129    InitTanks;
     1130    Name := SPlayer + ' ' + IntToStr(I + 1);
     1131  end;
     1132end;
     1133
    11271134procedure TEngine.ResizePlayerFrames;
    11281135var
     
    11591166  FBitmapLock := TCriticalSection.Create;
    11601167  IntfImage := TLazIntfImage.Create(1, 1);
     1168  PlayerPool := TListObject.Create;
    11611169  Players := TListObject.Create;
     1170  Players.OwnsObjects := False;
    11621171  Keyboard := TKeyboard.Create;
    11631172  World := TWorld.Create;
    11641173  World.Engine := Self;
     1174  InitPlayerPool;
    11651175  Redraw;
    11661176end;
     
    11721182  FBitmapLock.Free;
    11731183  IntfImage.Free;
     1184  PlayerPool.Free;
    11741185  Players.Free;
    11751186  Keyboard.Free;
     
    11941205end;
    11951206
    1196 procedure TEngine.Draw;
     1207procedure TEngine.Draw(Thread: TVirtualThread);
    11971208var
    11981209  I: Integer;
     
    12101221      Lock.Release;
    12111222    end;
    1212     Synchronize(DoDrawToBitmap);
     1223    if not Thread.Terminated then Thread.Synchronize(DoDrawToBitmap);
    12131224  end;
    12141225end;
     
    12191230  I2: Integer;
    12201231begin
     1232  Players.Clear;
     1233  for I := 0 to PlayerPool.Count - 1 do
     1234  with TPlayer(PlayerPool[I]) do
     1235  if Enabled then
     1236    Players.Add(PlayerPool[I]);
     1237  ResizePlayerFrames;
     1238
    12211239  World.Generate;
    12221240
     
    12271245end;
    12281246
    1229 initialization
    1230 
    1231 Engine := TEngine.Create;
    1232 
    1233 finalization
    1234 
    1235 Engine.Free;
    1236 
    12371247end.
    12381248
Note: See TracChangeset for help on using the changeset viewer.