!*************************** 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
!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
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...
!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