| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- Unit Objs;
- InterFace
- Uses Objects, Graph, TypeLib;
- Const
- MAXNAME = 30;
- MAXTYPE = 20;
- Type
- vec = record x,y:real; end;
- rect = record A,B,C,D : vec; end;
- Pline = ^TLine;
- Tline = record A,B : vec; end;
- PString = ^String;
- ManMoods = (MOOD_STOP,MOOD_WALK,MOOD_ACCEL,MOOD_BRAKING);
- CObjs = Object
- oType : string[MAXTYPE];
- Name : string[MAXNAME];
- Color : integer;
- Heading: Real;
- POS : vec;
- Speed : vec;
- Accel : vec;
- Bounds : TLine;
- procedure Step;
- procedure Draw;
- procedure Clear;
- End;
- CHouse = Object (COBjs)
- UL, BR : vec;
- Door : Rect;
- Constructor Init(cx,cy,sTop,sBottom,sLeft,sRight : real;aName : string);
- Procedure SetDoor(dx1,dy1,dx2,dy2 : real);
- Procedure Draw;
- end;
- CMan = Object (COBjs)
- Mood : MANMOODS;
- MaxAccel : real;
- MaxSpeed : real;
- StepPos : real;
- Scale : real;
- NewMove : byte;
- DefBounds: TLine;
- Model : array [0..5] of PLine;
- Procedure CreateMan(var Ar:array of PLine;SP:real);
- Constructor Init(cx,cy,ang,aScale:real;aName:string;aCol:integer);
- Procedure Rotate(aAng : real);
- Procedure SetSpeed(aNewSpeed : real);
- Procedure SetAccel(aNewAccel : real);
- Procedure Step;
- Procedure Clear;
- Procedure Draw;
- Destructor Destroy;
- end;
- Procedure DrawRay(aC:vec;Ang,Len:real);
- Procedure SetBounds(Ob : array of Pline;numvert:word;var aB:TLine;DefBounds:TLine);
- Procedure RotateVec(var aV : Vec; Ang:Real);
- Procedure RotateRect(var Ob : rect;Ang:real);
- Procedure RotateLine(var Ob : TLine;Ang:real);
- Procedure RotateArray(var Ob : array of Pline;numvert:word;Ang:real);
- Function Len(aVec : vec) : real;
- Procedure Neg(var aV : real);
- IMPLEMENTATION
- {-------------------------------}
- Procedure Neg(var aV : real);
- begin
- aV := -aV;
- end;{Neg}
- {-------------------}
- Procedure SetBounds;
- var
- i : word;
- begin
- with aB do begin
- Ab := DefBounds;
- for i := 0 to NumVert do
- begin
- if ob[i]^.A.X > A.X then A.X:=ob[i]^.A.X;
- if ob[i]^.B.X > A.X then A.X:=ob[i]^.B.X;
- if ob[i]^.A.Y > A.Y then A.Y:=ob[i]^.A.Y;
- if ob[i]^.B.Y > A.Y then A.Y:=ob[i]^.B.Y;
- if ob[i]^.A.X < B.X then B.X:=ob[i]^.A.X;
- if ob[i]^.B.X < B.X then B.X:=ob[i]^.B.X;
- if ob[i]^.A.Y < B.Y then B.Y:=ob[i]^.A.Y;
- if ob[i]^.B.Y < B.Y then B.Y:=ob[i]^.B.Y;
- end;
- end;
- end;{SetBounds}
- {--------------------}
- Procedure DrawRay;
- Begin
- Line(Round(aC.X),Round(aC.Y),
- Round(aC.X+Len*cos(PI*Ang/180)),Round(aC.Y+Len*sin(PI*Ang/180)));
- end; {DrawRay}
- {--------------------}
- Procedure RotateVec;
- var ps : vec;
- begin
- ps.X := aV.X * cos(PI*Ang/180) - aV.Y * sin(PI*Ang/180);
- ps.Y := aV.X * sin(PI*Ang/180) + aV.Y * cos(PI*Ang/180);
- av := ps;
- end;{RotateVec}
- {--------------------}
- Procedure RotateRect;
- begin
- RotateVec(ob.A,Ang);
- RotateVec(ob.B,Ang);
- RotateVec(ob.C,Ang);
- RotateVec(ob.D,Ang);
- end;{RotateVec}
- {--------------------}
- Procedure RotateLine;
- begin
- RotateVec(ob.A,Ang);
- RotateVec(ob.B,Ang);
- end;{RotateVec}
- {--------------------}
- Procedure RotateArray;
- var u : word;
- begin
- for u := 0 to numvert do RotateLine(ob[u]^,Ang);
- end;{RotateVec}
- {--------------------}
- Function Len;
- begin
- Len := Sqrt(Sqr(aVec.X)+Sqr(aVec.Y));
- end;{Len}
- {--------------------}
- {COBJ}
- Procedure CObjs.step; begin end;
- Procedure CObjs.Draw; begin end;
- Procedure CObjs.Clear; begin end;
- {/COBJ}
- {------------}
- {CMan}
- Procedure CMan.CreateMan;
- Begin
- with Ar[0]^ do Begin
- A.x:=-3*Scale;A.y:=0;B.x:=-7*Scale;B.y:=0;end;
- with Ar[1]^ do Begin
- A.x:=3*Scale;A.y:=0;B.x:=7*Scale;B.y:=0;end;
- with Ar[2]^ do Begin
- A.x:=-7*Scale;A.y:=0;B.x:=-7*Scale;B.y:=4*Scale-8*abs(SP)/5;end;
- with Ar[3]^ do Begin
- A.x:=7*Scale;A.y:=0;B.x:=7*Scale;B.y:=-4*Scale+8*abs(SP)/5;end;
- with Ar[4]^ do Begin
- A.x:=-4*Scale;A.y:=0;B.x:=-4*Scale;B.y:=-8*Scale+11*abs(SP)/5;end;
- with Ar[5]^ do Begin
- A.x:=4*Scale;A.y:=0;B.x:=4*Scale;B.y:=3*Scale-11*abs(SP)/5;end;
- End;{CMan.CreateMan}
- {--------------------}
- Constructor CMan.Init;
- var i : byte;
- begin
- Heading := Ang;
- oType := 'Man';
- Name := aName;
- Color := aCol;
- Scale := aScale;
- POS.X := cx;
- POS.Y := cy;
- Mood := MOOD_STOP;
- MaxSpeed := 10;MaxAccel := 5;
- Speed.X:=0;Speed.Y:=0;Accel.X:=0;Accel.Y:=0;
- for i:=0 to 5 do New(Model[i]);
- CreateMan(Model,0);
- RotateArray(Model,5,Heading);
- with DefBounds do begin A.X:=-3*Scale;A.Y:=-3*Scale;B.X:=3*Scale;b.Y:=3*Scale;end;
- SetBounds(Model,5,Bounds,DefBounds);
- NewMove := 0;
- end; {CMan.Init}
- {---------------}
- Procedure CMan.Rotate;
- Begin
- Heading := Heading + aAng;
- If Heading > 360 then Heading := Heading - 360;
- If Heading < 0 then Heading := Heading + 360;
- RotateVec(Speed,aAng);
- RotateVec(Accel,aAng);
- RotateArray(Model,5,aAng);
- { SetBounds(Model,5,Bounds,DefBounds);}
- End;{CMan.Rotate}
- {-------------------}
- Procedure CMan.SetSpeed;
- begin
- if aNewSpeed <> 0 then if Mood = MOOD_STOP then Mood:=MOOD_WALK;
- if aNewSpeed > MaxSpeed then aNewSpeed := MaxSpeed;
- Speed.X := aNewSpeed * cos(PI*Heading/180+PI/2);
- Speed.Y := aNewSpeed * sin(PI*Heading/180+PI/2);
- end;{CMan.SetSpeed}
- {-------------------}
- Procedure CMan.SetAccel;
- begin
- if aNewAccel > 0 then Mood:=MOOD_ACCEL
- else if aNewAccel < 0 then Mood := MOOD_BRAKING;
- if aNewAccel > MaxAccel then aNewAccel := MaxAccel;
- Accel.X := aNewAccel * cos(PI*Heading/180+PI/2);
- Accel.Y := aNewAccel * sin(PI*Heading/180+PI/2);
- end;{CMan.SetSpeed}
- {-------------------}
- Procedure CMan.Step;
- Begin
- POS.X := POS.X + Speed.X;
- POS.Y := POS.Y + Speed.Y;
- StepPos := StepPos + Len(Speed)*0.4;
- while StepPos > 10*Scale do StepPos:=StepPos-10*Scale;
- If StepPos > 5*Scale then StepPos:=StepPos-10*Scale;
- CreateMan(Model,StepPos);
- RotateArray(Model,5,Heading);
- if NewMove <> 0 then Dec(NewMove);
- if NewMove = 1 then
- begin
- NewMove := random(40)+2;
- Rotate(360*random-180);
- SetAccel(MaxAccel*random - MaxAccel/2);
- end;
- Speed.X := Speed.X + Accel.X;
- Speed.Y := Speed.Y + Accel.Y;
- if Len(Speed) > MaxSpeed then SetSpeed(MaxSpeed*random);
- if Len(Speed) < 0.001 then SetAccel(MaxAccel*random - MaxAccel/2);
- if (Pos.X > 630) and (Speed.X > 0) then Pos.X := 10;
- if (Pos.X < 10) and (Speed.X < 0) then Pos.X := 630;
- if (Pos.Y > 470) and (Speed.Y > 0) then Pos.Y:=10;
- if (Pos.Y < 10) and (Speed.Y < 0) then Pos.Y:=470;
- end; {CMan.Step}
- {-------------------}
- Procedure CMan.Draw;
- var i:byte;
- Begin
- SetColor(Color);
- Circle(ROUND(POS.X),Round(480-POS.Y),Round(3*Scale));
- for i := 0 to 5 do
- begin
- Line(ROUND(POS.X+Model[I]^.A.X), ROUND(480-(POS.Y+Model[I]^.A.Y)),
- ROUND(POS.X+Model[I]^.B.X), ROUND(480-(POS.Y+Model[I]^.B.Y)));
- end;
- End; {CMan.Draw}
- {-------------------}
- Procedure CMan.Clear;
- begin
- Bar(ROUND(POS.X+Bounds.A.X)+1, ROUND(480-(POS.Y+Bounds.A.Y))-1,
- ROUND(POS.X+Bounds.B.X)-1, ROUND(480-(POS.Y+Bounds.B.Y))+1);
- end;{CMAn.Clear}
- {-------------------}
- Destructor CMan.Destroy;
- var i:byte;
- begin
- for i := 0 to 5 do Dispose(Model[i]);
- end;{CMan.Destroy}
- {-------------------}
- {/CMan}
- {CHouse}
- Constructor Chouse.Init; begin end;
- Procedure CHouse.SetDoor; begin end;
- Procedure CHouse.Draw;begin end;
- {/CHouse}
- END.
|