Code:
unit MainFrm;
// idea is
// I check available directions...
// then I set a direction
// when I would hit a wall...I check again available directions...
// then I set a direction...
// could be good
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TMain = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure DrawMap();
procedure DrawMonster();
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TDirection = ( dUp, dDown , dLeft, dRight );
TMonster = class
strict private
FName : string;
FPositionX,FPositionY : integer;
FVelocityX,FVelocityY : integer;
FSetDir : TDirection;
Direction : array of TDirection;
published
property Name : string
read FName write FName;
property PositionX : integer
read FPositionX write FPositionX;
property PositionY : integer
read FPositionY write FPositionY;
property SetDir : TDirection
read FSetDir write FSetDir;
property VelocityX : integer
read FVelocityX write FVelocityX;
property VelocityY : integer
read FVelocityY write FVelocityY;
constructor Create( Name : string ; PositionX,PositionY : integer ; SetDir : TDirection );
procedure GetPossibleDirections();
procedure OnMove;
end;
TMapLine = array [0..19] of Integer;
TMap = array [0..14] of TMapLine;
const
Map: Array [0..14,0..19] of Integer = ((1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
(1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,1),
(1,0,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,1,0,1),
(1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1),
(1,0,1,0,1,0,1,0,0,0,0,1,1,1,1,1,1,1,0,1),
(1,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1),
(1,0,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1),
(1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1),
(1,0,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1),
(1,0,1,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,0,1),
(1,0,1,0,1,0,1,1,1,0,1,1,0,0,1,0,1,0,0,1),
(1,0,1,0,1,0,1,1,1,0,0,1,0,0,1,0,0,0,0,1),
(1,0,1,1,1,0,1,1,1,0,0,0,0,0,1,0,0,0,0,1),
(1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1),
(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1));
var
Main: TMain;
Monster : array of TMonster;
// hacky way later fix
AI : array of TShape;
implementation
{$R *.dfm}
constructor TMonster.Create(Name: string ; PositionX,PositionY : integer; SetDir : TDirection);
begin
FName := Name;
FPositionX := PositionX;
FPositionY := PositionY;
FSetDir := SetDir;
FVelocityX := 0;
FVelocityY := 0;
end;
procedure TMonster.GetPossibleDirections;
begin
// debug
Main.Edit1.Text:='';
// empty directions
SetLength(Direction,0);
// no wall found up, way is free
if Map[PositionY-1,PositionX] <> 1 then
begin
SetLength(Direction,length(Direction)+1);
Direction[High(Direction)]:=dUp;
Main.Edit1.Text:=Main.Edit1.Text+' UP ';
end;
// no wall found down, way is free
if Map[PositionY+1,PositionX] <> 1 then
begin
SetLength(Direction,length(Direction)+1);
Direction[High(Direction)]:=dDown;
Main.Edit1.Text:=Main.Edit1.Text+' DOWN ';
end;
// no wall found left , way is free
if Map[PositionY,PositionX-1] <> 1 then
begin
SetLength(Direction,length(Direction)+1);
Direction[High(Direction)]:=dLeft;
Main.Edit1.Text:=Main.Edit1.Text+' LEFT ';
end;
// no wall found right , way is free
if Map[PositionY,PositionX+1] <> 1 then
begin
SetLength(Direction,length(Direction)+1);
Direction[High(Direction)]:=dRight;
Main.Edit1.Text:=Main.Edit1.Text+' RIGHT ';
end;
end;
procedure TMonster.OnMove;
begin
VelocityY := 0;
VelocityX := 0;
if SetDir = dUp then
begin
if Map[PositionY-1,PositionX] = 1 then
begin
GetPossibleDirections();
SetDir := Direction[random(length(Direction))];
end;
end;
if SetDir = dDown then
begin
if Map[PositionY+1,PositionX] = 1 then
begin
GetPossibleDirections();
SetDir := Direction[random(length(Direction))];
end;
end;
if SetDir = dRight then
begin
if Map[PositionY,PositionX+1] = 1 then
begin
GetPossibleDirections();
SetDir := Direction[random(length(Direction))];
end;
end;
if SetDir = dLeft then
begin
if Map[PositionY,PositionX-1] = 1 then
begin
GetPossibleDirections();
SetDir := Direction[random(length(Direction))];
end;
end;
if SetDir = dUp then
VelocityY:=-2;
if SetDir = dDown then
VelocityY:=+2;
if SetDir = dRight then
VelocityX:=+2;
if SetDir = dLeft then
VelocityX:=-2;
end;
procedure TMain.Button1Click(Sender: TObject);
var i : integer;
begin
DrawMap();
// we do 2 monsters for now
SetLength(Monster,1);
SetLength(AI,1);
Monster[0] := TMonster.Create('Robert',1,1,dDown);
// Monster[1] := TMonster.Create('Devid',3,1,dDown);
// Monster[2] := TMonster.Create('Antal',18,4,dLeft);
for i := 0 to length(Monster)-1 do
begin
AI[i] := TShape.Create(self);
AI[i].Parent:=Panel2;
AI[i].Top:=Monster[i].PositionY*(Panel2.Height div 15);
AI[i].Left:=Monster[i].PositionX*(Panel2.Width div 20);
AI[i].Height:=Panel2.Height div 15;
AI[i].Width:=Panel2.Width div 20;
AI[i].Brush.Color:=clGreen;
AI[i].Pen.Color:=clGreen;
AI[i].Visible:=true;
end;
end;
procedure TMain.Button2Click(Sender: TObject);
var i : integer;
begin
Timer1.Enabled:=true;
{for i := 0 to length(Monster)-1 do
begin
Monster[i].OnMove;
end;
DrawMonster(); }
end;
procedure TMain.DrawMonster;
var i : integer;
begin
// re-draw monster at new position
for i := 0 to length(Monster)-1 do
begin
// AI[i].Top:=Monster[i].StartY*(Panel2.Height div 15);
// AI[i].Left:=Monster[i].StartX*(Panel2.Width div 20);
AI[i].Top:=AI[i].Top+Monster[i].VelocityY;
AI[i].Left:=AI[i].Left+Monster[i].VelocityX;
Monster[i].PositionY:=AI[i].Top div (Panel2.Height div 15);
Edit2.Text:=inttostr(Monster[i].PositionY);
Monster[i].PositionX:=AI[i].Left div (panel2.Width div 20);
Edit3.Text:=inttostr(Monster[i].PositionX);
end;
end;
procedure TMain.Timer1Timer(Sender: TObject);
var i : integer;
begin
for i := 0 to length(Monster)-1 do
begin
Monster[i].OnMove;
end;
DrawMonster();
end;
procedure TMain.DrawMap;
var x,y: integer;
Wall : TShape;
begin
for y := 0 to 14 do
for x := 0 to 19 do
begin
if Map[y,x] = 1 then
begin
Wall := TShape.Create(self);
Wall.Parent:=Panel2;
Wall.Top:=y*(Panel2.Height div 15);
Wall.Left:=x*(Panel2.Width div 20);
Wall.Height:=Panel2.Height div 15;
Wall.Width:=Panel2.Width div 20;
Wall.Brush.Color:=clRed;
Wall.Pen.Color:=clRed;
Wall.Visible:=true;
end;
end;
end;
end.
I've altered so there is only one moving monster.
Bookmarks