Changeset 26 for trunk/UCore.pas


Ignore:
Timestamp:
Sep 29, 2011, 8:54:28 PM (13 years ago)
Author:
george
Message:
  • Fixed: Wrong shooting through walls.
  • Added: Clearing dirt before tank during digging.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UCore.pas

    r25 r26  
    1313  MaxBulletCount = 10;
    1414  EnergySteps = 4000;
     15  EnergyDecreaseDig = 0.001;
    1516  ShieldSteps = 40;
    1617  ExplosionBulletCount = 100;
     
    2021  BulletExplosionRange = 3;
    2122  ShootDelay = 0.2; // seconds
     23  DigDelay = 0.2; // seconds
     24  ShootDigDelay = 0.005; // seconds
    2225  ShootEnergyDecrease = 0.01;
     26  PlayerFrameWidth = 80;
     27  PlayerFrameHeight = 80;
     28  PlayerHouseSize = 30;
     29  PlayerHouseDoorSize = 8;
    2330
    2431type
     
    5966  end;
    6067
    61   TMatterIndex = (miSpace, miDirt1, miDirt2, miRock, miBullet1, miBullet2,
     68  TMatterIndex = (miSpace, miDirt1, miDirt2, miRock, miBullet1, miBullet2, miBorder,
    6269    miPlayer1Cannon, miPlayer1Home, miPlayer1TankBody, miPlayer1TankBody2,
    6370    miPlayer2Cannon, miPlayer2Home, miPlayer2TankBody, miPlayer2TankBody2,
     
    7077
    7178  TMatterKind = (mkSpace, mkDirt, mkRock, mkBullet, mkTankBody,
    72     mkHome);
     79    mkHome, mkBorder);
    7380
    7481  { TPlayer }
     
    8491    function ShowTankProc(Item1, Item2: Byte): Byte;
    8592    function HideTankProc(Item1, Item2: Byte): Byte;
     93    function DigProc(Item1, Item2: Byte): Byte;
    8694  public
    8795    Id: Integer;
     
    96104    Bullets: TListObject; // TListObject<TBullet>
    97105    LastShootTime: TDateTime;
     106    LastDigTime: TDateTime;
    98107    Energy: Real;
    99108    LastEnergy: Real;
     
    176185    IntfImage: TLazIntfImage;
    177186    ClearBackground: Boolean;
     187    procedure InitDigMasks;
    178188    procedure SetActive(const AValue: Boolean);
    179189    procedure SetBitmap(const AValue: TBitmap);
     
    187197    PlayerPool: TListObject; // TListObject<TPlayer>
    188198    Players: TListObject; // TListObject<TPlayer>
     199    DigMasks: TListObject; // TListObject<TMatrixByte>
    189200    Lock: TCriticalSection;
    190201    constructor Create;
     
    207218    (X: 0; Y: 1), (X: -1; Y: 1), (X: -1; Y: 0), (X: -1; Y: -1));
    208219
    209 function SwapBRComponent(Value: Integer): Integer; inline;
     220function SwapBRComponent(Value: Cardinal): Cardinal; inline;
    210221
    211222
     
    216227
    217228
    218 function SwapBRComponent(Value: Integer): Integer;
     229function SwapBRComponent(Value: Cardinal): Cardinal; inline;
    219230begin
    220231//  Result := (Value and $00ff00) or ((Value shr 16) and $ff) or ((Value and $ff) shl 16);
     
    326337    Kind := mkBullet;
    327338    Color := clRed;
     339    Player := -1;
     340  end;
     341  // Border
     342  with TMatter(Matter.AddNew(TMatter.Create)) do begin
     343    Kind := mkBorder;
     344    Color := clNavy;
    328345    Player := -1;
    329346  end;
     
    667684    HideTank;
    668685    Matter := CheckColision;
    669     if (Matter = miDirt1) then Dig := not Dig;
    670     if (Matter = miSpace) or ((Matter = miDirt1) and (not Dig)) then begin
     686    if (Matter = miDirt1) and (
     687    (Engine.KeyBoard.KeyState[Ord(Keys.Shoot)] and
     688    ((Now - LastDigTime) > ShootDigDelay * OneSecond)) or
     689    (not Engine.KeyBoard.KeyState[Ord(Keys.Shoot)] and
     690    ((Now - LastDigTime) > DigDelay * OneSecond))) then begin
     691      Dig := not Dig;
     692      with Engine, World do
     693      Surface.Merge(Surface.CreateIndex(
     694        Position.X - TMatrixByte(DigMasks[Direction]).Count.X div 2,
     695        Position.Y - TMatrixByte(DigMasks[Direction]).Count.Y div 2),
     696        TMatrixByte(DigMasks[Direction]), DigProc);
     697      Energy := Energy - EnergyDecreaseDig;
     698      if Energy < 0 then Energy := 0;
     699      Engine.Redraw;
     700      LastDigTime := Now;
     701      Direction := NewDirection;
     702    end;
     703    if (Matter = miSpace) then begin
    671704      Position := NewPosition;
    672705      Direction := NewDirection;
     
    681714      NewBullet := TBullet.Create;
    682715      NewBullet.Player := Self;
    683       NewBullet.Position.X := Position.X + DirectionToDelta[Direction].X * 4;
    684       NewBullet.Position.Y := Position.Y + DirectionToDelta[Direction].Y * 4;
     716      NewBullet.Position.X := Position.X + DirectionToDelta[Direction].X * 3;
     717      NewBullet.Position.Y := Position.Y + DirectionToDelta[Direction].Y * 3;
    685718      NewBullet.Direction.X := DirectionToDelta[Direction].X;
    686719      NewBullet.Direction.Y := DirectionToDelta[Direction].Y;
     
    807840//    FillRect(ScreenFrame);
    808841    Fill(CreateIndex(ScreenFrame.Left, ScreenFrame.Top),
    809       CreateIndex(ScreenFrame.Right - 1, ScreenFrame.Bottom - 1),
     842      CreateIndex(ScreenFrame.Right, ScreenFrame.Bottom),
    810843      TMatter(Engine.World.Matter[Integer(miRock)]).Color);
    811844
     
    834867
    835868procedure TPlayer.PlaceHouse;
    836 const
    837   HouseSize = 30;
    838   DoorSize = 8;
    839869var
    840870  X, Y: Integer;
    841871  Matter: Byte;
    842872begin
    843   House.AsTRect := Rect(Position.X - HouseSize div 2, Position.Y - HouseSize div 2,
    844     Position.X + HouseSize div 2, Position.Y + HouseSize div 2);
    845   for Y := 0 to HouseSize - 1 do
    846     for X := 0 to HouseSize - 1 do begin
    847       if ((Y = 0) or (Y = (HouseSize - 1)) or (X = 0) or (X = (HouseSize - 1))) and
    848       not (((Y = 0) or (Y = (HouseSize - 1))) and (X > ((HouseSize - DoorSize) div 2)) and
    849       (X < ((HouseSize - 1 + DoorSize) div 2)))
     873  House.AsTRect := Rect(Position.X - PlayerHouseSize div 2, Position.Y - PlayerHouseSize div 2,
     874    Position.X + PlayerHouseSize div 2, Position.Y + PlayerHouseSize div 2);
     875  for Y := 0 to PlayerHouseSize - 1 do
     876    for X := 0 to PlayerHouseSize - 1 do begin
     877      if ((Y = 0) or (Y = (PlayerHouseSize - 1)) or (X = 0) or (X = (PlayerHouseSize - 1))) and
     878      not (((Y = 0) or (Y = (PlayerHouseSize - 1))) and (X > ((PlayerHouseSize - PlayerHouseDoorSize) div 2)) and
     879      (X < ((PlayerHouseSize - 1 + PlayerHouseDoorSize) div 2)))
    850880      then Matter := Byte(miPlayer1Home) + Id * 4
    851881        else Matter := Byte(miSpace);
     
    907937begin
    908938  if Item2 > 0 then Result := 0 else Result := Item1;
     939end;
     940
     941function TPlayer.DigProc(Item1, Item2: Byte): Byte;
     942begin
     943  if ((Item1 = Integer(miDirt1)) or (Item1 = Integer(miDirt2))) and (Item2 = 1) then
     944    Result := Integer(miSpace) else Result := Item1;
    909945end;
    910946
     
    11261162  TargetHeight: Integer;
    11271163  TargetWidth: Integer;
     1164  BgColor: Cardinal;
    11281165begin
    11291166  if Assigned(FBitmap) then
     
    11341171    BytePerRow := RawImage.Description.BytesPerLine;
    11351172    if ClearBackground then begin
    1136       FillChar(RawImage.Data^, Bitmap.Height * BytePerRow, 0);
     1173      BgColor := TMatter(World.Matter[Integer(miBorder)]).Color;
     1174      BgColor := SwapBRComponent(BgColor);
     1175      FillDWord(RawImage.Data^, Bitmap.Height * BytePerRow div 4, BgColor);
    11371176      ClearBackground := False;
    11381177    end;
     
    11951234end;
    11961235
     1236procedure TEngine.InitDigMasks;
     1237var
     1238  NewMask: TMatrixByte;
     1239  I: Integer;
     1240  X, Y: Integer;
     1241begin
     1242  DigMasks.Clear;
     1243
     1244  // 001111100
     1245  // 0111A1110
     1246  // 00z1A1z00
     1247  // 00zxAxz00
     1248  // 00zxAxz00
     1249  // 00zxxxz00
     1250  // 00z000z00
     1251  // 000000000
     1252  // 000000000
     1253
     1254  NewMask := TMatrixByte.Create;
     1255  with NewMask do begin
     1256    Count := CreateIndex(9, 9);
     1257    for I := 0 to 4 do ItemsXY[2 + I, 0] := 1;
     1258    for I := 0 to 2 do begin
     1259      ItemsXY[1 + I, 1] := 1;
     1260      ItemsXY[5 + I, 1] := 1;
     1261    end;
     1262    ItemsXY[3, 2] := 1;
     1263    ItemsXY[5, 2] := 1;
     1264  end;
     1265  DigMasks.Add(NewMask);
     1266
     1267  // 000011110
     1268  // 0000z1111
     1269  // 000zx1A11
     1270  // 00zxxA111
     1271  // 0zxxAxxz1
     1272  // 000xxxz00
     1273  // 0000xz000
     1274  // 0000z0000
     1275  // 000000000
     1276
     1277  NewMask := TMatrixByte.Create;
     1278  with NewMask do begin
     1279    Count := CreateIndex(9, 9);
     1280    for I := 0 to 3 do begin
     1281      ItemsXY[4 + I, 0] := 1;
     1282      ItemsXY[5 + I, 1] := 1;
     1283    end;
     1284    ItemsXY[5, 2] := 1;
     1285    ItemsXY[7, 2] := 1;
     1286    ItemsXY[8, 2] := 1;
     1287    for I := 0 to 2 do
     1288      ItemsXY[6 + I, 3] := 1;
     1289    ItemsXY[8, 4] := 1;
     1290  end;
     1291  DigMasks.Add(NewMask);
     1292
     1293  NewMask := TMatrixByte.Create;
     1294  NewMask.Assign(TMatrixByte(DigMasks[0]));
     1295  NewMask.Reverse;
     1296  NewMask.ReverseHorizontal;
     1297  DigMasks.Add(NewMask);
     1298
     1299  NewMask := TMatrixByte.Create;
     1300  NewMask.Assign(TMatrixByte(DigMasks[1]));
     1301  NewMask.ReverseVertical;
     1302  DigMasks.Add(NewMask);
     1303
     1304  NewMask := TMatrixByte.Create;
     1305  NewMask.Assign(TMatrixByte(DigMasks[0]));
     1306  NewMask.ReverseVertical;
     1307  DigMasks.Add(NewMask);
     1308
     1309  NewMask := TMatrixByte.Create;
     1310  NewMask.Assign(TMatrixByte(DigMasks[1]));
     1311  NewMask.ReverseVertical;
     1312  NewMask.ReverseHorizontal;
     1313  DigMasks.Add(NewMask);
     1314
     1315  NewMask := TMatrixByte.Create;
     1316  NewMask.Assign(TMatrixByte(DigMasks[0]));
     1317  NewMask.Reverse;
     1318  DigMasks.Add(NewMask);
     1319
     1320  NewMask := TMatrixByte.Create;
     1321  NewMask.Assign(TMatrixByte(DigMasks[1]));
     1322  NewMask.ReverseHorizontal;
     1323  DigMasks.Add(NewMask);
     1324end;
     1325
    11971326procedure TEngine.InitPlayerPool;
    11981327var
     
    12831412      HorizFrameCount := 1;
    12841413    end;
    1285     FBitmapLower.Count := FBitmapLower.CreateIndex(80 * HorizFrameCount, 60 * VertFrameCount);
     1414    FBitmapLower.Count := FBitmapLower.CreateIndex(PlayerFrameWidth * HorizFrameCount,
     1415      PlayerFrameHeight * VertFrameCount);
    12861416    for I := 0 to Players.Count - 1 do begin
    12871417      TPlayer(Players[I]).ScreenFrame.AsTRect := Rect(
    1288         (I mod HorizFrameCount) * (FBitmapLower.Count.X div HorizFrameCount),
    1289         (I div HorizFrameCount) * (FBitmapLower.Count.Y div VertFrameCount),
     1418        (I mod HorizFrameCount) * (FBitmapLower.Count.X div HorizFrameCount) + 1,
     1419        (I div HorizFrameCount) * (FBitmapLower.Count.Y div VertFrameCount) + 1,
    12901420        ((I mod HorizFrameCount) + 1) * (FBitmapLower.Width div HorizFrameCount),
    12911421        ((I div HorizFrameCount) + 1) * (FBitmapLower.Height div VertFrameCount));
     
    13091439  World.Engine := Self;
    13101440  InitPlayerPool;
     1441  DigMasks := TListObject.Create;
     1442  InitDigMasks;
    13111443  Redraw;
    13121444end;
     
    13151447begin
    13161448  Active := False;
     1449  DigMasks.Free;
    13171450  FBitmapLower.Free;
    13181451  FBitmapLock.Free;
     
    13501483    try
    13511484      Lock.Acquire;
    1352       //FBitmapLower.FillAll(0);
     1485      if ClearBackground then FBitmapLower.FillAll(clNavy);
    13531486      for I := 0 to Players.Count - 1 do begin
    13541487        TPlayer(Players[I]).Paint;
Note: See TracChangeset for help on using the changeset viewer.