Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit GameEnity;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, Graphics, GameUtilityUnit, TimerUnit, typinfo;
- type
- TEntity = class
- Speed: Real;
- Image: TBitMap;
- Location: TLocation;
- Direction: TDirection;
- Request: TDirection;
- Spawn: TLocation;
- Exclamation: TBitmap;
- constructor Create(X, Y: Integer ; _Game:TObject); Virtual;
- procedure Move(_Direction: TDirection); Virtual;
- procedure Update; Virtual;
- procedure Approach(_Direction: TDirection);
- function DistanceTo(_Location: TLocation):Real;
- function IsMoving: Boolean;
- function GetLocation: TLocation;
- procedure Paint(Canvas: TCanvas); Virtual;
- procedure Respawn; Virtual;
- end;
- TEnemyNature = (Rusher, Ambusher, Randomer, Camper);
- TEnemy = class(TEntity)
- Last: TDirection;
- Nature: TEnemyNature;
- LogicTimer: TTimer;
- Ways: Integer;
- constructor Create(X, Y: Integer; _Nature: TEnemyNature;_Game:TObject);
- procedure Update; Override;
- procedure Move(_Direction: TDirection); Override;
- function OnXRoad: Boolean;
- procedure NewPath;
- end;
- TPlayer = class(TEntity)
- Images: TPlayerImages;
- constructor Create(X, Y: Integer;_Game:TObject); Override;
- procedure Paint(Canvas: TCanvas); Override;
- procedure Update; Override;
- end;
- TEnemies = array of TEnemy;
- implementation
- uses GameMain;
- var
- Game: TGame;
- procedure TEntity.Paint(Canvas: TCanvas);
- var
- X, Y: Integer;
- begin
- X := Round(Location.X);
- Y := Round(Location.Y);
- if Image <> nil then
- begin
- Canvas.Draw(X, Y, Image);
- if Game.Killing and (Self is TEnemy) then
- begin
- Canvas.Draw(X + 8, Y - 8, Exclamation);
- end;
- end
- else
- begin
- Canvas.Rectangle(X , Y, X + SQUARE, Y + SQUARE);
- end;
- end;
- constructor TEntity.Create(X, Y: Integer;_Game:TObject);
- begin
- Location := ConvertToLocation(X*SQUARE, Y*SQUARE);
- Spawn := Location;
- Direction := NONE;
- Request := NONE;
- Speed := 0.7;
- Image := nil;
- Game := _Game as TGame;
- end;
- procedure TEntity.Move(_Direction: TDirection);
- begin
- Request := _Direction;
- end;
- function TEntity.IsMoving: Boolean;
- begin
- Result := Direction <> NONE;
- end;
- function TEntity.GetLocation: TLocation;
- begin
- Result := Location;
- end;
- procedure TEntity.Update;
- begin
- if Request <> None then
- begin
- if ((Round(Location.X) mod SQUARE) < 1) and ((Round(Location.Y) mod SQUARE) < 1) then
- begin
- Location.X := Round(Location.X);
- Location.Y := Round(Location.Y);
- if Game.CanMove(Self, Request) then
- begin
- Direction := Request;
- Request := None;
- end;
- end;
- end;
- if IsMoving and Game.CanMove(Self, Direction) then Approach(Direction)
- else Direction := None;
- end;
- procedure TEntity.Approach(_Direction: TDirection);
- begin
- case _Direction of
- LEFT: Location.X := Location.X - Speed;
- RIGHT: Location.X := Location.X + Speed;
- UP: Location.Y := Location.Y - Speed;
- DOWN: Location.Y := Location.Y + Speed;
- end;
- end;
- procedure TEntity.Respawn;
- begin
- Location := Spawn;
- end;
- function TEntity.DistanceTo(_Location: TLocation): Real;
- begin
- Result := Sqrt(Sqr(_Location.X - Location.X) + Sqr(_Location.Y - Location.Y));
- end;
- constructor TPlayer.Create(X, Y: Integer; _Game:TObject);
- var
- Dir: TDirection;
- begin
- Inherited;
- for Dir := Low(Dir) to High(Dir) do Images[Dir] := TBitmap.Create;
- Images[None].LoadFromFile(IMAGE_DIR + 'pacman.bmp');
- Images[UP].LoadFromFile(IMAGE_DIR + 'pacmanU.bmp');
- Images[DOWN].LoadFromFile(IMAGE_DIR + 'pacmanD.bmp');
- Images[LEFT].LoadFromFile(IMAGE_DIR + 'pacmanL.bmp');
- Images[RIGHT].LoadFromFile(IMAGE_DIR + 'pacmanR.bmp');
- end;
- procedure TPlayer.Paint(Canvas: TCanvas);
- begin
- if Direction <> None then Image := Images[Direction];
- Inherited;
- end;
- procedure TPlayer.Update;
- begin
- Inherited;
- with Game.GameMap do
- if (Network[Round(Location.Y) div SQUARE][Round(Location.X) div SQUARE] = Food) then
- begin
- Network[Round(Location.Y) div SQUARE][Round(Location.X) div SQUARE] := Nothing;
- Dec(FoodRemaining);
- end
- else
- if Network[Round(Location.Y) div SQUARE][Round(Location.X) div SQUARE] = Ball then
- begin
- Network[Round(Location.Y) div SQUARE][Round(Location.X) div SQUARE] := Nothing;
- Game.StartKilling;
- end;
- end;
- constructor TEnemy.Create(X, Y: Integer; _Nature: TEnemyNature; _Game:TObject);
- begin
- Nature := _Nature;
- Location := ConvertToLocation(X * SQUARE, Y * SQUARE);
- Spawn := Location;
- Last := None;
- LogicTimer := TTimer.Create;
- LogicTimer.Reset;
- Game := _Game as TGame;
- Exclamation := TBitmap.Create;
- Exclamation.Transparent := True;
- Exclamation.LoadFromFile(IMAGE_DIR + 'ex.bmp');
- end;
- function TEnemy.OnXRoad:Boolean;
- var
- X0, Y0 ,I :Integer;
- begin
- if ((Round(Location.X) mod SQUARE) <= 1) and ((Round(Location.Y) mod SQUARE) <= 1)then
- begin
- X0 := Round(Location.X) div Square;
- Y0 := Round(Location.Y) div Square;
- I := 0;
- if Game.GameMap.IsFree(X0 + 1, Y0) then Inc(I);
- if Game.GameMap.IsFree(X0 - 1 , Y0) then Inc(I);
- if Game.GameMap.IsFree(X0, Y0 + 1) then Inc(I);
- if Game.GameMap.IsFree(X0, Y0 - 1) then Inc(I);
- if I >= 3 then Result := True else Result := False;
- end
- else
- Result := False;
- end;
- procedure TEnemy.NewPath;
- var
- PossibleMoves: TMoves;
- Dir: TDirection;
- R: Integer;
- Debug: TLocation;
- begin
- SetLength(PossibleMoves, 0);
- for Dir := Low(TDirection) to RIGHT do
- begin
- if not (Dir = Invert(Last)) and Game.CanMove(Self, Dir) then
- begin
- SetLength(PossibleMoves, Length(PossibleMoves) + 1);
- PossibleMoves[Length(PossibleMoves) - 1].Destination := PseudoMove(Location, Dir);
- PossibleMoves[Length(PossibleMoves) - 1].Direction := Dir;
- end;
- end;
- if Length(PossibleMoves) = 0 then
- begin
- Move(Invert(Last));
- Exit;
- end;
- if Length(PossibleMoves) = 1 then
- begin
- Move(PossibleMoves[0].Direction);
- Exit;
- end;
- R := Random(Sqr(Length(PossibleMoves))) + 1;
- case Nature of
- Camper:
- begin
- PossibleMoves := Sort(PossibleMoves,Spawn);
- if Length(PossibleMoves) = 2 then
- begin
- if R<=2 then Move(PossibleMoves[0].Direction)
- else Move(PossibleMoves[1].Direction)
- end
- else
- if Length(PossibleMoves) = 3 then
- begin
- if R <= 4 then Move(PossibleMoves[0].Direction)
- else if R <= 7 then Move(PossibleMoves[1].Direction)
- else Move(PossibleMoves[2].Direction)
- end
- else
- begin
- if R <= 6 then Move(PossibleMoves[0].Direction)
- else if R <= 10 then Move(PossibleMoves[1].Direction)
- else if R <= 14 then Move(PossibleMoves[2].Direction)
- else Move(PossibleMoves[3].Direction)
- end;
- end;
- Rusher:
- begin
- PossibleMoves := Sort(PossibleMoves, Game.Player.Location);
- Move(PossibleMoves[0].Direction);
- end;
- Randomer:
- begin
- Move(PossibleMoves[Random(Length(PossibleMoves))].Direction);
- end;
- Ambusher:
- begin
- Debug := GetPointForAmbusher(Game.GameMap.Network);
- PossibleMoves := Sort(PossibleMoves, Debug);
- Move(PossibleMoves[Length(PossibleMoves)-1].Direction);
- end;
- end;
- end;
- procedure TEnemy.Update;
- begin
- if ((LogicTimer.GetTime > 100) and OnXRoad()) or (Direction = None) then begin
- LogicTimer.Reset;
- NewPath;
- Direction := Request;
- Request := None;
- end;
- if IsMoving and Game.CanMove(Self, Direction) then Approach(Direction) else Direction := None;
- end;
- procedure TEnemy.Move(_Direction :TDirection);
- begin
- Last := _Direction;
- Inherited;
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement