!*************************** AMUS Program Label ****************************** ! Filename: SHIP.BAS Date: 10/??/90 ! Category: GAMES Hash Code: Version: 1.0(100) ! Initials: WENG/AM Name: Michael Mc Murdie ! Company: Morton & Pitalo, Inc. Telephone #: 9169272400 ! Related Files: SHIP.CMD, AMIGOS STUFF, INKEY.SBR, SLEEP.SBR, ... ! Min. Op. Sys.: AMOSL 1.3B/AMOS32 1.0 Expertise Level: BEG ! Special: not really... ! Description: Just a silly graphical lunar lander game !***************************************************************************** !This is my variation of the lunar lander program. It works as follows: !The Left/Right arrow keys rotate the ship CCW/CW and each rotation !consumes 10 units of fuel. In order to slow the ship press the numbers ! 1 - 9 for variable burn rate of fuel, 1 being the lowest, 9 being the !highest. The point is to land on the landing pad at a slow speed. The ship !will continue to move in the direction it is currently going taking into !account gravity. If you hit the land first you die or if you hit the landing !pad too fast you also die. Right now this is a REAL simple implementation !but in the future I would like to see more variation. Such things as a !variable landscape and location of the landing pad. In addition maybe you !could offer variable gravity, fuel amount and height of mountains based on !level of difficulty. In other words run amuk... ! PROGRAM SHIP,1.0(100) !el numero de version... ++INCLUDE AMGSYM.BSI !grab the AMIGOS defs MAP1 GCB,X,50000 !graphics control block MAP1 PT'ARY !point array data structure MAP2 PT'CT,B,2 !number of points MAP2 PTS(50) !actual point array MAP3 PT'X,B,2 !x values MAP3 PT'Y,B,2 !y values MAP1 OLD'POS MAP2 OLD'CT,B,2 MAP2 OLD'PTS(50) MAP3 OLD'X,B,2 MAP3 OLD'Y,B,2 !surface is the actual surface of the planet we're landing on MAP1 SURFACE !surface to check MAP2 SRF'CT,B,2 !number of points MAP2 SRF'PTS(50) !position of each point MAP3 SRF'X,B,2 MAP3 SRF'Y,B,2 MAP1 SHIP(20,2),F,6 !array to hold the SHIP shape MAP1 FLAME(10,2),F,6 !flame shape MAP1 SHIP'X,F,6 !current SHIP position x MAP1 SHIP'Y,F,6 !current SHIP position y MAP1 SHIP'ANG,F,6,0 !current SHIP angle index MAP1 NO'SHIP'PTS,F,6 !number of points making up the SHIP MAP1 CHAR,S,1 !input character !sine & cosine values are stored in an array to increase speed MAP1 SIN'ARY(72),F,6 !sine values MAP1 COS'ARY(72),F,6 !cosine values MAP1 STAT'STR,S,80 XCALL AMGSBR,G'OPWK,GCB,"",STATUS !open the workstation XCALL AMGSBR,G'SWM,GCB,1,STATUS !set XOR mode XCALL AMGSBR,G'SPLC,GCB,1,STATUS !white lines XCALL AMGSBR,G'SPLT,GCB,1,STATUS !solid lines CALL BUILD'SHIP XCALL NOECHO : ? TAB(-1,29);TAB(-1,0); CALL SHOW'BASE PT'CT = NO'SHIP'PTS OLD'CT = PT'CT !the following segment sets the initial values change them as desired SHIP'X = 2000 : SHIP'Y = 22000 : SHIP'ANG = 17 VEL'X = 400 : VEL'Y = 75 : FUEL = 2000 : BURN = 0 GRAVITY = 10 ? tab(-1,11); ? tab(34,1); ? "Velocity X: Y:";tab(34,31);"Height:";tab(34,46);"Fuel:"; ? TAB(-1,12); INIT'FLAG = 0 : CLK = 0 LOOP: NEW'VEL'Y = VEL'Y - BURN + GRAVITY !get new velocity SHIP'Y = SHIP'Y - 0.5*(NEW'VEL'Y + VEL'Y) !new y position SHIP'X = SHIP'X + VEL'X !new x position VEL'Y = NEW'VEL'Y ? TAB(34,13);VEL'X USING "####"; !show current x velocity ? TAB(34,22);VEL'Y USING "####"; !show current y velocity ? TAB(34,38);SHIP'Y USING "#####"; !show height ? TAB(34,51);FUEL USING "####"; !show fuel left ! ? TAB(34,61);CLK USING "#######"; !show elapsed time BURN = 0 CALL CHECK'COLLISION !how's my driving? CALL SHOW'SHIP !update ship position XCALL INKEY,CHAR !key press waiting? CHAR = UCS(CHAR) IF CHAR=CHR(12) CALL ROTATE'RIGHT IF CHAR=CHR( 8) CALL ROTATE'LEFT IF CHAR >= "0" AND CHAR <= "9" CALL BURN'FUEL IF CHAR="Q" GOTO QUIT'SHIP !quiters never win ... wimp! IF CHAR="" XCALL SLEEP,0.1 !nothing, just snooze... CLK = CLK + 1 GOTO LOOP QUIT'SHIP: CALL ERASE'SHIP XCALL AMGSBR,G'CLWK,GCB,STATUS !close the workstation ? TAB(-1,0);TAB(-1,28); CHAIN "DSK0:COGO[15,1]" !this is only for our system END SHOW'SHIP: !draw the ship at the current x & y position FOR I=1 TO NO'SHIP'PTS ARY'INDEX = SHIP'ANG + SHIP(I,2) IF ARY'INDEX > 72 ARY'INDEX = ARY'INDEX - 72 PT'X(I) = SHIP'X + COS'ARY(ARY'INDEX)*SHIP(I,1) PT'Y(I) = SHIP'Y + SIN'ARY(ARY'INDEX)*SHIP(I,1) NEXT I IF INIT'FLAG XCALL AMGSBR,G'PL,GCB,OLD'POS,STATUS XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS OLD'POS = PT'ARY INIT'FLAG = 1 RETURN !since were using XOR writing mode, just redraw the ship and it disappears... ERASE'SHIP: XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS RETURN ROTATE'LEFT: !rotate ship CCW IF FUEL < 10 RETURN !check GAS FUEL = FUEL - 10 !burn some fuel SHIP'ANG = SHIP'ANG - 2 !change angle by 10 degrees IF SHIP'ANG < 1 SHIP'ANG = SHIP'ANG + 72 !adjust array index RETURN ROTATE'RIGHT: !rotate ship CW IF FUEL < 10 RETURN !any gas left? FUEL = FUEL - 10 !burn some fuel SHIP'ANG = SHIP'ANG + 2 !change angle by 10 degrees IF SHIP'ANG > 72 SHIP'ANG = SHIP'ANG - 72 !adjust index RETURN BUILD'SHIP: !this SHIP array holds the dimensions of the ship. Each measurement is !taken as a distance and an angle from this center point. Each angle !is actually a reference into the sine & cosine arrays. ! SHIP( 1,1) = 500 ... 500 units from center to 1st point ! SHIP( 1,2) = 18 ... 18*5 or 90 degrees from horizontal, references ! 18th position in sine & cosine arrays... !define the SHIP shape SHIP( 1,1) = 500 SHIP( 1,2) = 18 SHIP( 2,1) = 640 SHIP( 2,2) = 42 SHIP( 3,1) = 700 SHIP( 3,2) = 48 SHIP( 4,1) = 480 SHIP( 4,2) = 54 SHIP( 5,1) = 700 SHIP( 5,2) = 60 SHIP( 6,1) = 640 SHIP( 6,2) = 66 SHIP( 7,1) = 500 SHIP( 7,2) = 18 NO'SHIP'PTS = 7 !define the flame shape FLAME(1,1) = 600 FLAME(1,2) = 52 FLAME(2,1) = 1500 FLAME(2,2) = 54 FLAME(3,1) = 600 FLAME(3,2) = 56 !load the sines & cosines into arrays for speed !loaded at 5 degree increments. ? "ANGS INIT" FOR I=1 TO 72 SIN'ARY(I) = SIN((I-1)*0.087266463) COS'ARY(I) = COS((I-1)*0.087266463) ? "."; NEXT I ? RETURN !BURN'FUEL at the rate determined by user input. Each burn contributes to !the x velocity & the y velocity depending on the ship angle. BURN'FUEL: BURN'RATE = VAL(CHAR)*10 IF FUEL < BURN'RATE CALL NO'GAS : RETURN FUEL = FUEL - BURN'RATE BURN = BURN'RATE*COS'ARY(SHIP'ANG) VEL'X = VEL'X - BURN'RATE*SIN'ARY(SHIP'ANG) FOR I=1 TO 3 ARY'INDEX = SHIP'ANG + FLAME(I,2) IF ARY'INDEX > 72 ARY'INDEX = ARY'INDEX - 72 PT'X(I) = SHIP'X + COS'ARY(ARY'INDEX)*FLAME(I,1) PT'Y(I) = SHIP'Y + SIN'ARY(ARY'INDEX)*FLAME(I,1) NEXT I PT'CT = 3 XCALL AMGSBR,G'SPLC,GCB,4,STATUS XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS XCALL SLEEP,0.1 XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS XCALL AMGSBR,G'SPLC,GCB,1,STATUS PT'CT = NO'SHIP'PTS RETURN !check to see if the midpoint of the ship has found terra firma anywhere, !is so we blow up. CHECK'COLLISION: IF SHIP'X < 13500 AND SHIP'X > 9500 GOTO CHECK'LANDING I = 2 CC'1: IF I > SRF'CT GOTO CC'3 IF SHIP'X <= SRF'X(I) AND SHIP'X >= SRF'X(I-1) GOTO CC'2 I = I+1 GOTO CC'1 CC'2: Y'POS = SRF'Y(I-1) + & (((SHIP'X-SRF'X(I-1))*(SRF'Y(I)-SRF'Y(I-1)))/(SRF'X(I)-SRF'X(I-1))) IF Y'POS < SHIP'Y RETURN CC'3: GOTO BOOM !we are over the landing pad...have we landed yet?? CHECK'LANDING: LAND'FLAG = 0 FOR I=1 TO NO'SHIP'PTS !check all corners of the ship ARY'INDEX = SHIP'ANG + SHIP(I,2) IF ARY'INDEX > 72 ARY'INDEX = ARY'INDEX - 72 Y'POS = SHIP'Y + SIN'ARY(ARY'INDEX)*SHIP(I,1) IF Y'POS < 4000 LAND'FLAG = 1 NEXT I IF LAND'FLAG = 0 RETURN !at this point we know we are on the ground ? TAB(33,1); !could definitely stand a little better messages... IF VEL'Y < 50 ? "Good Landing" IF VEL'Y > 50 AND VEL'Y < 75 ? "Landed with structural damage" IF VEL'Y > 75 AND VEL'Y < 125 ? "Landed, severe damage, few survivors" IF VEL'Y > 125 ? "Landed, Ship completely destroyed, all lives lost" : GOTO BOOM ? TAB(34,13);VEL'X USING "####"; ? TAB(34,22);VEL'Y USING "####"; ? TAB(34,38);SHIP'Y USING "#####"; ? TAB(34,51);FUEL USING "####"; ? TAB(1,1); ? TAB(-1,28); XCALL AMGSBR,G'CLWK,GCB,STATUS !close the workstation END !we crashed so let's blow up... BOOM: XCALL AMGSBR,G'SPLT,GCB,2,STATUS XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS XCALL SLEEP,0.1 XCALL AMGSBR,G'SPLT,GCB,3,STATUS XCALL AMGSBR,G'PL,GCB,PT'ARY,STATUS XCALL SLEEP,0.1 CALL ERASE'SHIP FOR I=1 TO 10 ? TAB(-1,36); XCALL SLEEP,0.1 ? TAB(-1,37); XCALL SLEEP,0.1 NEXT I ? TAB(1,1); ? "YOU DIED..." ? TAB(-1,28); XCALL AMGSBR,G'CLWK,GCB,STATUS !close the workstation END SHOW'BASE: !in the future, we should alter the landscape for variety, !possibly using random number generation for the surface. SRF'X( 1) = 00000 : SRF'Y( 1) = 2662 SRF'X( 2) = 00000 : SRF'Y( 2) = 6600 SRF'X( 3) = 02600 : SRF'Y( 3) = 12500 SRF'X( 4) = 03600 : SRF'Y( 4) = 5300 SRF'X( 5) = 06000 : SRF'Y( 5) = 8400 SRF'X( 6) = 07500 : SRF'Y( 6) = 6000 SRF'X( 7) = 08200 : SRF'Y( 7) = 9000 SRF'X( 8) = 09500 : SRF'Y( 8) = 4000 SRF'X( 9) = 13500 : SRF'Y( 9) = 4000 SRF'X(10) = 15200 : SRF'Y(10) = 13000 SRF'X(11) = 16500 : SRF'Y(11) = 7100 SRF'X(12) = 19400 : SRF'Y(12) = 10000 SRF'X(13) = 21000 : SRF'Y(13) = 8000 SRF'X(14) = 24100 : SRF'Y(14) = 13500 SRF'X(15) = 26200 : SRF'Y(15) = 8700 SRF'X(16) = 28000 : SRF'Y(16) = 13000 SRF'X(17) = 29900 : SRF'Y(17) = 8100 SRF'X(18) = 32000 : SRF'Y(18) = 12000 SRF'X(19) = 32000 : SRF'Y(19) = 2662 SRF'X(20) = 00000 : SRF'Y(20) = 2662 SRF'CT = 20 XCALL AMGSBR,G'SFAS,GCB,3,STATUS XCALL AMGSBR,G'SFAI,GCB,22,STATUS XCALL AMGSBR,G'SFAC,GCB,9,STATUS XCALL AMGSBR,G'FA,GCB,SURFACE,STATUS PT'X(1) = 9500 : PT'Y(1) = 4000 PT'X(2) = 13500 : PT'Y(2) = 4000 PT'X(3) = 13500 : PT'Y(3) = 3000 PT'X(4) = 9500 : PT'Y(4) = 3000 PT'X(5) = 9500 : PT'Y(5) = 4000 PT'CT = 5 XCALL AMGSBR,G'SFAS,GCB,2,STATUS XCALL AMGSBR,G'SFAC,GCB,5,STATUS XCALL AMGSBR,G'FA,GCB,PT'ARY,STATUS RETURN !no gas left in the tanks...bummer... NO'GAS: ? TAB(32,1); ? TAB(-2,1);TAB(-3,4);CHR(7);" INSUFFICIENT FUEL "; ? TAB(-2,1);TAB(-3,0); RETURN