gravwars.pp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. Program GravityWars;
  2. {A demo for TP 4.0 compability of Graph.
  3. The sources for this game was found on a site that claims to only have
  4. PD stuff with the below header(which was only reindented), and the webmaster
  5. said that everything he published was sent to him with that purpose. We tried
  6. to contact the authors mentioned below via mail over internet, but that
  7. failed. If there is somebody that claims authorship of these programs,
  8. please mail [email protected], and the sources will be removed from our
  9. websites.
  10. ------------------------------------------------------------------------
  11. ORIGINAL Header:
  12. by Sohrab Ismail-Beigi Completed 4/23/89
  13. SYSOP of The 3D Graphics BBS
  14. 300/1200/2400 baud, N-8-1 Full duplex
  15. (201) 444-4154
  16. Turbo Pascal 4.0 source code. Requires VGA 640x480x16 display.
  17. Note: pix=pixels in the comments}
  18. {$ifdef Win32}
  19. {$apptype GUI}
  20. {$endif}
  21. Uses
  22. {$ifdef Win32}
  23. Windows,
  24. WinCrt,
  25. {$else}
  26. Crt,
  27. {$endif}
  28. Graph;
  29. Type
  30. spacecraft=Record {used for ships and pointer}
  31. coffx,coffy,r : longint; {center offsets and radius in pix}
  32. imagex,imagey : longint; {upper left of image}
  33. imagepointr : pointer; {pointer to image data}
  34. imagesize : word; {size in bytes}
  35. end;
  36. planettype=Record
  37. cx,cy,r : longint; {planet center and radius}
  38. d,GM : real; {density and G*M product}
  39. end;
  40. Const
  41. color : array[1..3] of byte=(Red,Green,LightBlue); {colors for planets}
  42. G=0.1; {gravity constant}
  43. bhr=15; {black hole radius}
  44. Esc=#27; {ASCII for Esc}
  45. Return=#13; { " " RETURN}
  46. Var
  47. ship : array[1..2] of spacecraft; {2 ships}
  48. tp,pointr : spacecraft; {tp is temporary, 1 pointer}
  49. pl : array[1..9] of planettype; {the 9 planets}
  50. screen : Record {the game area}
  51. sx,ex,sy,ey,cx,cy,lx,ly : longint; {start x/y, end x/y, center}
  52. end; {x/y, length x/y}
  53. np,GraphDriver,GraphMode : integer; {# of planets}
  54. criticaldist : real; {for escape velocity calc}
  55. playsong : boolean; {play the songs?}
  56. Procedure Init; {initialize everything}
  57. begin
  58. //SetGraphBufSize(10);
  59. GraphDriver:=VGA;
  60. GraphMode:=VGAHi;
  61. {$ifdef Win32}
  62. ShowWindow(GetActiveWindow,0);
  63. {$endif}
  64. InitGraph(GraphDriver,GraphMode,'');
  65. setbkcolor(black);
  66. setviewport(0,0,getmaxx,getmaxy,clipoff);
  67. clearviewport;
  68. SetColor(LightGray);
  69. SetFillStyle(SolidFill,LightGray); {Hull of ships}
  70. Circle(100,100,9);
  71. FloodFill(100,100,LightGray);
  72. Bar(77,98,100,102);
  73. MoveTo(82,98);
  74. LineRel(-3,-8);
  75. LineRel(-13,0); LineRel(0,-3);
  76. LineRel(24,0); LineRel(0,3);
  77. LineRel(-7,0); LineRel(3,8);
  78. FloodFill(83,97,LightGray);
  79. MoveTo(82,101); LineRel(-3,8);
  80. LineRel(-13,0); LineRel(0,3);
  81. LineRel(24,0); LineRel(0,-3);
  82. LineRel(-7,0); LineRel(3,-8);
  83. FloodFill(83,103,LightGray);
  84. MoveTo(200,200); LineRel(5,-5);
  85. LineRel(5,5); LineRel(10,0);
  86. LineRel(5,-8); LineRel(15,0);
  87. LineRel(-6,9); LineRel(6,9);
  88. LineRel(-15,0); LineRel(-5,-7);
  89. LineRel(-10,0); LineRel(-5,5);
  90. LineRel(-6,-7); LineRel(2,-2);
  91. FloodFill(201,201,LightGray);
  92. SetColor(LightRed);
  93. SetFillStyle(SolidFill,LightRed); {Red lights on ships}
  94. Circle(100,100,2);
  95. FloodFill(100,100,LightRed);
  96. Bar(89,87,91,90); Bar(89,109,91,112);
  97. Bar(224,200,226,203); Bar(240,192,242,194);
  98. Bar(240,208,242,210);
  99. SetColor(Yellow);
  100. MoveTo(0,0); LineRel(0,10);
  101. MoveTo(0,0); LineRel(10,0);
  102. MoveTo(0,0); LineRel(15,15); {pointer}
  103. tp.imagesize:=ImageSize(0,0,16,16); {kludge to subdue compiler bug}
  104. GetMem(tp.imagepointr,tp.imagesize);
  105. GetImage(0,0,16,16,tp.imagepointr^);
  106. pointr.imagesize:=ImageSize(0,0,16,16);
  107. GetMem(pointr.imagepointr,pointr.imagesize);
  108. GetImage(0,0,16,16,pointr.imagepointr^); {get pointer}
  109. pointr.coffx:=7;
  110. pointr.coffy:=7;
  111. pointr.r:=9;
  112. ship[1].imagesize:=ImageSize(66,87,110,113);
  113. GetMem(ship[1].imagepointr,ship[1].imagesize);
  114. GetImage(66,87,110,113,ship[1].imagepointr^); {enterprise}
  115. ship[1].coffx:=22; ship[1].coffy:=13; ship[1].r:=26;
  116. ship[2].imagesize:=ImageSize(199,192,242,210);
  117. GetMem(ship[2].imagepointr,ship[2].imagesize);
  118. GetImage(199,192,242,210,ship[2].imagepointr^); {klingon}
  119. ship[2].coffx:=21; ship[2].coffy:=9; ship[2].r:=23;
  120. ClearDevice;
  121. screen.sx:=1;
  122. screen.ex:=638;
  123. screen.sy:=33;
  124. screen.ey:=478;
  125. screen.cx:=(screen.sx+screen.ex) div 2; {initialize screen}
  126. screen.cy:=(screen.sy+screen.ey) div 2; {bounds}
  127. screen.lx:=screen.ex-screen.sx+1;
  128. screen.ly:=screen.ey-screen.sy+1;
  129. criticaldist:=2.0*sqrt(sqr(screen.lx)+sqr(screen.ly)); {critical distance}
  130. playsong:=true; {for escape vel. calc}
  131. end;
  132. Procedure Finish; {free memory and end}
  133. begin
  134. FreeMem(ship[1].imagepointr,ship[1].imagesize);
  135. FreeMem(ship[2].imagepointr,ship[2].imagesize);
  136. FreeMem(pointr.imagepointr,pointr.imagesize);
  137. FreeMem(tp.imagepointr,tp.imagesize);
  138. CloseGraph;
  139. end;
  140. Function InBounds(cx,cy,r:longint):boolean; {is the point with radius}
  141. begin {completely in screen bounds?}
  142. InBounds:=true;
  143. if r<>0 then
  144. if (cx-r<=screen.sx) or (cx+r>=screen.ex) or
  145. (cy-r<=screen.sy) or (cy+r>=screen.ey) then
  146. InBounds:=false
  147. else
  148. if (cx-bhr<=screen.sx) or (cx+bhr>=screen.ex) or
  149. (cy-bhr<=screen.sy) or (cy+bhr>=screen.ey) then
  150. InBounds:=false;
  151. end;
  152. Procedure RandomSetup; {make a random setup}
  153. var i,j : integer;
  154. a,b : longint;
  155. ok : boolean;
  156. begin
  157. Randomize;
  158. np:=Random(9)+1; {random # of planets 1-9}
  159. for i:=1 to np do {pick planet positions}
  160. Repeat
  161. ok:=true;
  162. pl[i].cx:=Random(screen.lx)+screen.sx;
  163. pl[i].cy:=Random(screen.ly)+screen.sy;
  164. pl[i].d:=(Random(3)+2)/2.0;
  165. pl[i].r:=0;
  166. if Random>0.05 then pl[i].r:=Random(70)+20; {5% chance of blackhole}
  167. if pl[i].r<>0 then
  168. pl[i].GM:=G*2*pi*sqr(pl[i].r)*pl[i].d
  169. else
  170. pl[i].GM:=G*2*pi*sqr(30)*1.0;
  171. ok:=InBounds(pl[i].cx,pl[i].cy,pl[i].r);
  172. if (i>1) and (ok) then {any collisions with existing planets?}
  173. for j:=1 to i-1 do
  174. begin
  175. if sqrt(sqr(pl[i].cx-pl[j].cx)+sqr(pl[i].cy-pl[j].cy))<=
  176. pl[i].r+pl[j].r+2*bhr then
  177. ok:=false;
  178. end;
  179. Until ok;
  180. for i:=1 to 2 do {pick ship positions}
  181. Repeat
  182. ok:=true;
  183. ship[i].imagex:=Random(screen.lx div 2)+screen.sx; {enterprise to the}
  184. if i=2 then ship[2].imagex:=ship[i].imagex+screen.lx div 2; {left and}
  185. ship[i].imagey:=Random(screen.ly)+screen.sy; {klingon to the right}
  186. a:=ship[i].imagex+ship[i].coffx; b:=ship[i].imagey+ship[i].coffy;
  187. ok:=InBounds(a,b,ship[i].r);
  188. for j:=1 to np do {any collisions with planets?}
  189. if sqrt(sqr(a-pl[j].cx)+sqr(b-pl[j].cy))<=pl[j].r+ship[i].r+bhr then
  190. ok:=false;
  191. Until ok;
  192. end;
  193. Procedure DrawSetup; {draw current setup}
  194. var i,j : integer;
  195. begin
  196. ClearDevice;
  197. SetColor(White);
  198. Rectangle(screen.sx-1,screen.sy-1,screen.ex-1,screen.ey-1); {game box}
  199. for i:=1 to 2000 do {2000 random stars}
  200. PutPixel(Random(screen.lx)+screen.sx,Random(screen.ly)+screen.sy,White);
  201. for i:=1 to 2 do {2 ships}
  202. PutImage(ship[i].imagex,ship[i].imagey,ship[i].imagepointr^,NormalPut);
  203. for i:=1 to np do {np planets}
  204. if pl[i].r>0 then {normal}
  205. begin
  206. SetColor(color[trunc(pl[i].d*2-1)]);
  207. Circle(pl[i].cx,pl[i].cy,pl[i].r);
  208. SetFillStyle(SolidFill,color[trunc(pl[i].d*2-1)]);
  209. FloodFill(pl[i].cx,pl[i].cy,color[trunc(pl[i].d*2-1)]);
  210. end
  211. else {black hole}
  212. begin
  213. SetColor(Black);
  214. for j:=0 to bhr do
  215. Circle(pl[i].cx,pl[i].cy,j);
  216. end;
  217. end;
  218. Procedure ClearDialogBox; {clear text message area}
  219. begin
  220. SetFillStyle(SolidFill,Black);
  221. Bar(0,0,screen.ex-1,screen.sy-2);
  222. end;
  223. Function GetString:string; {get a string until RETURN is pressed}
  224. var s : string;
  225. c : char;
  226. begin
  227. s:='';
  228. Repeat
  229. c:=ReadKey;
  230. if (c=chr(8)) and (length(s)>0) then {backspace key}
  231. begin
  232. delete(s,length(s),1);
  233. MoveRel(-8,0); {delete last char}
  234. SetFillStyle(SolidFill,Black);
  235. Bar(GetX,GetY,GetX+8,GetY+8);
  236. end
  237. else if c<>Return then
  238. begin
  239. s:=concat(s,c); {get and draw char}
  240. SetColor(LightGray);
  241. OutText(c);
  242. end;
  243. Until c=Return;
  244. GetString:=s;
  245. end;
  246. Procedure PlayGame;
  247. Const number_of_explosion_dots=20; {# dots for explosion with planet surface}
  248. Var vx,vy,vc,x,y,dt,ax,ay,dx,dy,dr,k : real;
  249. v0,angle : array[1..2] of real;
  250. s : string;
  251. ch : char;
  252. i,event,player,winner : integer;
  253. ok,donecritical,offscreen : boolean;
  254. buffer : array[1..number_of_explosion_dots] of Record {for explosion}
  255. x,y,color : integer;
  256. end;
  257. begin
  258. v0[1]:=0; v0[2]:=0; angle[1]:=0; angle[2]:=0;
  259. player:=1;
  260. donecritical:=false;
  261. Repeat {infinite loop}
  262. ClearDialogBox;
  263. SetColor(LightGray);
  264. str(player,s);
  265. s:=concat('Player ',s); {player #}
  266. OutTextXY(0,0,s);
  267. Repeat {get angle}
  268. MoveTo(0,10);
  269. str(angle[player]:3:5,s);
  270. s:=concat('Angle: [',s,']: ');
  271. OutText(s);
  272. s:=GetString;
  273. if (s[1]='Q') or (s[1]='q') then exit;
  274. i:=0;
  275. if s<>'' then Val(s,angle[player],i);
  276. SetFillStyle(SolidFill,Black);
  277. ok:=(i=0) and (angle[player]>=0.0) and (angle[player]<=360);
  278. if not ok then Bar(0,10,screen.ex-1,18);
  279. Until ok;
  280. Repeat {get initial velocity}
  281. MoveTo(0,20);
  282. str(v0[player]:2:5,s);
  283. s:=concat('Initial Velocity: [',s,']: ');
  284. OutText(s);
  285. s:=GetString;
  286. if (s[1]='Q') or (s[1]='q') then exit;
  287. i:=0;
  288. if s<>'' then Val(s,v0[player],i);
  289. SetFillStyle(SolidFill,Black);
  290. ok:=(i=0) and (v0[player]>=0.0) and (v0[player]<=10.0);
  291. if not ok then Bar(0,20,screen.ex-1,28);
  292. Until ok;
  293. k:=pi*angle[player]/180.0; {angle in radians}
  294. vx:=v0[player]*cos(k);
  295. vy:=-v0[player]*sin(k);
  296. x:=ship[player].imagex+ship[player].coffx+ship[player].r*cos(k);
  297. y:=ship[player].imagey+ship[player].coffy-ship[player].r*sin(k);
  298. ClearDialogBox;
  299. MoveTo(round(x),round(y));
  300. SetColor(White);
  301. offscreen:=false;
  302. Repeat {calculate and draw trajectory}
  303. dt:=0.25; {time interval [vel. is in pix/time]}
  304. x:=x+vx*dt; y:=y+vy*dt;
  305. ax:=0; ay:=0;
  306. for i:=1 to np do {calc accel. due to gravity}
  307. begin
  308. dx:=x-pl[i].cx; dy:=y-pl[i].cy; dr:=sqrt(sqr(dx)+sqr(dy));
  309. k:=1/(sqr(dr)*dr);
  310. if pl[i].r<>0 then {normal}
  311. begin
  312. ax:=ax-pl[i].GM*dx*k;
  313. ay:=ay-pl[i].GM*dy*k
  314. end
  315. else {black hole}
  316. begin
  317. ax:=ax-pl[i].GM*dx*(k+sqr(k*dr));
  318. ay:=ay-pl[i].GM*dy*(k+sqr(k*dr));
  319. end;
  320. end;
  321. vx:=vx+ax*dt; vy:=vy+ay*dt;
  322. event:=0;
  323. if keypressed then
  324. event:=1
  325. else if (x>=screen.sx) and (x<=screen.ex) and {in screen bounds?}
  326. (y>=screen.sy) and (y<=screen.ey) then
  327. begin
  328. donecritical:=false;
  329. i:=GetPixel(round(x),round(y));
  330. if (i=color[1]) or (i=color[2]) or (i=color[3]) or
  331. (i=LightRed) or (i=LightGray) then event:=2
  332. else
  333. if offscreen then
  334. MoveTo(round(x),round(y))
  335. else
  336. LineTo(round(x),round(y));
  337. offscreen:=false;
  338. end {off screen}
  339. else if not donecritical then
  340. begin
  341. offscreen:=true; {offscreen and critical distance}
  342. dx:=x-screen.cx; dy:=y-screen.cy; dr:=sqrt(sqr(dx)+sqr(dy));
  343. if dr>=criticaldist then
  344. begin
  345. vc:=(dx*vx+dy*vy)/dr;
  346. k:=0; for i:=1 to np do k:=k+pl[i].GM;
  347. if 0.5*sqr(vc)>=k/dr then {do we have escape velocity?}
  348. event:=3;
  349. end;
  350. end;
  351. Until event<>0;
  352. if event=1 then {a key was pressed for a break}
  353. begin
  354. ClearDialogBox;
  355. ch:=ReadKey; {one already in buffer}
  356. SetColor(LightGray);
  357. OutTextXY(0,0,'Break... Esc to break, any other key to continue');
  358. ch:=ReadKey;
  359. if ch=Esc then exit;
  360. end
  361. else if event=3 then {missile escaped the universe}
  362. begin
  363. ClearDialogBox;
  364. SetColor(LightGray);
  365. OutTextXY(0,0,'Missile left the galaxy...');
  366. delay(2000);
  367. end
  368. else {event=2} {hit something}
  369. begin
  370. if (i=color[1]) or (i=color[2]) or (i=color[3]) then {hit a planet}
  371. begin
  372. for i:=1 to number_of_explosion_dots do {draw explosion}
  373. begin
  374. buffer[i].x:=trunc(x+20*(Random-0.5));
  375. buffer[i].y:=trunc(y+20*(Random-0.5));
  376. buffer[i].color:=GetPixel(buffer[i].x,buffer[i].y);
  377. PutPixel(buffer[i].x,buffer[i].y,LightRed);
  378. delay(25);
  379. end;
  380. delay(1000);
  381. for i:=1 to number_of_explosion_dots do {erase explosion}
  382. PutPixel(buffer[i].x,buffer[i].y,buffer[i].color);
  383. end
  384. else {hit a ship!}
  385. begin
  386. if sqrt(sqr(x-ship[1].imagex-ship[1].coffx)+ {which one won?}
  387. sqr(y-ship[1].imagey-ship[1].coffy))<=ship[1].r+5 then
  388. winner:=2
  389. else winner:=1;
  390. for event:=1 to 100 do {flash the screen}
  391. SetPalette(Black,Random(16));
  392. SetPalette(Black,Black);
  393. for i:=1 to 1000 do {put some white and red points}
  394. begin
  395. k:=Random*2*pi;
  396. event:=Random(3);
  397. if event=0 then
  398. PutPixel(trunc(x+30*Random*cos(k)),trunc(y+30*Random*sin(k)),Black)
  399. else if event=1 then
  400. PutPixel(trunc(x+30*Random*cos(k)),trunc(y+30*Random*sin(k)),Red)
  401. else
  402. PutPixel(trunc(x+20*Random*cos(k)),trunc(y+20*Random*sin(k)),White);
  403. end;
  404. ClearDialogBox;
  405. SetColor(LightGray);
  406. str(winner,s);
  407. s:=concat('Player ',s,' wins!!!'); {announce}
  408. OutTextXY(0,0,s);
  409. if playsong then {play a tune}
  410. begin
  411. Sound(440); delay(150);
  412. Nosound; delay(50);
  413. Sound(440); delay(150);
  414. Sound(554); delay(150);
  415. Sound(659); delay(350);
  416. Sound(554); delay(150);
  417. Sound(659); delay(450);
  418. Nosound; delay(500);
  419. Sound(880); delay(800);
  420. Nosound;
  421. end;
  422. delay(3000);
  423. exit;
  424. end;
  425. end; {if event=3}
  426. Inc(player); if player=3 then player:=1; {next player}
  427. Until true=false; {infinite loop}
  428. end;
  429. Procedure PlayingtheGame; {playing the game menu}
  430. var option : char;
  431. begin
  432. Repeat
  433. ClearDialogBox;
  434. SetColor(LightGray);
  435. OutTextXY(0,0,'1. Random setup 2. Play game Esc quits menu');
  436. OutTextXY(0,10,'Option: ');
  437. option:=ReadKey;
  438. Case option of
  439. '1' : begin
  440. ClearDialogBox;
  441. RandomSetup;
  442. DrawSetup;
  443. end;
  444. '2' : PlayGame;
  445. end;
  446. Until option=Esc;
  447. end;
  448. Procedure Options; {options menu}
  449. var option : char;
  450. begin
  451. Repeat
  452. ClearDialogBox;
  453. SetColor(LightGray);
  454. OutTextXY(0,0,'1. Redraw screen 2. Sound on/off Esc quits menu');
  455. OutTextXY(0,10,'Option: ');
  456. option:=ReadKey;
  457. Case option of
  458. '1' : DrawSetUp;
  459. '2' : playsong:=not playsong;
  460. end;
  461. Until option=Esc;
  462. end;
  463. Procedure InterpKey(c:char; var x,y,coffx,coffy,r:longint;
  464. var jump:integer; var moveit:boolean);
  465. begin {interprets keys for movement of pointer, mainly to save}
  466. Case c of {space due to shared code in many Change routines}
  467. '+' : if jump<49 then Inc(jump,2);
  468. '-' : if jump>2 then Dec(jump,2);
  469. '8' : begin {up}
  470. Dec(y,jump);
  471. if InBounds(x+coffx,y+coffy,r) then
  472. moveit:=true
  473. else
  474. Inc(y,jump);
  475. end;
  476. '2' : begin {down}
  477. Inc(y,jump);
  478. if InBounds(x+coffx,y+coffy,r) then
  479. moveit:=true
  480. else
  481. Dec(y,jump);
  482. end;
  483. '4' : begin {left}
  484. Dec(x,jump);
  485. if InBounds(x+coffx,y+coffy,r) then
  486. moveit:=true
  487. else
  488. Inc(x,jump);
  489. end;
  490. '6' : begin {right}
  491. Inc(x,jump);
  492. if InBounds(x+coffx,y+coffy,r) then
  493. moveit:=true
  494. else
  495. Dec(x,jump);
  496. end;
  497. end; {case c of}
  498. end;
  499. Procedure MoveShip; {move a given ship to a new legal position}
  500. var c : char;
  501. s,jump,j : integer;
  502. x,y,xold,yold,a,b : longint;
  503. legal,moveit : boolean;
  504. begin
  505. ClearDialogBox;
  506. SetColor(LightGray);
  507. OutTextXY(0, 0,'Ships: 1. Enterprise 2. Klingon Esc aborts');
  508. OutTextXY(0,10,'Which ship? '); {get the proper ship}
  509. Repeat
  510. c:=ReadKey;
  511. Until (c='1') or (c='2') or (c=Esc);
  512. if c=Esc then exit;
  513. if c='1' then s:=1 else s:=2;
  514. ClearDialogBox;
  515. OutTextXY(0, 0,'Use cursors to move ship. (Num Lock on) Esc aborts');
  516. OutTextXY(0,10,'Enter to place, + and - to change size of jumps.');
  517. jump:=30;
  518. x:=ship[s].imagex; y:=ship[s].imagey;
  519. Repeat {loop until Esc or somewhere legal}
  520. Repeat {loop until Esc or RETURN}
  521. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  522. (c='+') or (c='-') or (c=Return) or (c=Esc);
  523. moveit:=false; xold:=x; yold:=y;
  524. InterpKey(c,x,y,ship[s].coffx,ship[s].coffy,ship[s].r,jump,moveit);
  525. if moveit then {if can move the image,}
  526. begin
  527. PutImage(xold,yold,ship[s].imagepointr^,XORPut); {erase old}
  528. PutImage(x,y,ship[s].imagepointr^,XORPut); {draw new}
  529. moveit:=false;
  530. end;
  531. Until (c=Return) or (c=Esc);
  532. if c=Esc then {abort}
  533. begin
  534. PutImage(x,y,ship[s].imagepointr^,XORPut);
  535. PutImage(ship[s].imagex,ship[s].imagey,ship[s].imagepointr^,NormalPut);
  536. exit;
  537. end;
  538. a:=x+ship[s].coffx; b:=y+ship[s].coffy;
  539. legal:=InBounds(a,b,ship[s].r); {in bounds?}
  540. for j:=1 to np do {in collision with any planets?}
  541. if sqrt(sqr(a-pl[j].cx)+sqr(b-pl[j].cy))<=pl[j].r+ship[s].r+bhr then
  542. legal:=false;
  543. if not legal then {oops! not legal!}
  544. begin
  545. SetPalette(Black,White);
  546. SetFillStyle(SolidFill,Black);
  547. Bar(0,20,screen.ex,screen.sy-2);
  548. delay(100);
  549. SetPalette(Black,Black);
  550. SetColor(LightGray);
  551. OutTextXY(0,20,'Illegal ship position!');
  552. end;
  553. Until legal;
  554. ship[s].imagex:=x; ship[s].imagey:=y; {ok, place it there}
  555. end;
  556. Procedure MovePlanet; {move a planet}
  557. var c : char;
  558. i,p,jump : integer;
  559. x,y,xold,yold,minr,t,cxorig,cyorig : longint;
  560. moveit,legal : boolean;
  561. begin
  562. ClearDialogBox;
  563. if np=0 then {no planets!}
  564. begin
  565. OutTextXY(0,0,'No planets to move!');
  566. delay(2000);
  567. exit;
  568. end;
  569. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  570. OutTextXY(0,10,'Enter to pick planet, + and - to change size of jumps.');
  571. jump:=30;
  572. x:=100; y:=100; PutImage(x,y,pointr.imagepointr^,XORPut);
  573. Repeat {loop until Esc or RETURN}
  574. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  575. (c='+') or (c='-') or (c=Return) or (c=Esc);
  576. moveit:=false; xold:=x; yold:=y;
  577. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  578. if moveit then
  579. begin
  580. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  581. PutImage(x,y,pointr.imagepointr^,XORPut);
  582. moveit:=false;
  583. end;
  584. Until (c=Return) or (c=Esc);
  585. PutImage(x,y,pointr.imagepointr^,XORPut); {erase pointer}
  586. if c=Esc then exit;
  587. p:=0; minr:=trunc(sqrt(sqr(screen.lx)+sqr(screen.ly)));
  588. for i:=1 to np do {find the closest planet/black hole}
  589. begin
  590. t:=trunc(sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy)));
  591. if t<minr then begin minr:=t; p:=i; end;
  592. end;
  593. SetColor(LightGreen); {clear it out}
  594. Circle(pl[p].cx,pl[p].cy,pl[p].r);
  595. SetFillStyle(SolidFill,Black);
  596. FloodFill(pl[p].cx,pl[p].cy,LightGreen);
  597. SetColor(Black);
  598. Circle(pl[p].cx,pl[p].cy,pl[p].r);
  599. ClearDialogBox;
  600. SetColor(LightGray);
  601. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  602. OutTextXY(0,10,'Enter to place planet center, + - change size of jumps.');
  603. jump:=30;
  604. x:=100; y:=100; PutImage(x,y,pointr.imagepointr^,XORPut);
  605. cxorig:=pl[p].cx; cyorig:=pl[p].cy; {save them as they may change later}
  606. Repeat {loop until Esc or legal position}
  607. Repeat
  608. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  609. (c='+') or (c='-') or (c=Return) or (c=Esc);
  610. moveit:=false; xold:=x; yold:=y;
  611. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  612. if moveit then
  613. begin
  614. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  615. PutImage(x,y,pointr.imagepointr^,XORPut);
  616. moveit:=false;
  617. end;
  618. Until (c=Return) or (c=Esc);
  619. legal:=true;
  620. if c<>Esc then {ok, RETURN pressed}
  621. begin
  622. pl[p].cx:=-1000; pl[p].cy:=-1000; {so it won't collide with itself!}
  623. for i:=1 to np do {any collisions with other planets?}
  624. if sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy))<=pl[i].r+pl[p].r+2*bhr then
  625. legal:=false;
  626. for i:=1 to 2 do {any collisions with other ships?}
  627. if sqrt(sqr(x-ship[i].imagex-ship[i].coffx)+
  628. sqr(y-ship[i].imagey-ship[i].coffy))<=pl[p].r+ship[i].r+bhr
  629. then legal:=false;
  630. end;
  631. if not legal then {oops!}
  632. begin
  633. SetPalette(Black,White);
  634. SetFillStyle(SolidFill,Black);
  635. Bar(0,20,screen.ex,screen.sy-2);
  636. delay(100);
  637. SetPalette(Black,Black);
  638. SetColor(LightGray);
  639. OutTextXY(0,20,'Illegal planet position!');
  640. end;
  641. Until legal;
  642. pl[p].cx:=x; pl[p].cy:=y; {put it there}
  643. if c=Esc then {abort and restore}
  644. begin
  645. pl[p].cx:=cxorig;
  646. pl[p].cy:=cyorig;
  647. end;
  648. DrawSetUp; {redraw screen}
  649. end;
  650. Procedure MakePlanet; {make a planet given center and radius}
  651. var c : char;
  652. i,p,jump : integer;
  653. x,y,xold,yold : longint;
  654. moveit,legal : boolean;
  655. begin
  656. ClearDialogBox;
  657. if np=9 then {too many planets already!}
  658. begin
  659. OutTextXY(0,0,'Can not make any more planets!');
  660. delay(2000);
  661. exit;
  662. end;
  663. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  664. OutTextXY(0,10,'Enter to place center, + and - to change size of jumps.');
  665. jump:=30;
  666. x:=100; y:=100; PutImage(x,y,pointr.imagepointr^,XORPut);
  667. Repeat {loop until a legal center is picked or Esc}
  668. Repeat
  669. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  670. (c='+') or (c='-') or (c=Return) or (c=Esc);
  671. moveit:=false; xold:=x; yold:=y;
  672. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  673. if moveit then
  674. begin
  675. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  676. PutImage(x,y,pointr.imagepointr^,XORPut);
  677. moveit:=false;
  678. end;
  679. Until (c=Return) or (c=Esc);
  680. if c=Esc then exit;
  681. legal:=true;
  682. for i:=1 to np do {any collisions with planets?}
  683. if sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy))<=pl[i].r+2*bhr then
  684. legal:=false;
  685. for i:=1 to 2 do {any collisions with ships?}
  686. if sqrt(sqr(x-ship[i].imagex-ship[i].coffx)+
  687. sqr(y-ship[i].imagey-ship[i].coffy))<=ship[i].r+bhr
  688. then legal:=false;
  689. if not legal then {uh oh!}
  690. begin
  691. SetPalette(Black,White);
  692. SetFillStyle(SolidFill,Black);
  693. Bar(0,20,screen.ex,screen.sy-2);
  694. delay(100);
  695. SetPalette(Black,Black);
  696. SetColor(LightGray);
  697. OutTextXY(0,20,'Illegal planet center!');
  698. end;
  699. Until legal;
  700. p:=np+1; pl[p].cx:=x; pl[p].cy:=y; {ok, store the info}
  701. ClearDialogBox;
  702. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  703. OutTextXY(0,10,'Enter to radius, + and - change size of jumps.');
  704. jump:=30;
  705. Repeat {loop until a legal radius is entered or Esc}
  706. Repeat
  707. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  708. (c='+') or (c='-') or (c=Return) or (c=Esc);
  709. moveit:=false; xold:=x; yold:=y;
  710. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  711. if moveit then
  712. begin
  713. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  714. PutImage(x,y,pointr.imagepointr^,XORPut);
  715. moveit:=false;
  716. end;
  717. Until (c=Return) or (c=Esc);
  718. if c=Esc then exit;
  719. legal:=true;
  720. pl[p].r:=round(sqrt(sqr(x-pl[p].cx)+sqr(y-pl[p].cy))); {find radius}
  721. for i:=1 to np do {planet collisions?}
  722. if sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy))<=pl[p].r+pl[i].r+2*bhr then
  723. legal:=false;
  724. for i:=1 to 2 do {ship collisions?}
  725. if sqrt(sqr(x-ship[i].imagex-ship[i].coffx)+
  726. sqr(y-ship[i].imagey-ship[i].coffy))<=pl[p].r+ship[i].r+bhr
  727. then legal:=false;
  728. if not legal then {oh no!}
  729. begin
  730. SetPalette(Black,White);
  731. SetFillStyle(SolidFill,Black);
  732. Bar(0,20,screen.ex,screen.sy-2);
  733. delay(100);
  734. SetPalette(Black,Black);
  735. SetColor(LightGray);
  736. OutTextXY(0,20,'Illegal planet radius!');
  737. end;
  738. Until legal;
  739. PutImage(x,y,pointr.imagepointr^,XORPut); {kill the pointer}
  740. Inc(np); {actually add the new planet info}
  741. pl[p].d:=1.0; pl[p].GM:=G*2*pi*sqr(pl[p].r)*1.0; {initialize it}
  742. SetColor(color[1]); {draw it}
  743. Circle(pl[p].cx,pl[p].cy,pl[p].r);
  744. SetFillStyle(SolidFill,color[1]);
  745. FloodFill(pl[p].cx,pl[p].cy,color[1]);
  746. end;
  747. Procedure ChangePlanet; {change density [color] of a planet}
  748. var c : char; {will not change black holes}
  749. i,p,jump : integer;
  750. x,y,xold,yold,minr,t : longint;
  751. moveit,legal : boolean;
  752. begin
  753. ClearDialogBox;
  754. legal:=false;
  755. if np>0 then {see if any non-black holes exist}
  756. for i:=1 to np do
  757. if pl[i].r<>0 then legal:=true;
  758. if (np=0) or (not legal) then {sorry!}
  759. begin
  760. OutTextXY(0,0,'No planets to change!');
  761. delay(2000);
  762. exit;
  763. end;
  764. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  765. OutTextXY(0,10,'Enter to pick planet, + and - to change size of jumps.');
  766. jump:=30;
  767. x:=100; y:=100; PutImage(x,y,pointr.imagepointr^,XORPut);
  768. Repeat {repeat until RETURN or Esc}
  769. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  770. (c='+') or (c='-') or (c=Return) or (c=Esc);
  771. moveit:=false; xold:=x; yold:=y;
  772. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  773. if moveit then
  774. begin
  775. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  776. PutImage(x,y,pointr.imagepointr^,XORPut);
  777. moveit:=false;
  778. end;
  779. Until (c=Return) or (c=Esc);
  780. PutImage(x,y,pointr.imagepointr^,XORPut); {kill the pointer}
  781. if c=Esc then exit;
  782. p:=0; minr:=trunc(sqrt(sqr(screen.lx)+sqr(screen.ly)));
  783. for i:=1 to np do {find closest non-black hole planet}
  784. begin
  785. t:=trunc(sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy)));
  786. if (t<minr) and (pl[i].r<>0) then begin minr:=t; p:=i; end;
  787. end;
  788. ClearDialogBox;
  789. OutTextXY(0, 0,'Change to: 1. Red 2. Green 3. Blue Esc aborts');
  790. OutTextXY(0,10,'Option: '); {get a density}
  791. Repeat c:=ReadKey; Until (c='1') or (c='2') or (c='3') or (c=Esc);
  792. if c=Esc then exit;
  793. i:=Ord(c)-48;
  794. pl[p].d:=(i+1)/2.0; {new density}
  795. SetColor(color[i]); {redraw}
  796. Circle(pl[p].cx,pl[p].cy,pl[p].r);
  797. SetFillStyle(SolidFill,color[i]);
  798. FloodFill(pl[p].cx,pl[p].cy,color[i]);
  799. end;
  800. Procedure DeletePlanet; {kill a planet/black hole}
  801. var c : char;
  802. i,p,jump : integer;
  803. x,y,xold,yold,minr,t : longint;
  804. moveit : boolean;
  805. begin
  806. ClearDialogBox;
  807. if np=0 then {nobody there!}
  808. begin
  809. OutTextXY(0,0,'No planets to delete!');
  810. delay(2000);
  811. exit;
  812. end;
  813. OutTextXY(0, 0,'Use cursors to move pointer. (Num Lock on) Esc aborts');
  814. OutTextXY(0,10,'Enter to pick planet, + and - to change size of jumps.');
  815. jump:=30;
  816. x:=100; y:=100; PutImage(x,y,pointr.imagepointr^,XORPut);
  817. Repeat
  818. Repeat c:=ReadKey; Until (c='4') or (c='8') or (c='6') or (c='2') or
  819. (c='+') or (c='-') or (c=Return) or (c=Esc);
  820. moveit:=false; xold:=x; yold:=y;
  821. InterpKey(c,x,y,pointr.coffx,pointr.coffy,pointr.r,jump,moveit);
  822. if moveit then
  823. begin
  824. PutImage(xold,yold,pointr.imagepointr^,XORPut);
  825. PutImage(x,y,pointr.imagepointr^,XORPut);
  826. moveit:=false;
  827. end;
  828. Until (c=Return) or (c=Esc);
  829. PutImage(x,y,pointr.imagepointr^,XORPut);
  830. if c=Esc then exit;
  831. p:=0; minr:=trunc(sqrt(sqr(screen.lx)+sqr(screen.ly)));
  832. for i:=1 to np do {find the closest planet/black hole}
  833. begin
  834. t:=trunc(sqrt(sqr(x-pl[i].cx)+sqr(y-pl[i].cy)));
  835. if t<minr then begin minr:=t; p:=i; end;
  836. end;
  837. if p<9 then {move everybody above the one deleted one down}
  838. for i:=p to np-1 do
  839. pl[i]:=pl[i+1];
  840. Dec(np); {delete}
  841. DrawSetup; {redraw}
  842. end;
  843. Procedure Changes; {changes menu}
  844. var option : char;
  845. begin
  846. Repeat
  847. ClearDialogBox;
  848. SetColor(LightGray);
  849. OutTextXY(0, 0,'1. Move ship 2. Move planet 3. Make planet');
  850. OutTextXY(0,10,'4. Change planet 5. Delete planet Esc quits menu');
  851. OutTextXY(0,20,'Option: ');
  852. option:=ReadKey;
  853. Case option of
  854. '1' : MoveShip;
  855. '2' : MovePlanet;
  856. '3' : MakePlanet;
  857. '4' : ChangePlanet;
  858. '5' : DeletePlanet;
  859. end;
  860. Until option=Esc;
  861. end;
  862. Procedure MainMenu; {main menu}
  863. var option : char;
  864. begin
  865. Repeat
  866. ClearDialogBox;
  867. SetColor(LightGray);
  868. OutTextXY(0,0,'1. Playing the game 2. Options 3. Changes 4. Quit');
  869. OutTextXY(0,10,'Option: ');
  870. option:=ReadKey;
  871. Case option of
  872. '1' : PlayingtheGame;
  873. '2' : Options;
  874. '3' : Changes;
  875. end;
  876. Until option='4';
  877. end;
  878. Procedure Title; {title screen and credits}
  879. begin
  880. SetTextStyle(SansSerifFont,HorizDir,9);
  881. OutTextXY(25,100,'Gravity Wars');
  882. SetTextStyle(SansSerifFont,HorizDir,2);
  883. OutTextXY(300,300,'by Sohrab Ismail-Beigi');
  884. delay(3000);
  885. SetTextStyle(DefaultFont,HorizDir,0);
  886. end;
  887. BEGIN
  888. Init;
  889. Title;
  890. RandomSetup;
  891. DrawSetup;
  892. MainMenu;
  893. Finish;
  894. END.
  895. $Log$
  896. Revision 1.3 2002-09-07 15:06:35 peter
  897. * old logs removed and tabs fixed
  898. }