OBJECTS2.PAS 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997
  1. {$R-}
  2. Unit Objects2;
  3. {‡¤¥áì ­ å®¤ïâáï ¢á¥ ®¡ê¥ªâë (ª« ááë) ¨á¯®«ì§ã¥¬ë¥ ¢ ¯à®£à ¬¬¥}
  4. {‚¥àá¨ï 2-ï, ¨á¯®«ì§ã¥âáï áâà ­¨æë}
  5. INTERFACE
  6. Uses Graph, Draw10H;
  7. type
  8. FLAG_ENUM = (NONE,CAN_DRAW,HEAT);
  9. FLAGS = set of FLAG_ENUM;
  10. Const
  11. M_360_2PI = 360/(2*Pi);
  12. GLOB_G : real = 0.01;
  13. FIELD_X : word = 600;
  14. TRES_LX : word = 10;
  15. TRES_MX : word = 630;
  16. TRES_LY : word = 10;
  17. TRES_MY : word = 340;
  18. SIZE_Y : word = 350;
  19. FPS : WORD = 1;
  20. TIME_FACTOR : real = 0.1;
  21. type
  22. {Globals}
  23. Vector = record
  24. x,y : real;
  25. end;
  26. TSprites = array [0..(65536 shr 2)-2] of Pointer;
  27. PSprites = ^TSprites;
  28. TWordArray = array [0..(65536 shr 1)-2] of word;
  29. PWordArray = ^TWordArray;
  30. TByteArray = array [0..65534] of Byte;
  31. PByteArray = ^TByteArray;
  32. TParams = record
  33. Pos,Speed,Accel : Vector;
  34. end;
  35. PWorld = ^TWorld;
  36. { MAIN OBJECT (Global Parent) }
  37. PWorldObject = ^TWorldObject;
  38. TWorldObject = object
  39. ObjType : string[20];
  40. Flag : FLAGS;
  41. World : PWorld;
  42. LocTime : LONGINT;
  43. Params : TParams;
  44. Angle : integer;
  45. ZORDER : Byte;
  46. Started : boolean;
  47. Constructor Init;
  48. Procedure Frame(t:longInt);virtual; {�à®æ¥¤ãà , ¢ë¯®«­ï¥¬ ï ­  ª ¦¤®¬
  49. è £¥, t - ¢à¥¬ï í⮣® è £  (®â१®ª)
  50. „«ï  ¡á®«îâ­®á⨠¢à¥¬¥­¨}
  51. Destructor Done;virtual;
  52. end;
  53. pDrawable = ^tDrawAble;
  54. tDrawable = object (TWorldObject)
  55. Frames : Psprites;
  56. FramesCount : integer;
  57. FrameSize : PWordArray;
  58. xsize,ysize : PWordArray;
  59. CurFrame : integer;
  60. Constructor Init;
  61. Procedure Draw;virtual;
  62. Function Inside(aPos:Vector):boolean;virtual;
  63. end;
  64. pRAH = ^tRAH;
  65. tRAH = object (TDrawable)
  66. Masks : Psprites;
  67. FileCount : integer;
  68. NextTrap : longint;
  69. FrameTime : longint;
  70. TrapBase, TrapVar : longint;
  71. SpeedBase, SpeedVar : longint;
  72. CountBase, CountVar : integer;
  73. A,B : Vector;
  74. Constructor Init(AnimDat:string;aPar : TParams;Zord:byte);
  75. Procedure DropTraps(aCount:byte);
  76. Procedure Frame(t : longint);virtual;
  77. Procedure Draw;virtual;
  78. Function Inside(aPos:Vector):boolean;virtual;
  79. Destructor Done;virtual;
  80. end;
  81. pTrap = ^tTrap;
  82. tTrap = object(TDrawable)
  83. Constructor Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte);
  84. Procedure Frame(t : longint);virtual;
  85. Procedure Draw;virtual;
  86. Function Inside(aPos:Vector):boolean;virtual;
  87. Destructor Done;virtual;
  88. end;
  89. pSting = ^tSting;
  90. tSting = object (TDrawable)
  91. dAngle : integer;
  92. Nose : Vector;
  93. Constructor Init(AnimDat:string;aPar : TParams;adAng:integer;Zord:byte);
  94. Procedure GetAngle;
  95. Procedure FindTarget(aDa:integer);
  96. Procedure ChangeAngle(dA : integer);
  97. Procedure Frame(t : longint);virtual;
  98. Procedure Draw;virtual;
  99. Destructor Done;virtual;
  100. end;
  101. pExpl = ^tExpl;
  102. tExpl = object (TDrawAble)
  103. Masks : Psprites;
  104. LifeTime : Longint;
  105. Constructor Init(AnimDat:string;aLifeTime:longint;aPos:vector;Zord:byte);
  106. Procedure Frame(t : longint);virtual;
  107. Procedure Draw;virtual;
  108. Destructor Done;virtual;
  109. end;
  110. { - - - - - - - - - - - - - - - -}
  111. PWOsList = ^TWOsList;
  112. TWOsList = record
  113. o : PworldObject;
  114. next : PWOsLIst;
  115. end;
  116. TWorld = object
  117. Ending : boolean;
  118. MSG : string;
  119. MSGSize : word;
  120. MSGColor : byte;
  121. Procedure Gone(aObj : PWorldObject); {Objects, that needs to be killed}
  122. Constructor Init(aBGn : string); {aBGN - BackGround fileName}
  123. Procedure Draw;
  124. Procedure Frame(t:longint);
  125. Function Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject;
  126. Procedure StartObjects(aT:string);
  127. Procedure Explosion(aPos:vector);
  128. Procedure Message(aS:string;aSize:word;aColor:byte);
  129. Function AddObject(aOb : PWorldObject):boolean;
  130. Function RemoveObject(aOb:PWorldObject):boolean;
  131. Destructor Done;
  132. private
  133. WObjects : PWOsList;
  134. ToGone : PWOsList; {‘⥪ ®¡ê¥ªâ®¢ ­  "㡨©á⢮"}
  135. { BackGround }
  136. xpos, ypos : PWordArray;
  137. xsize,ysize : PWordArray;
  138. FrameCount : Byte;
  139. BackGround : Psprites;
  140. FrameSize : PWordArray;
  141. {}
  142. end;
  143. {----------- END OF OBJECTS ----------------------}
  144. IMPLEMENTATION
  145. { TWorldObject Dummy }
  146. {------------------------------------------}
  147. Constructor TworldObject.Init;
  148. begin
  149. ObjType := 'dummy';
  150. Flag := [NONE];
  151. Zorder := 0;
  152. LocTime := 0;
  153. Started := false;
  154. end;{TworldObject.Init}
  155. {----}
  156. Procedure TWorldObject.Frame;
  157. begin {Nothing here now}
  158. end; {TWorldObject.Frame}
  159. {----}
  160. Destructor TWorldObject.Done;
  161. begin {Nothing here now}
  162. end; {TWorldObject.Done}
  163. {----}
  164. Constructor TDrawable.Init;
  165. begin
  166. Inherited Init;
  167. Flag := Flag + [CAN_DRAW];
  168. Frames:=nil;
  169. FramesCount:=0;
  170. FrameSize:=nil;
  171. xsize:=nil;ysize:=nil;
  172. CurFrame:=0;
  173. end;{TDrawable.Init}
  174. {----}
  175. Procedure TDrawable.Draw;
  176. begin
  177. end;{TDrawable.Draw}
  178. Function TDrawable.Inside;
  179. begin
  180. Inside:=false;
  181. end;{TDrawable.Inside}
  182. {------------------------------------------}
  183. { First object - Helicopter Commanche RAH-66}
  184. Constructor tRAH.Init;
  185. var
  186. i : byte;
  187. F : FILE;
  188. begin
  189. Inherited Init;
  190. Randomize;
  191. FLAG := FLAG + [HEAT] - [NONE];
  192. ObjType := 'RAH-66';
  193. TrapBase := 100;
  194. TrapVar := 30;
  195. { NextTrap := TrapBase + random(TrapVar) - (TrapVar shr 1);}
  196. Params := aPar;
  197. ZOrder := zOrd;
  198. Assign(F,AnimDat);
  199. {$I-}
  200. Reset(F,1);
  201. If IOResult <> 0 then
  202. begin
  203. CloseGraph;
  204. WriteLn('Error opening animation library for RAH-66 (',AnimDat,')');
  205. Halt(255);
  206. end;
  207. {$I+}
  208. BlockRead(F,FileCount,2);
  209. FramesCount := (FileCount-1)*2;
  210. GetMem(Frames, FramesCount*sizeof(Pointer));
  211. GetMem(Masks, FramesCount*sizeof(Pointer));
  212. GetMem(xsize, FramesCount*sizeof(Word));
  213. GetMem(ysize, FramesCount*sizeof(Word));
  214. GetMem(FrameSize,FramesCount*sizeof(Word));
  215. for i := 0 to FileCount-1 do
  216. begin
  217. BlockRead(F,FrameSize^[i],2);
  218. if MaxAvail < FrameSize^[i] then
  219. begin
  220. CloseGraph;
  221. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  222. Halt(255);
  223. end;
  224. GetMem(Frames^[i],FrameSize^[i]);
  225. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  226. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  227. Seek(F,FilePos(F)-4);
  228. BlockRead(F,Frames^[i]^,FrameSize^[i]);
  229. if MaxAvail < FrameSize^[i] then
  230. begin
  231. CloseGraph;
  232. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  233. Halt(255);
  234. end;
  235. GetMem(Masks^[i],FrameSize^[i]);
  236. BlockRead(F,Masks^[i]^,FrameSize^[i]);
  237. end;
  238. A.X := -(xsize^[0] shr 1);
  239. B.X := xsize^[0] shr 1;
  240. A.Y := -(ysize^[0] shr 1);
  241. B.Y := ysize^[0] shr 1;
  242. for i := FileCount to FramesCount-1 do
  243. begin
  244. Frames^[i] := Frames^[FramesCount-i];
  245. Masks^[i] := Masks^[FramesCount-i];
  246. FrameSize^[i] := FrameSize^[FramesCount-i];
  247. xsize^[i] := xsize^[FramesCount-i];
  248. ysize^[i] := ysize^[FramesCount-i];
  249. end;
  250. Close(F);
  251. CurFrame := 0;
  252. end;{tRAH.Init}
  253. {----}
  254. Function tRAH.Inside;
  255. begin
  256. with Params.pos do
  257. Inside := (aPos.x > A.X+X) and (aPos.x < B.X+X) and
  258. (aPos.y > A.y+y) and (aPos.y < B.y+y);
  259. end;{tRAH.Inside}
  260. {----------------------}
  261. Procedure tRAH.Frame;
  262. begin
  263. if started then
  264. begin
  265. with Params do begin
  266. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  267. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  268. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  269. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  270. if Pos.x > FIELD_X then
  271. World^.Gone(@Self);
  272. end;
  273. LocTime := LocTime + t;
  274. inc(FrameTime,t);
  275. if LocTime > NextTrap then
  276. begin
  277. DropTraps(CountBase + random(Countvar)-(countvar shr 1));
  278. NextTrap := LocTime + TrapBase + random(TrapVar) - (TrapVar shr 1);
  279. end;
  280. end;
  281. end;{tRAH.Frame}
  282. {-----}
  283. Procedure tRAH.DropTraps;
  284. var
  285. aNewTrap : pTrap;
  286. i : byte;
  287. nspeed : real;
  288. nangle : integer;
  289. begin
  290. Randomize;
  291. for i := 1 to aCount do
  292. begin
  293. nangle := random(360);
  294. nspeed := speedBase + random*SpeedVar - (SpeedVar shr 1);
  295. New(aNewTrap,Init('trap.dat',Params.pos,nspeed,GLOB_G,nangle,Zorder+random(11)-5));
  296. World^.AddObject(aNewTrap);
  297. end;
  298. end;{tRAH.DropTrap}
  299. {----}
  300. Procedure tRAH.Draw;
  301. var
  302. Top,Left : word;
  303. begin
  304. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  305. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  306. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  307. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  308. exit;
  309. PutImage(Left,Top,Masks^[CurFrame]^,AndPut);
  310. PutImage(Left,Top,Frames^[CurFrame]^,OrPut);
  311. CurFrame := (CurFrame+FrameTime div FPS) mod FramesCount;
  312. FrameTime := FrameTime mod FPS;
  313. end;{tRAH.Draw}
  314. {----}
  315. Destructor tRAH.Done;
  316. var
  317. i:byte;
  318. begin
  319. for i := 0 to FileCount-1 do
  320. begin
  321. FreeMem(Frames^[i],FrameSize^[i]);
  322. FreeMem( Masks^[i],FrameSize^[i]);
  323. end;
  324. FreeMem(Frames,FramesCount*sizeof(Pointer));
  325. FreeMem( Masks,FramesCount*sizeof(Pointer));
  326. FreeMem(FrameSize,FramesCount*sizeof(Word));
  327. FreeMem(xsize,FramesCount*sizeof(Word));
  328. FreeMem(ysize,FramesCount*sizeof(Word));
  329. Inherited Done;
  330. end; {tRAH.Done}
  331. {-------------------------------------------------}
  332. { Second object - rocket earth-air Stinger (hand-made) :) }
  333. Constructor tSting.Init;
  334. var
  335. i : byte;
  336. F : FILE;
  337. begin
  338. Inherited Init;
  339. ObjType := 'Stinger';
  340. Params := aPar;
  341. ZOrder := zOrd;
  342. dAngle := adAng;
  343. GetAngle;
  344. Nose.x:=Params.pos.x + xsize^[0]/2*cos(Angle/M_360_2PI);
  345. Nose.y:=Params.pos.y + xsize^[0]/2*sin(Angle/M_360_2PI);
  346. Assign(F,AnimDat);
  347. {$I-}
  348. Reset(F,1);
  349. If IOResult <> 0 then
  350. begin
  351. CloseGraph;
  352. WriteLn('Error opening animation library for Stinger (',AnimDat,')');
  353. Halt(255);
  354. end;
  355. {$I+}
  356. BlockRead(F,FramesCount,2);
  357. GetMem(Frames,FramesCount*sizeof(Pointer));
  358. GetMem(xsize,FramesCount*sizeof(Word));
  359. GetMem(ysize,FramesCount*sizeof(Word));
  360. GetMem(FrameSize,FramesCount*sizeof(Word));
  361. for i := 0 to FramesCount-1 do
  362. begin
  363. BlockRead(F,FrameSize^[i],2);
  364. if MaxAvail < FrameSize^[i] then
  365. begin
  366. CloseGraph;
  367. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  368. Halt(255);
  369. end;
  370. GetMem(Frames^[i],FrameSize^[i]);
  371. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  372. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  373. Seek(F,FilePos(F)-4);
  374. BlockRead(F,Frames^[i]^,FrameSize^[i]);
  375. end;
  376. Close(F);
  377. CurFrame := (Angle div (360 div FramesCount));
  378. if CurFrame < 0 then inc(curframe,FramesCount);
  379. end;{tSting.Init}
  380. {----}
  381. Procedure tSting.ChangeAngle(dA : integer);
  382. var
  383. speed : real;
  384. begin
  385. Angle := dA;
  386. while Angle < 0 do Inc(Angle,360);
  387. while Angle > 360 do dec(Angle,360);
  388. speed := sqrt(sqr(params.speed.x)+sqr(params.speed.y));
  389. Params.Speed.x := Speed * cos(Angle/M_360_2PI);
  390. Params.Speed.y := Speed * sin(Angle/M_360_2PI);
  391. end;
  392. Procedure tSting.FindTarget;
  393. var
  394. ang:integer;
  395. dist : real;
  396. ob : PWorldObject;
  397. begin
  398. ang:=-ada;
  399. ob := World^.Radar(@Self,HEAT,ang,-ang,dist);
  400. if (ob <> nil) then
  401. begin
  402. ChangeAngle(ang);
  403. end
  404. else GetAngle;
  405. ang:=-30;
  406. ob := World^.Radar(@Self,HEAT,ang,-ang,dist);
  407. if ob = nil then exit;
  408. if PDrawable(ob)^.Inside(Nose) then
  409. begin
  410. World^.Explosion(ob^.params.pos);
  411. World^.Gone(@Self);
  412. World^.Gone(ob);
  413. if ob^.objtype = 'RAH-66' then World^.Message('You Win',4,LightRed)
  414. else World^.Message('You Lose',4,LightGray);
  415. end;
  416. end;{tSting.FindTarget}
  417. {--------}
  418. Procedure tSting.GetAngle;
  419. begin
  420. if Params.Speed.x = 0 then
  421. begin
  422. if Params.Speed.y > 0 then Angle := 90 else
  423. Angle := 270;
  424. end else
  425. Angle := round(M_360_2PI*ArcTan(Params.Speed.y/Params.Speed.x));
  426. if Angle < 0 then Inc(Angle,360);
  427. if Params.Speed.X < 0 then Inc(Angle, 180);
  428. if Angle >= 360 then Dec(Angle, 360);
  429. end;{tSting.GetAngle}
  430. {------}
  431. Procedure tSting.Frame;
  432. begin
  433. if started then
  434. begin
  435. with Params do begin
  436. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  437. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  438. FindTarget(dAngle);
  439. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  440. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  441. if not ((Pos.X>TRES_LX) and (Pos.X<TRES_MX) and
  442. (Pos.Y>TRES_LY) and (Pos.Y<TRES_MY)) then
  443. if (((Pos.x>TRES_MX) and ((Speed.X>0) or (Accel.X>0))) or
  444. ((Pos.x<TRES_LX) and ((Speed.X<0) or (Accel.X<0))) or
  445. ((Pos.y>TRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or
  446. ((Pos.y<TRES_LY) and ((Speed.Y<0) or (Accel.Y<0))))
  447. then
  448. World^.Gone(@Self);
  449. LocTime := LocTime + t;
  450. end;
  451. end;
  452. end;{tSting.Frame}
  453. {----}
  454. Procedure tSting.Draw;
  455. var
  456. Top,Left : integer;
  457. x12,x22,y12,y22 : real;
  458. begin
  459. CurFrame := (Angle div (360 div FramesCount));
  460. if CurFrame < 0 then inc(curframe,FramesCount);
  461. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  462. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  463. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  464. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  465. exit;
  466. PutImage(Left,Top,Frames^[CurFrame]^,AndPut);
  467. Nose.x:=params.pos.x + xsize^[0]/2.1*cos(Angle/M_360_2PI);
  468. Nose.y:=params.pos.y + xsize^[0]/2.1*sin(Angle/M_360_2PI);
  469. x12:=Nose.x + 50*cos((Angle-dAngle)/M_360_2PI);
  470. y12:=Nose.y + 50*sin((Angle-dAngle)/M_360_2PI);
  471. x22:=Nose.x + 50*cos((Angle+dAngle)/M_360_2PI);
  472. y22:=Nose.y + 50*sin((Angle+dAngle)/M_360_2PI);
  473. SetColor(Black);
  474. Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x12),SIZE_Y-round(y12));
  475. Line(round(Nose.x),SIZE_Y-round(Nose.y),round(x22),SIZE_Y-round(y22));
  476. end;{tSting.Draw}
  477. {----}
  478. Destructor tSting.Done;
  479. var
  480. i:byte;
  481. begin
  482. for i := 0 to FramesCount-1 do
  483. FreeMem(Frames^[i],FrameSize^[i]);
  484. FreeMem(Frames,FramesCount*sizeof(Pointer));
  485. FreeMem(FrameSize,FramesCount*sizeof(Word));
  486. FreeMem(xsize,FramesCount*sizeof(Word));
  487. FreeMem(ysize,FramesCount*sizeof(Word));
  488. Inherited Done;
  489. end; {tSting.Done}
  490. {-------------------------------------------------}
  491. { Third object - just explosion}
  492. Constructor tExpl.Init;
  493. var
  494. i : byte;
  495. F : FILE;
  496. begin
  497. Inherited Init;
  498. ObjType := 'EXPL';
  499. LifeTime := aLifeTime;
  500. Params.pos := aPos;
  501. ZOrder := zOrd;
  502. Assign(F,AnimDat);
  503. {$I-}
  504. Reset(F,1);
  505. If IOResult <> 0 then
  506. begin
  507. CloseGraph;
  508. WriteLn('Error opening animation library for exposion (',AnimDat,')');
  509. Halt(255);
  510. end;
  511. {$I+}
  512. BlockRead(F,FramesCount,2);
  513. GetMem(Frames, FramesCount*sizeof(Pointer));
  514. GetMem(Masks, FramesCount*sizeof(Pointer));
  515. GetMem(xsize, FramesCount*sizeof(Word));
  516. GetMem(ysize, FramesCount*sizeof(Word));
  517. GetMem(FrameSize,FramesCount*sizeof(Word));
  518. for i := 0 to FramesCount-1 do
  519. begin
  520. BlockRead(F,FrameSize^[i],2);
  521. if MaxAvail < FrameSize^[i] then
  522. begin
  523. CloseGraph;
  524. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  525. Halt(255);
  526. end;
  527. GetMem(Frames^[i],FrameSize^[i]);
  528. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  529. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  530. Seek(F,FilePos(F)-4);
  531. BlockRead(F,Frames^[i]^,FrameSize^[i]);
  532. if MaxAvail < FrameSize^[i] then
  533. begin
  534. CloseGraph;
  535. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  536. Halt(255);
  537. end;
  538. GetMem(Masks^[i],FrameSize^[i]);
  539. BlockRead(F,Masks^[i]^,FrameSize^[i]);
  540. end;
  541. Close(F);
  542. CurFrame := 0;
  543. end;{tExpl.Init}
  544. {----}
  545. Procedure tExpl.Frame;
  546. begin
  547. if started then begin
  548. LocTime := LocTime + t;
  549. CurFrame := round((LocTime / LifeTime) * (FramesCount-1)) mod FramesCount;
  550. if LocTime >= LifeTime then World^.Gone(@Self);
  551. end;
  552. end;{tRAH.Frame}
  553. {----}
  554. Procedure tExpl.Draw;
  555. var
  556. Top,Left : word;
  557. begin
  558. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  559. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  560. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  561. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  562. exit;
  563. PutImage(Left,Top,Masks^[CurFrame]^,AndPut);
  564. PutImage(Left,Top,Frames^[CurFrame]^,OrPut);
  565. end;{tExpl.Draw}
  566. {----}
  567. Destructor tExpl.Done;
  568. var
  569. i:byte;
  570. begin
  571. for i := 0 to FramesCount-1 do
  572. begin
  573. FreeMem(Frames^[i],FrameSize^[i]);
  574. FreeMem( Masks^[i],FrameSize^[i]);
  575. end;
  576. FreeMem(Frames,FramesCount*sizeof(Pointer));
  577. FreeMem(Masks ,FramesCount*sizeof(Pointer));
  578. FreeMem(FrameSize,FramesCount*sizeof(Word));
  579. FreeMem(xsize,FramesCount*sizeof(Word));
  580. FreeMem(ysize,FramesCount*sizeof(Word));
  581. Inherited Done;
  582. end; {tExpl.Done}
  583. { Fourth object - Heat Trap }
  584. Constructor tTrap.Init(AnimDat:string;var aPos:vector; var aSpeed,aG : real; aAng:integer;zOrd:byte);
  585. var
  586. F:file;
  587. i:integer;
  588. begin
  589. Inherited Init;
  590. ObjType := 'HeatTrap';
  591. Flag := Flag + [HEAT];
  592. Params.Pos := aPos;
  593. Params.Accel.x:=0;
  594. Params.Accel.y:=-aG;
  595. Params.Speed.x := aSpeed * cos (aAng/M_360_2PI);
  596. Params.Speed.y := aSpeed * sin (aAng/M_360_2PI);
  597. ZOrder := zOrd;
  598. Assign(F,AnimDat);
  599. {$I-}
  600. Reset(F,1);
  601. If IOResult <> 0 then
  602. begin
  603. CloseGraph;
  604. WriteLn('Error opening animation library for Heat Trap (',AnimDat,')');
  605. Halt(255);
  606. end;
  607. {$I+}
  608. BlockRead(F,FramesCount,2);
  609. GetMem(Frames,FramesCount*sizeof(Pointer));
  610. GetMem(xsize,FramesCount*sizeof(Word));
  611. GetMem(ysize,FramesCount*sizeof(Word));
  612. GetMem(FrameSize,FramesCount*sizeof(Word));
  613. for i := 0 to FramesCount-1 do
  614. begin
  615. BlockRead(F,FrameSize^[i],2);
  616. if MaxAvail < FrameSize^[i] then
  617. begin
  618. CloseGraph;
  619. WriteLn('Sorry, not enough memory, need ',FrameSize^[i],' get ',MaxAvail);
  620. Halt(255);
  621. end;
  622. GetMem(Frames^[i],FrameSize^[i]);
  623. BlockRead(F,xsize^[i],2);inc(xsize^[i]);
  624. BlockRead(F,ysize^[i],2);inc(ysize^[i]);
  625. Seek(F,FilePos(F)-4);
  626. BlockRead(F,Frames^[i]^,FrameSize^[i]);
  627. end;
  628. Close(F);
  629. end;
  630. {----------}
  631. Function tTrap.Inside;
  632. begin
  633. with params.pos do
  634. Inside := (sqr(aPos.x-x) + sqr(aPos.y-y)) <= sqr(xsize^[0] shr 1);
  635. end;{tTrap.Inside}
  636. {---------------------}
  637. Procedure tTrap.Frame(t : longint);
  638. begin
  639. with Params do begin
  640. Speed.x := Speed.x+Accel.x*t*TIME_FACTOR;
  641. Speed.y := Speed.y+Accel.y*t*TIME_FACTOR;
  642. Pos.x := Pos.x + Speed.X*t*TIME_FACTOR;
  643. Pos.y := Pos.y + Speed.y*t*TIME_FACTOR;
  644. if not ((Pos.X>TRES_LX) and (Pos.X<TRES_MX) and
  645. (Pos.Y>TRES_LY) and (Pos.Y<TRES_MY)) then
  646. if (((Pos.x>TRES_MX) and ((Speed.X>0) or (Accel.X>0))) or
  647. ((Pos.x<TRES_LX) and ((Speed.X<0) or (Accel.X<0))) or
  648. ((Pos.y>TRES_MY) and ((Speed.Y>0) or (Accel.Y>0))) or
  649. ((Pos.y<TRES_LY) and ((Speed.Y<0) or (Accel.Y<0))))
  650. then
  651. World^.Gone(@Self);
  652. end;
  653. LocTime := LocTime + t;
  654. end;
  655. Procedure tTrap.Draw;
  656. var
  657. Top,Left : integer;
  658. begin
  659. Left := round(Params.Pos.x-(xsize^[CurFrame] shr 1));
  660. Top := SIZE_Y-round(Params.Pos.y+(ysize^[CurFrame] shr 1));
  661. if (Top<TRES_LY) or ((Top+ysize^[CurFrame])>=TRES_MY) or
  662. (Left<TRES_LX) or ((Left+xsize^[CurFrame])>=TRES_MX) then
  663. exit;
  664. PutImage(Left,Top,Frames^[CurFrame]^,AndPut);
  665. end;
  666. Destructor tTrap.Done;
  667. var i : byte;
  668. begin
  669. for i := 0 to FramesCount-1 do
  670. FreeMem(Frames^[i],FrameSize^[i]);
  671. FreeMem(Frames,FramesCount*sizeof(Pointer));
  672. FreeMem(FrameSize,FramesCount*sizeof(Word));
  673. FreeMem(xsize,FramesCount*sizeof(Word));
  674. FreeMem(ysize,FramesCount*sizeof(Word));
  675. Inherited Done;
  676. end;
  677. { ------ WOLRD OBJECT ( ã¯à ¢«ï¥â ¢á¥¬ ) --------}
  678. Constructor TWorld.Init;
  679. var
  680. F: FILE;
  681. k:byte;
  682. begin
  683. New(WObjects); {Init Dummy Element in Objectlist}
  684. WObjects^.Next:=nil;
  685. WObjects^.O:=nil;
  686. MSG := '';
  687. ToGone:=nil;
  688. Ending := false; {Global variable showing need to end}
  689. if aBGN <> '' then
  690. begin
  691. Assign(F,aBGN);
  692. {$I-}
  693. Reset(F,1);
  694. If IOResult <> 0 then exit;
  695. {$I+}
  696. BlockRead(F,FrameCount,1);
  697. GetMem(Background, FrameCount*sizeof(Pointer));
  698. GetMem(xpos, FrameCount*sizeof(word));
  699. GetMem(ypos, FrameCount*sizeof(word));
  700. GetMem(xsize, FrameCount*sizeof(word));
  701. GetMem(ysize, FrameCount*sizeof(word));
  702. GetMem(FrameSize, FrameCount*sizeof(word));
  703. for k:=0 to FrameCount-1 do
  704. begin
  705. BlockRead(F,FrameSize^[k],2);
  706. BlockRead(F,xPos^[k],2);
  707. BlockRead(F,yPos^[k],2);
  708. BlockRead(F,xSize^[k],2);
  709. BlockRead(F,ySize^[k],2);
  710. if MaxAvail < FrameSize^[k] then
  711. begin
  712. CloseGraph;
  713. WriteLn('Sorry, not enough memory, need ',FrameSize^[k],' get ',MaxAvail);
  714. Halt(255);
  715. end;
  716. GetMem( BackGround^[k], FrameSize^[k]);
  717. BlockRead(F,BackGround^[k]^,FrameSize^[k]);
  718. DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],CurPage,BackGround^[k]);
  719. end;
  720. Close(F);
  721. end
  722. else
  723. BackGround := nil;
  724. end;{TWorld.Init}
  725. {------}
  726. Function TWorld.Radar(aSelf:PWorldObject;aFlg:FLAG_ENUM;var a0:integer;a1:integer;var aDist:real):PWorldObject;
  727. var
  728. mo : PWorldObject;
  729. md,a,b : real;
  730. Ang : integer;
  731. aa : integer;
  732. c : PWOsList;
  733. begin
  734. Radar := nil;
  735. if (aSelf = nil) or (WObjects^.next = nil) then exit;
  736. md := 1E30;
  737. mo := nil;
  738. c:=Wobjects^.next;
  739. while (c<>nil) do
  740. begin
  741. if (aFLG in c^.o^.flag) then
  742. begin
  743. a:=c^.o^.params.pos.x-aSelf^.params.pos.x;
  744. b:=c^.o^.params.pos.y-aSelf^.params.pos.y;
  745. {<Calc angle>}
  746. if abs(a) < 0.001 then
  747. begin
  748. if b > 0 then Ang := 90 else
  749. Ang := 270;
  750. end else
  751. Ang := round(M_360_2PI*ArcTan(b/a));
  752. if Ang < 0 then Inc(Ang,360);
  753. if a < 0 then Inc(Ang, 180);
  754. if Ang >= 360 then Dec(Ang, 360);
  755. {</Calc angle>}
  756. Ang := aSelf^.Angle - Ang;
  757. if Ang > 180 then Ang := 360 - Ang;
  758. if Ang <-180 then Ang :=-360 - Ang;
  759. if (Ang>a0) and (Ang<a1) then
  760. begin
  761. if a*a+b*b < md then
  762. begin
  763. aa := ang;
  764. md := a*a+b*b;
  765. mo := c^.o;
  766. end;
  767. end;
  768. end;
  769. c:=c^.next;
  770. end;
  771. Radar := mo;
  772. a0 := aSelf^.Angle - aa;
  773. aDist := md;
  774. end;{Radar}
  775. {---------}
  776. Procedure TWorld.Explosion(aPos:vector);
  777. var
  778. aNew : PExpl;
  779. begin
  780. New(aNew,Init('expls.dat',round((random(5)+5)/TIME_FACTOR),aPos,255));
  781. AddObject(aNew);
  782. aNew^.Started := true;
  783. end;{TWorld.Explosion}
  784. {---------}
  785. Function TWorld.AddObject(aOb : PWorldObject):boolean;
  786. var
  787. N,C : PWOsList;
  788. begin
  789. New(N);
  790. N^.O := aOb;
  791. n^.Next:=NIL;
  792. aOb^.World := @Self;
  793. c:=WObjects; {ˆ­¨æ. "¡¥£ã­®ª"}
  794. while (c^.next <> nil) and {�®ª  ­¥ ¯®á«¥¤­¨© í«-â,}
  795. (aOb^.ZORDER > c^.next^.o^.ZORDER) {¨ ¢ë¯®«­ï¥âáï ®âá®àâ¨à®¢ ­­®áâì}
  796. do c:=c^.next;
  797. n^.next := c^.next; {‚áâ ¢«ï¥¬ ­ è í«-â ¬¥¦¤ã "¡¥£ã­ª®¬"}
  798. c^.next := n; {¨ á«¥¤ãî騬 §  ­¨¬}
  799. AddObject:=true;
  800. end;
  801. {------}
  802. Procedure TWorld.Gone;
  803. var
  804. N : PWOsList;
  805. begin
  806. New(N);
  807. N^.O := aObj;
  808. n^.Next:=ToGone;
  809. ToGone := n;
  810. end;
  811. {------}
  812. Function TWorld.RemoveObject(aOb:PWorldObject):boolean;
  813. var
  814. c,g : PWOsList;
  815. begin
  816. C:=WObjects;
  817. while (C^.next <> nil) and (c^.next^.o <> aOb) do c:=c^.next;
  818. if c^.next <> nil then
  819. begin
  820. RemoveObject:=true;
  821. g := c^.next;
  822. c^.next := g^.next;
  823. Dispose(g^.O,Done);
  824. Dispose(g);
  825. end
  826. else
  827. RemoveObject := false;
  828. end;{TWorld.RemoveObject}
  829. {----------------------------}
  830. Procedure TWorld.Frame;
  831. var
  832. c,c2 : PWOsList;
  833. ob : PDrawable;
  834. begin
  835. c := ToGone; {Killing dead objects}
  836. while c<>nil do
  837. begin
  838. RemoveObject(c^.o);
  839. c2:=c^.next;
  840. dispose(c);
  841. c:=c2;
  842. end;
  843. ToGone:=nil;
  844. c:=WObjects^.Next;
  845. if c = nil then Ending:=true;
  846. while c <> nil do
  847. begin
  848. C^.O^.Frame(t);
  849. C:=C^.next;
  850. end;
  851. end;{TWorld.Frame}
  852. {----------------------------}
  853. Procedure TWorld.Message;
  854. begin
  855. MSG := aS;
  856. MSGSize:=aSize;
  857. MSGColor:=aColor;
  858. end;{TWorld.Message}
  859. {----------------------------}
  860. Procedure TWorld.Draw;
  861. var
  862. c : PWOsList;
  863. k : byte;
  864. begin
  865. for k := 0 to FrameCount-1 do
  866. DrawSprite12H(xpos^[k],ypos^[k],xsize^[k],ysize^[k],1-CurPage,BackGround^[k]);
  867. If MSG <> '' then
  868. begin
  869. setColor(MSGColor);
  870. SetTextStyle(DefaultFont, HorizDir, MSGSize);
  871. SetTextJustify(CENTERTEXT,BOTTOMTEXT);
  872. OutTextXY(TRES_MX shr 1, TRES_MY,MSG);
  873. end;
  874. c:=WObjects^.Next;
  875. while c <> nil do
  876. begin
  877. if CAN_DRAW IN C^.O^.Flag then PDrawable(C^.O)^.Draw;
  878. C:=C^.next;
  879. end;
  880. end;{TWorld.Draw}
  881. {----------------------------}
  882. {----------------------------}
  883. Procedure TWorld.StartObjects;
  884. var
  885. c : PWOsList;
  886. begin
  887. c:=WObjects^.Next;
  888. while c <> nil do
  889. begin
  890. if CAN_DRAW IN C^.O^.Flag then
  891. if c^.o^.ObjType = aT then PDrawable(C^.O)^.Started := true;
  892. C:=C^.next;
  893. end;
  894. end;{TWorld.Draw}
  895. {----------------------------}
  896. Destructor TWorld.Done;
  897. var
  898. g:PWOsList;
  899. i:byte;
  900. begin
  901. while WObjects <> nil do
  902. begin
  903. g := WObjects^.next;
  904. if WObjects^.o <> nil then Dispose(WObjects^.o,Done);
  905. Dispose(WObjecTs);
  906. WObjects := g;
  907. end;
  908. while ToGone <> nil do
  909. begin
  910. g := ToGone^.next;
  911. Dispose(ToGone^.o,Done);
  912. Dispose(ToGone);
  913. ToGone := g;
  914. end;
  915. if BackGround <> nil then
  916. begin
  917. for i := 0 to FrameCount-1 do
  918. FreeMem(Background^[i],FrameSize^[i]);
  919. FreeMem(Background,FrameCount*sizeof(Pointer));
  920. FreeMem(xpos,FrameCount*sizeof(word));
  921. FreeMem(ypos,FrameCount*sizeof(word));
  922. FreeMem(xsize,FrameCount*sizeof(word));
  923. FreeMem(ysize,FrameCount*sizeof(word));
  924. FreeMem(FrameSize,FrameCount*sizeof(word));
  925. end;
  926. end; {TWorld.Done}
  927. {---------------------------------------------}
  928. {------ OTHER PROCEDURES ---------------}
  929. END.