{$R-} Unit Objects2; {Здесь находятся все объекты (классы) используемые в программе} {Версия 2-я, используется страницы} INTERFACE Uses Graph, Draw10H; type FLAG_ENUM = (NONE,CAN_DRAW,HEAT); FLAGS = set of FLAG_ENUM; Const M_360_2PI = 360/(2*Pi); GLOB_G : real = 0.01; FIELD_X : word = 600; TRES_LX : word = 10; TRES_MX : word = 630; TRES_LY : word = 10; TRES_MY : word = 340; SIZE_Y : word = 350; FPS : WORD = 1; TIME_FACTOR : real = 0.1; type {Globals} Vector = record x,y : real; end; TSprites = array [0..(65536 shr 2)-2] of Pointer; PSprites = ^TSprites; TWordArray = array [0..(65536 shr 1)-2] of word; PWordArray = ^TWordArray; TByteArray = array [0..65534] of Byte; PByteArray = ^TByteArray; TParams = record Pos,Speed,Accel : Vector; end; PWorld = ^TWorld; { MAIN OBJECT (Global Parent) } PWorldObject = ^TWorldObject; TWorldObject = object ObjType : string[20]; Flag : FLAGS; World : PWorld; LocTime : LONGINT; Params : TParams; Angle : integer; ZORDER : Byte; Started : boolean; Constructor Init; Procedure Frame(t:longInt);virtual; {Процедура, выполняемая на каждом шаге, t - время этого шага (отрезок) Для абсолютности времени} Destructor Done;virtual; end; pDrawable = ^tDrawAble; tDrawable = object (TWorldObject) Frames : Psprites; FramesCount : integer; FrameSize : PWordArray; xsize,ysize : PWordArray; CurFrame : integer; Constructor Init; Procedure Draw;virtual; Function Inside(aPos:Vector):boolean;virtual; end; pRAH = ^tRAH; tRAH = object (TDrawable) Masks : Psprites; FileCount : integer; NextTrap : longint; FrameTime : longint; TrapBase, TrapVar : longint; SpeedBase, SpeedVar : longint; CountBase, CountVar : integer; A,B : Vector; Constructor Init(AnimDat:string;aPar : TParams;Zord:byte); Procedure DropTraps(aCount:byte); Procedure Frame(t : longint);virtual; Procedure Draw;virtual; Function Inside(aPos:Vector):boolean;virtual; Destructor Done;virtual; end; pTrap = ^tTrap; tTrap = object(TDrawable) Constructor Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte); Procedure Frame(t : longint);virtual; Procedure Draw;virtual; Function Inside(aPos:Vector):boolean;virtual; Destructor Done;virtual; end; pSting = ^tSting; tSting = object (TDrawable) dAngle : integer; Nose : Vector; Constructor Init(AnimDat:string;aPar : TParams;adAng:integer;Zord:byte); Procedure GetAngle; Procedure FindTarget(aDa:integer); Procedure ChangeAngle(dA : integer); Procedure Frame(t : longint);virtual; Procedure Draw;virtual; Destructor Done;virtual; end; pExpl = ^tExpl; tExpl = object (TDrawAble) Masks : Psprites; LifeTime : Longint; Constructor Init(AnimDat:string;aLifeTime:longint;aPos:vector;Zord:byte); Procedure Frame(t : longint);virtual; Procedure Draw;virtual; Destructor Done;virtual; end; { - - - - - - - - - - - - - - - -} PWOsList = ^TWOsList; TWOsList = record o : PworldObject; next : PWOsLIst; end; TWorld = object Ending : boolean; MSG : string; MSGSize : word; MSGColor : byte; Procedure Gone(aObj : PWorldObject); {Objects, that needs to be killed} Constructor Init(aBGn : string); {aBGN - BackGround fileName} Procedure Draw; Procedure Frame(t:longint); Function Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject; Procedure StartObjects(aT:string); Procedure Explosion(aPos:vector); Procedure Message(aS:string;aSize:word;aColor:byte); Function AddObject(aOb : PWorldObject):boolean; Function RemoveObject(aOb:PWorldObject):boolean; Destructor Done; private WObjects : PWOsList; ToGone : PWOsList; {Стек объектов на "убийство"} { BackGround } xpos, ypos : PWordArray; xsize,ysize : PWordArray; FrameCount : Byte; BackGround : Psprites; FrameSize : PWordArray; {} end; {----------- END OF OBJECTS ----------------------} IMPLEMENTATION { TWorldObject Dummy } {------------------------------------------} Constructor TworldObject.Init; begin ObjType := 'dummy'; Flag := [NONE]; Zorder := 0; LocTime := 0; Started := false; end;{TworldObject.Init} {----} Procedure TWorldObject.Frame; begin {Nothing here now} end; {TWorldObject.Frame} {----} Destructor TWorldObject.Done; begin {Nothing here now} end; {TWorldObject.Done} {----} Constructor TDrawable.Init; begin Inherited Init; Flag := Flag + [CAN_DRAW]; Frames:=nil; FramesCount:=0; FrameSize:=nil; xsize:=nil;ysize:=nil; CurFrame:=0; end;{TDrawable.Init} {----} Procedure TDrawable.Draw; begin end;{TDrawable.Draw} Function TDrawable.Inside; begin Inside:=false; end;{TDrawable.Inside} {------------------------------------------} { First object - Helicopter Commanche RAH-66} Constructor tRAH.Init; var i : byte; F : FILE; begin Inherited Init; Randomize; FLAG := FLAG + [HEAT] - [NONE]; ObjType := 'RAH-66'; TrapBase := 100; TrapVar := 30; { NextTrap := TrapBase + random(TrapVar) - (TrapVar shr 1);} Params := aPar; ZOrder := zOrd; Assign(F,AnimDat); {$I-} Reset(F,1); If IOResult <> 0 then begin CloseGraph; WriteLn('Error opening animation library for RAH-66 (',AnimDat,')'); Halt(255); end; {$I+} BlockRead(F,FileCount,2); FramesCount := (FileCount-1)*2; GetMem(Frames, FramesCount*sizeof(Pointer)); GetMem(Masks, FramesCount*sizeof(Pointer)); GetMem(xsize, FramesCount*sizeof(Word)); GetMem(ysize, FramesCount*sizeof(Word)); GetMem(FrameSize,FramesCount*sizeof(Word)); for i := 0 to FileCount-1 do begin BlockRead(F,FrameSize^[i],2); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Frames^[i],FrameSize^[i]); BlockRead(F,xsize^[i],2);inc(xsize^[i]); BlockRead(F,ysize^[i],2);inc(ysize^[i]); Seek(F,FilePos(F)-4); BlockRead(F,Frames^[i]^,FrameSize^[i]); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Masks^[i],FrameSize^[i]); BlockRead(F,Masks^[i]^,FrameSize^[i]); end; A.X := -(xsize^[0] shr 1); B.X := xsize^[0] shr 1; A.Y := -(ysize^[0] shr 1); B.Y := ysize^[0] shr 1; for i := FileCount to FramesCount-1 do begin Frames^[i] := Frames^[FramesCount-i]; Masks^[i] := Masks^[FramesCount-i]; FrameSize^[i] := FrameSize^[FramesCount-i]; xsize^[i] := xsize^[FramesCount-i]; ysize^[i] := ysize^[FramesCount-i]; end; Close(F); CurFrame := 0; end;{tRAH.Init} {----} Function tRAH.Inside; begin with Params.pos do Inside := (aPos.x > A.X+X) and (aPos.x < B.X+X) and (aPos.y > A.y+y) and (aPos.y < B.y+y); end;{tRAH.Inside} {----------------------} Procedure tRAH.Frame; begin if started then begin with Params do begin Speed.x := Speed.x+Accel.x*t*TIME_FACTOR; Speed.y := Speed.y+Accel.y*t*TIME_FACTOR; Pos.x := Pos.x + Speed.X*t*TIME_FACTOR; Pos.y := Pos.y + Speed.y*t*TIME_FACTOR; if Pos.x > FIELD_X then World^.Gone(@Self); end; LocTime := LocTime + t; inc(FrameTime,t); if LocTime > NextTrap then begin DropTraps(CountBase + random(Countvar)-(countvar shr 1)); NextTrap := LocTime + TrapBase + random(TrapVar) - (TrapVar shr 1); end; end; end;{tRAH.Frame} {-----} Procedure tRAH.DropTraps; var aNewTrap : pTrap; i : byte; nspeed : real; nangle : integer; begin Randomize; for i := 1 to aCount do begin nangle := random(360); nspeed := speedBase + random*SpeedVar - (SpeedVar shr 1); New(aNewTrap,Init('trap.dat',Params.pos,nspeed,GLOB_G,nangle,Zorder+random(11)-5)); World^.AddObject(aNewTrap); end; end;{tRAH.DropTrap} {----} Procedure tRAH.Draw; var Top,Left : word; begin Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1)); Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1)); if (Top=TRES_MY) or (Left=TRES_MX) then exit; PutImage(Left,Top,Masks^[CurFrame]^,AndPut); PutImage(Left,Top,Frames^[CurFrame]^,OrPut); CurFrame := (CurFrame+FrameTime div FPS) mod FramesCount; FrameTime := FrameTime mod FPS; end;{tRAH.Draw} {----} Destructor tRAH.Done; var i:byte; begin for i := 0 to FileCount-1 do begin FreeMem(Frames^[i],FrameSize^[i]); FreeMem( Masks^[i],FrameSize^[i]); end; FreeMem(Frames,FramesCount*sizeof(Pointer)); FreeMem( Masks,FramesCount*sizeof(Pointer)); FreeMem(FrameSize,FramesCount*sizeof(Word)); FreeMem(xsize,FramesCount*sizeof(Word)); FreeMem(ysize,FramesCount*sizeof(Word)); Inherited Done; end; {tRAH.Done} {-------------------------------------------------} { Second object - rocket earth-air Stinger (hand-made) :) } Constructor tSting.Init; var i : byte; F : FILE; begin Inherited Init; ObjType := 'Stinger'; Params := aPar; ZOrder := zOrd; dAngle := adAng; GetAngle; Nose.x:=Params.pos.x + xsize^[0]/2*cos(Angle/M_360_2PI); Nose.y:=Params.pos.y + xsize^[0]/2*sin(Angle/M_360_2PI); Assign(F,AnimDat); {$I-} Reset(F,1); If IOResult <> 0 then begin CloseGraph; WriteLn('Error opening animation library for Stinger (',AnimDat,')'); Halt(255); end; {$I+} BlockRead(F,FramesCount,2); GetMem(Frames,FramesCount*sizeof(Pointer)); GetMem(xsize,FramesCount*sizeof(Word)); GetMem(ysize,FramesCount*sizeof(Word)); GetMem(FrameSize,FramesCount*sizeof(Word)); for i := 0 to FramesCount-1 do begin BlockRead(F,FrameSize^[i],2); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Frames^[i],FrameSize^[i]); BlockRead(F,xsize^[i],2);inc(xsize^[i]); BlockRead(F,ysize^[i],2);inc(ysize^[i]); Seek(F,FilePos(F)-4); BlockRead(F,Frames^[i]^,FrameSize^[i]); end; Close(F); CurFrame := (Angle div (360 div FramesCount)); if CurFrame < 0 then inc(curframe,FramesCount); end;{tSting.Init} {----} Procedure tSting.ChangeAngle(dA : integer); var speed : real; begin Angle := dA; while Angle < 0 do Inc(Angle,360); while Angle > 360 do dec(Angle,360); speed := sqrt(sqr(params.speed.x)+sqr(params.speed.y)); Params.Speed.x := Speed * cos(Angle/M_360_2PI); Params.Speed.y := Speed * sin(Angle/M_360_2PI); end; Procedure tSting.FindTarget; var ang:integer; dist : real; ob : PWorldObject; begin ang:=-ada; ob := World^.Radar(@Self,HEAT,ang,-ang,dist); if (ob <> nil) then begin ChangeAngle(ang); end else GetAngle; ang:=-30; ob := World^.Radar(@Self,HEAT,ang,-ang,dist); if ob = nil then exit; if PDrawable(ob)^.Inside(Nose) then begin World^.Explosion(ob^.params.pos); World^.Gone(@Self); World^.Gone(ob); if ob^.objtype = 'RAH-66' then World^.Message('You Win',4,LightRed) else World^.Message('You Lose',4,LightGray); end; end;{tSting.FindTarget} {--------} Procedure tSting.GetAngle; begin if Params.Speed.x = 0 then begin if Params.Speed.y > 0 then Angle := 90 else Angle := 270; end else Angle := round(M_360_2PI*ArcTan(Params.Speed.y/Params.Speed.x)); if Angle < 0 then Inc(Angle,360); if Params.Speed.X < 0 then Inc(Angle, 180); if Angle >= 360 then Dec(Angle, 360); end;{tSting.GetAngle} {------} Procedure tSting.Frame; begin if started then begin with Params do begin Speed.x := Speed.x+Accel.x*t*TIME_FACTOR; Speed.y := Speed.y+Accel.y*t*TIME_FACTOR; FindTarget(dAngle); Pos.x := Pos.x + Speed.X*t*TIME_FACTOR; Pos.y := Pos.y + Speed.y*t*TIME_FACTOR; if not ((Pos.X>TRES_LX) and (Pos.XTRES_LY) and (Pos.YTRES_MX) and ((Speed.X>0) or (Accel.X>0))) or ((Pos.xTRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or ((Pos.y=TRES_MY) or (Left=TRES_MX) then exit; PutImage(Left,Top,Frames^[CurFrame]^,AndPut); Nose.x:=params.pos.x + xsize^[0]/2.1*cos(Angle/M_360_2PI); Nose.y:=params.pos.y + xsize^[0]/2.1*sin(Angle/M_360_2PI); x12:=Nose.x + 50*cos((Angle-dAngle)/M_360_2PI); y12:=Nose.y + 50*sin((Angle-dAngle)/M_360_2PI); x22:=Nose.x + 50*cos((Angle+dAngle)/M_360_2PI); y22:=Nose.y + 50*sin((Angle+dAngle)/M_360_2PI); SetColor(Black); Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x12),SIZE_Y-round(y12)); Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x22),SIZE_Y-round(y22)); end;{tSting.Draw} {----} Destructor tSting.Done; var i:byte; begin for i := 0 to FramesCount-1 do FreeMem(Frames^[i],FrameSize^[i]); FreeMem(Frames,FramesCount*sizeof(Pointer)); FreeMem(FrameSize,FramesCount*sizeof(Word)); FreeMem(xsize,FramesCount*sizeof(Word)); FreeMem(ysize,FramesCount*sizeof(Word)); Inherited Done; end; {tSting.Done} {-------------------------------------------------} { Third object - just explosion} Constructor tExpl.Init; var i : byte; F : FILE; begin Inherited Init; ObjType := 'EXPL'; LifeTime := aLifeTime; Params.pos := aPos; ZOrder := zOrd; Assign(F,AnimDat); {$I-} Reset(F,1); If IOResult <> 0 then begin CloseGraph; WriteLn('Error opening animation library for exposion (',AnimDat,')'); Halt(255); end; {$I+} BlockRead(F,FramesCount,2); GetMem(Frames, FramesCount*sizeof(Pointer)); GetMem(Masks, FramesCount*sizeof(Pointer)); GetMem(xsize, FramesCount*sizeof(Word)); GetMem(ysize, FramesCount*sizeof(Word)); GetMem(FrameSize,FramesCount*sizeof(Word)); for i := 0 to FramesCount-1 do begin BlockRead(F,FrameSize^[i],2); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Frames^[i],FrameSize^[i]); BlockRead(F,xsize^[i],2);inc(xsize^[i]); BlockRead(F,ysize^[i],2);inc(ysize^[i]); Seek(F,FilePos(F)-4); BlockRead(F,Frames^[i]^,FrameSize^[i]); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Masks^[i],FrameSize^[i]); BlockRead(F,Masks^[i]^,FrameSize^[i]); end; Close(F); CurFrame := 0; end;{tExpl.Init} {----} Procedure tExpl.Frame; begin if started then begin LocTime := LocTime + t; CurFrame := round((LocTime / LifeTime) * (FramesCount-1)) mod FramesCount; if LocTime >= LifeTime then World^.Gone(@Self); end; end;{tRAH.Frame} {----} Procedure tExpl.Draw; var Top,Left : word; begin Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1)); Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1)); if (Top=TRES_MY) or (Left=TRES_MX) then exit; PutImage(Left,Top,Masks^[CurFrame]^,AndPut); PutImage(Left,Top,Frames^[CurFrame]^,OrPut); end;{tExpl.Draw} {----} Destructor tExpl.Done; var i:byte; begin for i := 0 to FramesCount-1 do begin FreeMem(Frames^[i],FrameSize^[i]); FreeMem( Masks^[i],FrameSize^[i]); end; FreeMem(Frames,FramesCount*sizeof(Pointer)); FreeMem(Masks ,FramesCount*sizeof(Pointer)); FreeMem(FrameSize,FramesCount*sizeof(Word)); FreeMem(xsize,FramesCount*sizeof(Word)); FreeMem(ysize,FramesCount*sizeof(Word)); Inherited Done; end; {tExpl.Done} { Fourth object - Heat Trap } Constructor tTrap.Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte); var F:file; i:integer; begin Inherited Init; ObjType := 'HeatTrap'; Flag := Flag + [HEAT]; Params.Pos := aPos; Params.Accel.x:=0; Params.Accel.y:=-aG; Params.Speed.x := aSpeed * cos (aAng/M_360_2PI); Params.Speed.y := aSpeed * sin (aAng/M_360_2PI); ZOrder := zOrd; Assign(F,AnimDat); {$I-} Reset(F,1); If IOResult <> 0 then begin CloseGraph; WriteLn('Error opening animation library for Heat Trap (',AnimDat,')'); Halt(255); end; {$I+} BlockRead(F,FramesCount,2); GetMem(Frames,FramesCount*sizeof(Pointer)); GetMem(xsize,FramesCount*sizeof(Word)); GetMem(ysize,FramesCount*sizeof(Word)); GetMem(FrameSize,FramesCount*sizeof(Word)); for i := 0 to FramesCount-1 do begin BlockRead(F,FrameSize^[i],2); if MaxAvail < FrameSize^[i] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail); Halt(255); end; GetMem(Frames^[i],FrameSize^[i]); BlockRead(F,xsize^[i],2);inc(xsize^[i]); BlockRead(F,ysize^[i],2);inc(ysize^[i]); Seek(F,FilePos(F)-4); BlockRead(F,Frames^[i]^,FrameSize^[i]); end; Close(F); end; {----------} Function tTrap.Inside; begin with params.pos do Inside := (sqr(aPos.x-x) + sqr(aPos.y-y)) <= sqr(xsize^[0] shr 1); end;{tTrap.Inside} {---------------------} Procedure tTrap.Frame(t : longint); begin with Params do begin Speed.x := Speed.x+Accel.x*t*TIME_FACTOR; Speed.y := Speed.y+Accel.y*t*TIME_FACTOR; Pos.x := Pos.x + Speed.X*t*TIME_FACTOR; Pos.y := Pos.y + Speed.y*t*TIME_FACTOR; if not ((Pos.X>TRES_LX) and (Pos.XTRES_LY) and (Pos.YTRES_MX) and ((Speed.X>0) or (Accel.X>0))) or ((Pos.xTRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or ((Pos.y=TRES_MY) or (Left=TRES_MX) then exit; PutImage(Left,Top,Frames^[CurFrame]^,AndPut); end; Destructor tTrap.Done; var i : byte; begin for i := 0 to FramesCount-1 do FreeMem(Frames^[i],FrameSize^[i]); FreeMem(Frames,FramesCount*sizeof(Pointer)); FreeMem(FrameSize,FramesCount*sizeof(Word)); FreeMem(xsize,FramesCount*sizeof(Word)); FreeMem(ysize,FramesCount*sizeof(Word)); Inherited Done; end; { ------ WOLRD OBJECT ( управляет всем ) --------} Constructor TWorld.Init; var F: FILE; k:byte; begin New(WObjects); {Init Dummy Element in Objectlist} WObjects^.Next:=nil; WObjects^.O:=nil; MSG := ''; ToGone:=nil; Ending := false; {Global variable showing need to end} if aBGN <> '' then begin Assign(F,aBGN); {$I-} Reset(F,1); If IOResult <> 0 then exit; {$I+} BlockRead(F,FrameCount,1); GetMem(Background, FrameCount*sizeof(Pointer)); GetMem(xpos, FrameCount*sizeof(word)); GetMem(ypos, FrameCount*sizeof(word)); GetMem(xsize, FrameCount*sizeof(word)); GetMem(ysize, FrameCount*sizeof(word)); GetMem(FrameSize, FrameCount*sizeof(word)); for k:=0 to FrameCount-1 do begin BlockRead(F,FrameSize^[k],2); BlockRead(F,xPos^[k],2); BlockRead(F,yPos^[k],2); BlockRead(F,xSize^[k],2); BlockRead(F,ySize^[k],2); if MaxAvail < FrameSize^[k] then begin CloseGraph; WriteLn('Sorry, not enough memory, need ',FrameSize^[k],' get ',MaxAvail); Halt(255); end; GetMem( BackGround^[k], FrameSize^[k]); BlockRead(F,BackGround^[k]^,FrameSize^[k]); DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],CurPage,BackGround^[k]); end; Close(F); end else BackGround := nil; end;{TWorld.Init} {------} Function TWorld.Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject; var mo : PWorldObject; md,a,b : real; Ang : integer; aa : integer; c : PWOsList; begin Radar := nil; if (aSelf = nil) or (WObjects^.next = nil) then exit; md := 1E30; mo := nil; c:=Wobjects^.next; while (c<>nil) do begin if (aFLG in c^.o^.flag) then begin a:=c^.o^.params.pos.x-aSelf^.params.pos.x; b:=c^.o^.params.pos.y-aSelf^.params.pos.y; {} if abs(a) < 0.001 then begin if b > 0 then Ang := 90 else Ang := 270; end else Ang := round(M_360_2PI*ArcTan(b/a)); if Ang < 0 then Inc(Ang,360); if a < 0 then Inc(Ang, 180); if Ang >= 360 then Dec(Ang, 360); {} Ang := aSelf^.Angle - Ang; if Ang > 180 then Ang := 360 - Ang; if Ang <-180 then Ang :=-360 - Ang; if (Ang>a0) and (Ang nil) and {Пока не последний эл-т,} (aOb^.ZORDER > c^.next^.o^.ZORDER) {и выполняется отсортированность} do c:=c^.next; n^.next := c^.next; {Вставляем наш эл-т между "бегунком"} c^.next := n; {и следующим за ним} AddObject:=true; end; {------} Procedure TWorld.Gone; var N : PWOsList; begin New(N); N^.O := aObj; n^.Next:=ToGone; ToGone := n; end; {------} Function TWorld.RemoveObject(aOb:PWorldObject):boolean; var c,g : PWOsList; begin C:=WObjects; while (C^.next <> nil) and (c^.next^.o <> aOb) do c:=c^.next; if c^.next <> nil then begin RemoveObject:=true; g := c^.next; c^.next := g^.next; Dispose(g^.O,Done); Dispose(g); end else RemoveObject := false; end;{TWorld.RemoveObject} {----------------------------} Procedure TWorld.Frame; var c,c2 : PWOsList; ob : PDrawable; begin c := ToGone; {Killing dead objects} while c<>nil do begin RemoveObject(c^.o); c2:=c^.next; dispose(c); c:=c2; end; ToGone:=nil; c:=WObjects^.Next; if c = nil then Ending:=true; while c <> nil do begin C^.O^.Frame(t); C:=C^.next; end; end;{TWorld.Frame} {----------------------------} Procedure TWorld.Message; begin MSG := aS; MSGSize:=aSize; MSGColor:=aColor; end;{TWorld.Message} {----------------------------} Procedure TWorld.Draw; var c : PWOsList; k : byte; begin for k := 0 to FrameCount-1 do DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],1-CurPage,BackGround^[k]); If MSG <> '' then begin setColor(MSGColor); SetTextStyle(DefaultFont, HorizDir, MSGSize); SetTextJustify(CENTERTEXT,BOTTOMTEXT); OutTextXY(TRES_MX shr 1, TRES_MY,MSG); end; c:=WObjects^.Next; while c <> nil do begin if CAN_DRAW IN C^.O^.Flag then PDrawable(C^.O)^.Draw; C:=C^.next; end; end;{TWorld.Draw} {----------------------------} {----------------------------} Procedure TWorld.StartObjects; var c : PWOsList; begin c:=WObjects^.Next; while c <> nil do begin if CAN_DRAW IN C^.O^.Flag then if c^.o^.ObjType = aT then PDrawable(C^.O)^.Started := true; C:=C^.next; end; end;{TWorld.Draw} {----------------------------} Destructor TWorld.Done; var g:PWOsList; i:byte; begin while WObjects <> nil do begin g := WObjects^.next; if WObjects^.o <> nil then Dispose(WObjects^.o,Done); Dispose(WObjecTs); WObjects := g; end; while ToGone <> nil do begin g := ToGone^.next; Dispose(ToGone^.o,Done); Dispose(ToGone); ToGone := g; end; if BackGround <> nil then begin for i := 0 to FrameCount-1 do FreeMem(Background^[i],FrameSize^[i]); FreeMem(Background,FrameCount*sizeof(Pointer)); FreeMem(xpos,FrameCount*sizeof(word)); FreeMem(ypos,FrameCount*sizeof(word)); FreeMem(xsize,FrameCount*sizeof(word)); FreeMem(ysize,FrameCount*sizeof(word)); FreeMem(FrameSize,FrameCount*sizeof(word)); end; end; {TWorld.Done} {---------------------------------------------} {------ OTHER PROCEDURES ---------------} END.