Changeset 4 for trunk/UCore.pas
- Timestamp:
- Mar 6, 2011, 6:43:01 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UCore.pas
r3 r4 8 8 Dialogs, Classes, SysUtils, Contnrs, Graphics, SpecializedMatrix, SpecializedList; 9 9 10 const 11 MaxBulletCount = 10; 12 10 13 type 11 14 TEngine = class; 12 13 TSurfaceMatter = (smNothing, smDirt1, smDirt2, smRock, 14 smPlayer1H, smPlayer1L, smPlayer2H, smPlayer2L, smCannon, smBullet); 15 TPlayer = class; 16 17 TSurfaceMatter = (smNothing, smDirt1, smDirt2, smRock, smCannon, smBullet, 18 smPlayer1H, smPlayer1L, smPlayer2H, smPlayer2L, 19 smPlayer3H, smPlayer3L, smPlayer4H, smPlayer4L); 15 20 16 21 TPlayerKeys = record … … 22 27 end; 23 28 29 TBullet = class 30 Player: TPlayer; 31 Position: TPoint; 32 Direction: Integer; 33 end; 34 24 35 { TTank } 25 36 … … 35 46 TPlayer = class 36 47 private 48 NewDirection: Integer; 49 NewPosition: TPoint; 50 Dig: Boolean; 37 51 function ShowTankProc(Item1, Item2: Byte): Byte; 38 52 function HideTankProc(Item1, Item2: Byte): Byte; … … 46 60 Keys: TPlayerKeys; 47 61 Tanks: TListObject; 62 Bullets: TListObject; 48 63 procedure Control; 49 64 procedure Paint; 50 65 procedure PlaceHouse; 51 function CheckColision: Boolean;66 function CheckColision: TSurfaceMatter; 52 67 procedure ShowTank; 53 68 procedure HideTank; … … 69 84 constructor Create; 70 85 destructor Destroy; override; 86 procedure DrawToBitmap(Bitmap: TBitmap); 71 87 property Size: TMatrixByteIndex read GetSize write SetSize; 72 88 end; … … 78 94 FBitmap: TBitmap; 79 95 FRedrawPending: Boolean; 96 FBitmapLower: TBitmap; 80 97 function GetPlayerCount: Integer; 81 98 procedure SetBitmap(const AValue: TBitmap); … … 90 107 procedure ResizePlayerFrames; 91 108 procedure Tick; 109 procedure Draw; 92 110 property PlayerCount: Integer read GetPlayerCount write SetPlayerCount; 93 111 property Bitmap: TBitmap read FBitmap write SetBitmap; … … 97 115 const 98 116 SurfaceMatterColors: array[TSurfaceMatter] of TColor = (clBlack, $0756b0, 99 $2170c3, TColor($9a9a9a), TColor($00ff00), TColor($00a000), 100 TColor($ff2c2c), TColor($b60000), clYellow, clRed); 117 $2170c3, TColor($9a9a9a), clYellow, clRed, 118 TColor($00ff00), TColor($00a000), TColor($ff2c2c), TColor($b60000), 119 TColor($0000ff), TColor($0000a0), TColor($ff2cff), TColor($b600b6)); 120 DirectionToDelta: array[0..7] of TPoint = 121 ((X: 0; Y: -1), (X: 1; Y: -1), (X: 1; Y: 0), (X: 1; Y: 1), 122 (X: 0; Y: 1), (X: -1; Y: 1), (X: -1; Y: 0), (X: -1; Y: -1)); 101 123 102 124 var … … 136 158 var 137 159 X, Y: Integer; 160 Distance: Double; 161 Delta: Double; 138 162 begin 139 163 for Y := 0 to Surface.Count.Y - 1 do … … 143 167 Surface.ItemsXY[Y, X] := Byte(smDirt2); 144 168 end; 169 170 Distance := 0.1 * Surface.Count.X; 171 Delta := 0; 172 for Y := 0 to Surface.Count.Y - 1 do begin 173 for X := 0 to Round(Distance) - 1 do begin 174 Surface.ItemsXY[Y, X] := Byte(smRock); 175 end; 176 Delta := (Random * 2 - 1) * 3 - (Distance / (0.1 * Surface.Count.X) * 2 - 1); 177 Distance := Distance + Delta; 178 end; 179 180 Distance := 0.1 * Surface.Count.X; 181 Delta := 0; 182 for Y := 0 to Surface.Count.Y - 1 do begin 183 for X := 0 to Round(Distance) - 1 do begin 184 Surface.ItemsXY[Y, Surface.Count.X - 1 - X] := Byte(smRock); 185 end; 186 Delta := (Random * 2 - 1) * 3 - (Distance / (0.1 * Surface.Count.X) * 2 - 1); 187 Distance := Distance + Delta; 188 end; 189 190 Distance := 0.1 * Surface.Count.Y; 191 Delta := 0; 192 for X := 0 to Surface.Count.X - 1 do begin 193 for Y := 0 to Round(Distance) - 1 do begin 194 Surface.ItemsXY[Y, X] := Byte(smRock); 195 end; 196 Delta := (Random * 2 - 1) * 3 - (Distance / (0.1 * Surface.Count.Y) * 2 - 1); 197 Distance := Distance + Delta; 198 end; 199 200 Distance := 0.1 * Surface.Count.Y; 201 Delta := 0; 202 for X := 0 to Surface.Count.X - 1 do begin 203 for Y := 0 to Round(Distance) - 1 do begin 204 Surface.ItemsXY[Surface.Count.Y - 1 - Y, X] := Byte(smRock); 205 end; 206 Delta := (Random * 2 - 1) * 3 - (Distance / (0.1 * Surface.Count.Y) * 2 - 1); 207 Distance := Distance + Delta; 208 end; 145 209 end; 146 210 … … 150 214 begin 151 215 Surface := TMatrixByte.Create; 152 NewSize.X := 100;153 NewSize.Y := 100;216 NewSize.X := 800; 217 NewSize.Y := 300; 154 218 Size := NewSize; 155 219 end; … … 161 225 end; 162 226 227 procedure TWorld.DrawToBitmap(Bitmap: TBitmap); 228 var 229 X, Y: Integer; 230 begin 231 try 232 Bitmap.BeginUpdate(True); 233 for Y := 0 to Bitmap.Height - 1 do 234 for X := 0 to Bitmap.Width - 1 do 235 Bitmap.Canvas.Pixels[X, Y] := SurfaceMatterColors[TSurfaceMatter( 236 Surface.ItemsXY[Trunc(Y / Bitmap.Height * Surface.Count.Y), 237 Trunc(X / Bitmap.Width * Surface.Count.X)])]; 238 finally 239 Bitmap.EndUpdate; 240 end; 241 end; 242 163 243 { TPlayer } 164 244 165 245 procedure TPlayer.Control; 166 246 var 167 NewPosition: TPoint;168 NewDirection: Integer;169 247 Delta: TPoint; 248 Matter: TSurfaceMatter; 249 NewBullet: TBullet; 250 I: Integer; 170 251 begin 171 252 Delta.X := 0; 172 253 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;254 if Engine.KeyState[Ord(Keys.Down)] then Delta.Y := Delta.Y + 1; 255 if Engine.KeyState[Ord(Keys.Up)] then Delta.Y := Delta.Y - 1; 175 256 if Engine.KeyState[Ord(Keys.Right)] then Delta.X := Delta.X + 1; 176 257 if Engine.KeyState[Ord(Keys.Left)] then Delta.X := Delta.X - 1; … … 186 267 else if (Delta.X = -1) and (Delta.Y = 0) then NewDirection := 6 187 268 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 begin269 270 if NewDirection = Direction then 271 NewPosition := Point(Position.X + Delta.X, Position.Y + Delta.Y) 272 else NewPosition := Position; 192 273 HideTank; 193 Position := NewPosition; 194 Direction := NewDirection; 274 Matter := CheckColision; 275 if (Matter = smDirt1) then Dig := not Dig; 276 if (Matter = smNothing) or ((Matter = smDirt1) and (not Dig)) then begin 277 Position := NewPosition; 278 Direction := NewDirection; 279 Engine.Redraw; 280 end; 195 281 ShowTank; 196 Engine.Redraw; 282 end; 283 284 285 if Engine.KeyState[Ord(Keys.Shoot)] then 286 if Bullets.Count < MaxBulletCount then begin 287 NewBullet := TBullet.Create; 288 NewBullet.Player := Self; 289 NewBullet.Position := Position; 290 NewBullet.Direction := Direction; 291 Bullets.Add(NewBullet); 292 end; 293 294 for I := Bullets.Count - 1 downto 0 do 295 with TBullet(Bullets[I]) do begin 296 Engine.World.Surface.ItemsXY[Position.Y, Position.X] := Byte(smNothing); 297 298 Position.X := Position.X + DirectionToDelta[Direction].X; 299 Position.Y := Position.Y + DirectionToDelta[Direction].Y; 300 301 with Engine.World.Surface do 302 if (Position.X >= Count.X) or (Position.X < 0) or 303 (Position.Y >= Count.Y) or (Position.Y < 0) then 304 Bullets.Delete(I) else 305 Engine.World.Surface.ItemsXY[Position.Y, Position.X] := Byte(smBullet); 197 306 end; 198 307 end; … … 203 312 XX, YY: Integer; 204 313 begin 205 with Engine. Bitmap.Canvas do begin314 with Engine.FBitmapLower.Canvas do begin 206 315 Rectangle(ScreenFrame); 207 //FillRect(ScreenFrame); 316 Brush.Color := SurfaceMatterColors[smRock]; 317 FillRect(ScreenFrame); 208 318 209 319 … … 248 358 end; 249 359 250 function TPlayer.CheckColision: Boolean; 251 begin 252 360 function TPlayer.CheckColision: TSurfaceMatter; 361 var 362 X, Y: Integer; 363 begin 364 Result := smNothing; 365 with Engine.World, TTank(Tanks[NewDirection]) do 366 for Y := 0 to Image.Count.Y - 1 do 367 for X := 0 to Image.Count.X - 1 do 368 if (Image.ItemsXY[Y, X] > 0) and 369 (Surface.ItemsXY[Y + NewPosition.Y, X + NewPosition.X] <> Byte(smNothing)) then 370 begin 371 Result := smDirt1; 372 if (Surface.ItemsXY[Y + NewPosition.Y, X + NewPosition.X] <> Byte(smDirt1)) and 373 (Surface.ItemsXY[Y + NewPosition.Y, X + NewPosition.X] <> Byte(smDirt2)) then 374 begin 375 Result := TSurfaceMatter(Surface.ItemsXY[Y + NewPosition.Y, X + NewPosition.X]); 376 Exit; 377 end; 378 end; 253 379 end; 254 380 … … 261 387 begin 262 388 with Engine.World do begin 263 Surface.Merge( TMatrixByte.Point(Position.X, Position.Y), TTank(Tanks[Direction]).Image, ShowTankProc);389 Surface.Merge(Surface.CreateIndex(Position.X, Position.Y), TTank(Tanks[Direction]).Image, ShowTankProc); 264 390 end; 265 391 end; … … 273 399 begin 274 400 with Engine.World do begin 275 Surface.Merge( TMatrixByte.Point(Position.X, Position.Y), TTank(Tanks[Direction]).Image, HideTankProc);401 Surface.Merge(Surface.CreateIndex(Position.X, Position.Y), TTank(Tanks[Direction]).Image, HideTankProc); 276 402 end; 277 403 end; … … 287 413 NewTank := TTank.Create; 288 414 with NewTank do begin 289 Image.Count := TMatrixByte.Point(7, 7);415 Image.Count := Image.CreateIndex(7, 7); 290 416 for I := 0 to 3 do 291 417 Image[I, 3] := Byte(smCannon); … … 305 431 NewTank := TTank.Create; 306 432 with NewTank do begin 307 Image.Count := TMatrixByte.Point(7, 7);433 Image.Count := Image.CreateIndex(7, 7); 308 434 for I := 0 to 2 do 309 435 Image[3 - I, 3 + I] := Byte(smCannon); … … 368 494 begin 369 495 Tanks := TListObject.Create; 496 Bullets := TListObject.Create; 370 497 end; 371 498 372 499 destructor TPlayer.Destroy; 373 500 begin 501 Bullets.Free; 374 502 Tanks.Free; 375 503 inherited Destroy; … … 422 550 I: Integer; 423 551 begin 424 // TODO: Determine frames from player count 425 if Assigned(Bitmap) then begin 426 HorizFrameCount := 2; 427 VertFrameCount := 1; 552 if Assigned(FBitmapLower) then begin 553 if Players.Count > 1 then begin 554 if Players.Count > 2 then VertFrameCount := 2 555 else VertFrameCount := 1; 556 HorizFrameCount := Round(Players.Count / VertFrameCount); 557 end else begin 558 VertFrameCount := 1; 559 HorizFrameCount := 1; 560 end; 561 FBitmapLower.SetSize(80 * HorizFrameCount, 60 * VertFrameCount); 428 562 for I := 0 to Players.Count - 1 do begin 429 563 TPlayer(Players[I]).ScreenFrame := Rect( 430 (I mod HorizFrameCount) * (Bitmap.Width div HorizFrameCount), 431 (I div HorizFrameCount) * (Bitmap.Height div VertFrameCount), 432 ((I mod HorizFrameCount) + 1) * (Bitmap.Width div HorizFrameCount), 433 ((I div HorizFrameCount) + 1) * (Bitmap.Height div VertFrameCount)); 434 end; 435 end; 564 (I mod HorizFrameCount) * (FBitmapLower.Width div HorizFrameCount), 565 (I div HorizFrameCount) * (FBitmapLower.Height div VertFrameCount), 566 ((I mod HorizFrameCount) + 1) * (FBitmapLower.Width div HorizFrameCount), 567 ((I div HorizFrameCount) + 1) * (FBitmapLower.Height div VertFrameCount)); 568 end; 569 end; 570 Redraw; 436 571 end; 437 572 438 573 constructor TEngine.Create; 439 574 begin 575 FBitmapLower := TBitmap.Create; 440 576 Players := TObjectList.Create; 441 577 World := TWorld.Create; 442 578 World.Engine := Self; 579 Redraw; 443 580 end; 444 581 445 582 destructor TEngine.Destroy; 446 583 begin 584 FBitmapLower.Free; 447 585 Players.Free; 448 586 World.Free; … … 457 595 TPlayer(Players[I]).Control; 458 596 end; 459 597 end; 598 599 procedure TEngine.Draw; 600 var 601 I: Integer; 602 begin 460 603 if FRedrawPending then begin 461 if Assigned(Bitmap) then begin462 Bitmap.Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height);463 for I := 0 to Players.Count - 1 do begin464 TPlayer(Players[I]).Control;465 TPlayer(Players[I]).Paint;466 end;604 FBitmapLower.Canvas.FillRect(0, 0, FBitmapLower.Width, FBitmapLower.Height); 605 for I := 0 to Players.Count - 1 do begin 606 TPlayer(Players[I]).Paint; 607 end; 608 if Assigned(FBitmap) then begin 609 FBitmap.Canvas.StretchDraw(Rect(0, 0, FBitmap.Width, FBitmap.Height), FBitmapLower); 467 610 end; 468 611 FRedrawPending := False; … … 481 624 begin 482 625 // Reset position 483 Position := Point( 25 + Random(World.Surface.Count.X - 50),484 25 + Random(World.Surface.Count.Y - 50));626 Position := Point(Round(World.Surface.Count.X * 0.2) + Random(Round(World.Surface.Count.X * 0.6)), 627 Round(World.Surface.Count.Y * 0.2) + Random(Round(World.Surface.Count.Y * 0.6))); 485 628 486 629 PlaceHouse; 487 630 end; 631 Redraw; 488 632 end; 489 633
Note:
See TracChangeset
for help on using the changeset viewer.