Changeset 3 for trunk/UCore.pas
- Timestamp:
- Mar 6, 2011, 12:13:35 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UCore.pas
r2 r3 1 1 unit UCore; 2 2 3 {$mode objfpc}{$H+}3 {$mode Delphi}{$H+} 4 4 5 5 interface 6 6 7 7 uses 8 Dialogs, Classes, SysUtils, Contnrs, Graphics, SpecializedMatrix ;8 Dialogs, Classes, SysUtils, Contnrs, Graphics, SpecializedMatrix, SpecializedList; 9 9 10 10 type 11 11 TEngine = class; 12 12 13 TSurfaceMatter = (smNothing, smDirt1, smDirt2, smRock1, smRock2, smHouse1, smHouse2); 13 TSurfaceMatter = (smNothing, smDirt1, smDirt2, smRock, 14 smPlayer1H, smPlayer1L, smPlayer2H, smPlayer2L, smCannon, smBullet); 14 15 15 16 TPlayerKeys = record … … 21 22 end; 22 23 24 { TTank } 25 26 TTank = class 27 Image: TMatrixByte; 28 Mask: TMatrixByte; 29 constructor Create; 30 destructor Destroy; override; 31 end; 32 23 33 { TPlayer } 24 34 25 35 TPlayer = class 36 private 37 function ShowTankProc(Item1, Item2: Byte): Byte; 38 function HideTankProc(Item1, Item2: Byte): Byte; 39 public 40 Id: Integer; 26 41 Engine: TEngine; 27 Color: TColor;28 42 Position: TPoint; 43 Direction: Integer; 29 44 ScreenFrame: TRect; 30 45 Name: string; 31 46 Keys: TPlayerKeys; 47 Tanks: TListObject; 32 48 procedure Control; 33 49 procedure Paint; 50 procedure PlaceHouse; 51 function CheckColision: Boolean; 52 procedure ShowTank; 53 procedure HideTank; 54 procedure InitTanks; 55 constructor Create; 56 destructor Destroy; override; 34 57 end; 35 58 … … 54 77 private 55 78 FBitmap: TBitmap; 79 FRedrawPending: Boolean; 56 80 function GetPlayerCount: Integer; 57 81 procedure SetBitmap(const AValue: TBitmap); 58 82 procedure SetPlayerCount(const AValue: Integer); 83 procedure Redraw; 59 84 public 60 85 KeyState: array[0..High(Word)] of Boolean; … … 64 89 destructor Destroy; override; 65 90 procedure ResizePlayerFrames; 66 procedure Paint;91 procedure Tick; 67 92 property PlayerCount: Integer read GetPlayerCount write SetPlayerCount; 68 93 property Bitmap: TBitmap read FBitmap write SetBitmap; 94 procedure NewGame; 69 95 end; 70 96 71 97 const 72 SurfaceMatterColors: array[TSurfaceMatter] of TColor = (clBlack, $0756b0, $2170c3, clGray, clGray + $808080, clGreen, clBlue); 98 SurfaceMatterColors: array[TSurfaceMatter] of TColor = (clBlack, $0756b0, 99 $2170c3, TColor($9a9a9a), TColor($00ff00), TColor($00a000), 100 TColor($ff2c2c), TColor($b60000), clYellow, clRed); 73 101 74 102 var … … 76 104 77 105 implementation 106 107 { TTank } 108 109 constructor TTank.Create; 110 begin 111 Mask := TMatrixByte.Create; 112 Image := TMatrixByte.Create; 113 end; 114 115 destructor TTank.Destroy; 116 begin 117 Mask.Free; 118 Image.Free; 119 inherited Destroy; 120 end; 78 121 79 122 { TWorld } … … 97 140 for X := 0 to Surface.Count.X - 1 do begin 98 141 if Random < 0.5 then 99 Surface [Y, X] := Byte(smDirt1) else100 Surface [Y, X] := Byte(smDirt2);142 Surface.ItemsXY[Y, X] := Byte(smDirt1) else 143 Surface.ItemsXY[Y, X] := Byte(smDirt2); 101 144 end; 102 145 end; … … 107 150 begin 108 151 Surface := TMatrixByte.Create; 109 NewSize.X := 5000;110 NewSize.Y := 500;152 NewSize.X := 100; 153 NewSize.Y := 100; 111 154 Size := NewSize; 112 155 end; … … 121 164 122 165 procedure TPlayer.Control; 123 begin 124 if Engine.KeyState[Ord(Keys.Up)] then Position.Y := Position.Y + 1; 125 if Engine.KeyState[Ord(Keys.Down)] then Position.Y := Position.Y - 1; 126 if Engine.KeyState[Ord(Keys.Right)] then Position.X := Position.X + 1; 127 if Engine.KeyState[Ord(Keys.Left)] then Position.X := Position.X - 1; 166 var 167 NewPosition: TPoint; 168 NewDirection: Integer; 169 Delta: TPoint; 170 begin 171 Delta.X := 0; 172 Delta.Y := 0; 173 if Engine.KeyState[Ord(Keys.Up)] then Delta.Y := Delta.Y + 1; 174 if Engine.KeyState[Ord(Keys.Down)] then Delta.Y := Delta.Y - 1; 175 if Engine.KeyState[Ord(Keys.Right)] then Delta.X := Delta.X + 1; 176 if Engine.KeyState[Ord(Keys.Left)] then Delta.X := Delta.X - 1; 177 178 NewDirection := Direction; 179 if (Delta.X <> 0) or (Delta.Y <> 0) then begin 180 if (Delta.X = 0) and (Delta.Y = -1) then NewDirection := 0 181 else if (Delta.X = 1) and (Delta.Y = -1) then NewDirection := 1 182 else if (Delta.X = 1) and (Delta.Y = 0) then NewDirection := 2 183 else if (Delta.X = 1) and (Delta.Y = 1) then NewDirection := 3 184 else if (Delta.X = 0) and (Delta.Y = 1) then NewDirection := 4 185 else if (Delta.X = -1) and (Delta.Y = 1) then NewDirection := 5 186 else if (Delta.X = -1) and (Delta.Y = 0) then NewDirection := 6 187 else if (Delta.X = -1) and (Delta.Y = -1) then NewDirection := 7; 188 end; 189 190 NewPosition := Point(Position.X + Delta.X, Position.Y + Delta.Y); 191 if CheckColision then begin 192 HideTank; 193 Position := NewPosition; 194 Direction := NewDirection; 195 ShowTank; 196 Engine.Redraw; 197 end; 128 198 end; 129 199 … … 136 206 Rectangle(ScreenFrame); 137 207 //FillRect(ScreenFrame); 208 138 209 139 210 with Engine.World do … … 143 214 YY := Y - ScreenFrame.Top - ((ScreenFrame.Bottom - ScreenFrame.Top) div 2) + Position.Y; 144 215 if (YY >= 0) and (YY < Surface.Count.Y) and (XX >= 0) and (XX < Surface.Count.X) then 145 Pixels[X, Y] := SurfaceMatterColors[TSurfaceMatter(Surface [YY, XX])];216 Pixels[X, Y] := SurfaceMatterColors[TSurfaceMatter(Surface.ItemsXY[YY, XX])]; 146 217 end; 218 147 219 (*CopyRect(ScreenFrame, Engine.World.Surface.Canvas, 148 220 Rect( … … 157 229 end; 158 230 231 procedure TPlayer.PlaceHouse; 232 const 233 HouseSize = 30; 234 DoorSize = 8; 235 var 236 X, Y: Integer; 237 Matter: Byte; 238 begin 239 for Y := 0 to HouseSize - 1 do 240 for X := 0 to HouseSize - 1 do begin 241 if ((Y = 0) or (Y = (HouseSize - 1)) or (X = 0) or (X = (HouseSize - 1))) and 242 not (((Y = 0) or (Y = (HouseSize - 1))) and (X > ((HouseSize - DoorSize) div 2)) and 243 (X < ((HouseSize - 1 + DoorSize) div 2))) 244 then Matter := Byte(smPlayer1H) + Id * 2 245 else Matter := Byte(smNothing); 246 Engine.World.Surface.ItemsXY[Position.Y - HouseSize div 2 + Y, Position.X - HouseSize div 2 + X] := Matter; 247 end; 248 end; 249 250 function TPlayer.CheckColision: Boolean; 251 begin 252 253 end; 254 255 function TPlayer.ShowTankProc(Item1, Item2: Byte): Byte; 256 begin 257 if Item2 > 0 then Result := Item2 else Result := Item1; 258 end; 259 260 procedure TPlayer.ShowTank; 261 begin 262 with Engine.World do begin 263 Surface.Merge(TMatrixByte.Point(Position.X, Position.Y), TTank(Tanks[Direction]).Image, ShowTankProc); 264 end; 265 end; 266 267 function TPlayer.HideTankProc(Item1, Item2: Byte): Byte; 268 begin 269 if Item2 > 0 then Result := 0 else Result := Item1; 270 end; 271 272 procedure TPlayer.HideTank; 273 begin 274 with Engine.World do begin 275 Surface.Merge(TMatrixByte.Point(Position.X, Position.Y), TTank(Tanks[Direction]).Image, HideTankProc); 276 end; 277 end; 278 279 procedure TPlayer.InitTanks; 280 var 281 NewTank: TTank; 282 I: Integer; 283 X, Y: Integer; 284 begin 285 Tanks.Clear; 286 287 NewTank := TTank.Create; 288 with NewTank do begin 289 Image.Count := TMatrixByte.Point(7, 7); 290 for I := 0 to 3 do 291 Image[I, 3] := Byte(smCannon); 292 for I := 1 to 6 do begin 293 Image[I, 1] := Byte(smPlayer1H) + Id * 2; 294 Image[I, 5] := Byte(smPlayer1H) + Id * 2; 295 end; 296 for I := 2 to 5 do begin 297 Image[I, 2] := Byte(smPlayer1H) + Id * 2 + 1; 298 Image[I, 4] := Byte(smPlayer1H) + Id * 2 + 1; 299 end; 300 Image[4, 3] := Byte(smPlayer1H) + Id * 2 + 1; 301 Image[5, 3] := Byte(smPlayer1H) + Id * 2 + 1; 302 end; 303 Tanks.Add(NewTank); 304 305 NewTank := TTank.Create; 306 with NewTank do begin 307 Image.Count := TMatrixByte.Point(7, 7); 308 for I := 0 to 2 do 309 Image[3 - I, 3 + I] := Byte(smCannon); 310 for I := 0 to 3 do begin 311 Image[3 - I, I] := Byte(smPlayer1H) + Id * 2; 312 Image[6 - I, 3 + I] := Byte(smPlayer1H) + Id * 2; 313 end; 314 for I := 0 to 2 do begin 315 Image[3 - I, 1 + I] := Byte(smPlayer1H) + Id * 2 + 1; 316 Image[5 - I, 3 + I] := Byte(smPlayer1H) + Id * 2 + 1; 317 end; 318 Image[2, 3] := Byte(smPlayer1H) + Id * 2 + 1; 319 Image[3, 2] := Byte(smPlayer1H) + Id * 2 + 1; 320 Image[4, 2] := Byte(smPlayer1H) + Id * 2 + 1; 321 Image[4, 3] := Byte(smPlayer1H) + Id * 2 + 1; 322 Image[3, 4] := Byte(smPlayer1H) + Id * 2 + 1; 323 end; 324 Tanks.Add(NewTank); 325 326 NewTank := TTank.Create; 327 NewTank.Image.Assign(TTank(Tanks[0]).Image); 328 NewTank.Image.Reverse; 329 NewTank.Image.ReverseHorizontal; 330 Tanks.Add(NewTank); 331 332 NewTank := TTank.Create; 333 NewTank.Image.Assign(TTank(Tanks[1]).Image); 334 NewTank.Image.ReverseVertical; 335 Tanks.Add(NewTank); 336 337 NewTank := TTank.Create; 338 NewTank.Image.Assign(TTank(Tanks[0]).Image); 339 NewTank.Image.ReverseVertical; 340 Tanks.Add(NewTank); 341 342 NewTank := TTank.Create; 343 NewTank.Image.Assign(TTank(Tanks[1]).Image); 344 NewTank.Image.ReverseVertical; 345 NewTank.Image.ReverseHorizontal; 346 Tanks.Add(NewTank); 347 348 NewTank := TTank.Create; 349 NewTank.Image.Assign(TTank(Tanks[0]).Image); 350 NewTank.Image.Reverse; 351 Tanks.Add(NewTank); 352 353 NewTank := TTank.Create; 354 NewTank.Image.Assign(TTank(Tanks[1]).Image); 355 NewTank.Image.ReverseHorizontal; 356 Tanks.Add(NewTank); 357 358 for I := 0 to Tanks.Count - 1 do 359 with TTank(Tanks[I]) do begin 360 Mask.Assign(Image); 361 for Y := 0 to Mask.Count.Y - 1 do 362 for X := 0 to Mask.Count.X - 1 do 363 if Mask.ItemsXY[X, Y] > 0 then Mask.ItemsXY[X, Y] := 1; 364 end; 365 end; 366 367 constructor TPlayer.Create; 368 begin 369 Tanks := TListObject.Create; 370 end; 371 372 destructor TPlayer.Destroy; 373 begin 374 Tanks.Free; 375 inherited Destroy; 376 end; 377 159 378 { TEngine } 160 379 … … 179 398 NewPlayer := TPlayer.Create; 180 399 NewPlayer.Engine := Self; 400 NewPlayer.Id := I; 181 401 NewPlayer.Name := 'Player ' + IntToStr(I); 402 NewPlayer.InitTanks; 182 403 Players.Add(NewPlayer); 183 404 end; … … 188 409 end; 189 410 ResizePlayerFrames; 411 end; 412 413 procedure TEngine.Redraw; 414 begin 415 FRedrawPending := True; 190 416 end; 191 417 … … 224 450 end; 225 451 226 procedure TEngine. Paint;452 procedure TEngine.Tick; 227 453 var 228 454 I: Integer; 229 455 begin 230 if Assigned(Bitmap) then begin 231 Bitmap.Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height); 232 for I := 0 to Players.Count - 1 do begin 233 TPlayer(Players[I]).Control; 234 TPlayer(Players[I]).Paint; 235 end; 456 for I := 0 to Players.Count - 1 do begin 457 TPlayer(Players[I]).Control; 458 end; 459 460 if FRedrawPending then begin 461 if Assigned(Bitmap) then begin 462 Bitmap.Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height); 463 for I := 0 to Players.Count - 1 do begin 464 TPlayer(Players[I]).Control; 465 TPlayer(Players[I]).Paint; 466 end; 467 end; 468 FRedrawPending := False; 469 end; 470 end; 471 472 procedure TEngine.NewGame; 473 var 474 I: Integer; 475 I2: Integer; 476 begin 477 World.Generate; 478 479 for I := 0 to Players.Count - 1 do 480 with TPlayer(Players[I]) do 481 begin 482 // Reset position 483 Position := Point(25 + Random(World.Surface.Count.X - 50), 484 25 + Random(World.Surface.Count.Y - 50)); 485 486 PlaceHouse; 236 487 end; 237 488 end;
Note:
See TracChangeset
for help on using the changeset viewer.