REM Peter Cooper's DOOM RayCaster Thingamajig modified by a lot of people REM and then Matt Bross (Before me, Victor Woeltjen). My Comments are REMmed DEFINT A-Z CONST UpArrow% = 72, DnArrow% = 80, LArrow% = 75, RArrow% = 77, Esc% = 1 CONST PI# = 22 / 7 REM ****************************INFO ARRAYS********************************** REM $DYNAMIC DIM Grid%(1 TO 12, 1 TO 12): REM Map DIM STable(359 + 90) AS LONG: REM SIN table REM ******************************VARIABLES********************************** PX& = 9: PY& = 11 'the starting coordinates of the player's location Stride = 3 'the distance covered in one "step" by the player ' by pressing the up or down arrow keys Heading% = 0 'the heading of the player (in degrees) turn% = 5 'number of degrees of rotation produced by ' pressing the right or left arrow keys PX& = PX& * 1024: REM scale PX and PY to use fixed point math PY& = PY& * 1024 REM ****************************INFO SCREEN********************************** SCREEN 7, , 0, 0: RANDOMIZE TIMER + VAL(DATE$) PRINT PRINT PRINT " RAYCASTER DEMO" PRINT PRINT " UP ARROW........Move Forward" PRINT " DOWN ARROW......Move Backward" PRINT " RIGHT ARROW.....Turn Right" PRINT " LEFT ARROW......Turn Left" PRINT PRINT PRINT " Please wait..."; REM ******************************LOAD INFO********************************** FOR Y% = 1 TO 12: FOR X% = 1 TO 12: READ Grid%(X%, Y%): NEXT: NEXT REM Make SIN table, convert to radians, scale by 1024 and then divide by 10 REM to make the view field smaller. REM COS(x) = SIN(x + 90) FOR A% = 0 TO 359 + 90: STable(A%) = (COS(A% * PI / 180) * 1024) \ 10: NEXT REM ***************************CREATE BACKGROUND***************************** REM I'M ony using one page for the background because it annoyed me. SCREEN , , 2, 0: CLS REM Map FOR Y% = 1 TO 12: FOR X% = 1 TO 12: PSET (X%, Y%), Grid%(X%, Y%): NEXT: NEXT ' Moon CIRCLE (50, 30), 10, 8: PAINT (50, 30), 14, 8 CIRCLE (43, 29), 10, 0: PAINT (43, 29), 0, 0 ' Clouds moved after moon so they would overlap it FOR i = 1 TO 10 R% = INT(RND * 25) + 25 aspect! = RND / 10 X% = INT(RND * (319 - R% - R%)) Y% = INT(RND * 80) CIRCLE (X%, Y%), R%, 15, , , aspect!: PAINT (X%, Y%), 15 NEXT 'Building (gray) LINE (200, 20)-(220, 15), 8: LINE -(240, 20), 8: LINE -(240, 99), 8 LINE (200, 20)-(200, 99), 8: LINE -(240, 99), 8: PAINT (220, 50), 8 FOR Cnt% = 1 TO 20 ' Lights PSET (INT(RND * 38) + 201, INT(RND * 80) + 20), 14 NEXT ' Building (border) LINE (200, 20)-(220, 15), 0: LINE -(240, 20), 0: LINE -(240, 99), 0 LINE (219, 15)-(219, 99), 0: LINE (200, 20)-(200, 99), 0 FOR Y% = 100 TO 199: FOR X% = 0 TO 319 IF RND > .5 THEN PSET (X%, Y%), 8 NEXT: NEXT SCREEN , , 0, 0 REM *****************************READY TO GO********************************* LOCATE , 1 PRINT " Press any key to begin..."; DO WHILE LEN(INKEY$): LOOP: DO UNTIL LEN(INKEY$): LOOP REM ********************SET UP AND DRAW FIRST FRAME************************** ViewPG% = 0: WorkPG% = 1: BG1% = 2 SCREEN , , WorkPG%, ViewPG% GOTO ComputeView DEF SEG = 0 REM -------------------------->BEGIN MAIN LOOP<------------------------------ DO 'Main loop REM *****************************FAST INKEY$********************************* GetKey: DO: Keycode% = INP(&H60): LOOP UNTIL Keycode% WHILE LEN(INKEY$): WEND SELECT CASE Keycode% CASE RArrow: Heading% = (Heading% + turn%) MOD 360 CASE LArrow: Heading% = (Heading% + (360 - turn%)) MOD 360 CASE UpArrow NewPX& = PX& - (STable(Heading% + 90) * Stride) NewPY& = PY& - (STable(Heading%) * Stride) IF Grid%(NewPX& \ 1024, NewPY& \ 1024) = 0 THEN PX& = NewPX&: PY& = NewPY& ELSE 'tried to walk through a wall SOUND 80, 1: GOTO GetKey END IF CASE DnArrow NewPX& = PX& + (STable(Heading% + 90) * Stride) NewPY& = PY& + (STable(Heading%) * Stride) IF Grid%(NewPX& \ 1024, NewPY& \ 1024) = 0 THEN PX& = NewPX&: PY& = NewPY& ELSE 'tried to walk through a wall SOUND 80, 1: GOTO GetKey END IF CASE Esc: EXIT DO CASE ELSE: GOTO GetKey END SELECT REM **************************RENDERING PROCESS***************************** ComputeView: PCOPY BG1%, WorkPG% REM show your location on map PSET (PX& \ 1024, PY& \ 1024), 15 X1% = -1 FOR A% = Heading% - 31 TO Heading% + 32 ANGLE = A% MOD 360: IF ANGLE < 0 THEN ANGLE = ANGLE + 360 StepX& = STable(ANGLE + 90): StepY& = STable(ANGLE) XX& = PX&: YY& = PY& L% = 0 REM Sent out ray at ANGLE until it hits something DO XX& = XX& - StepX&: YY& = YY& - StepY& L% = L% + 1 K% = Grid%(XX& \ 1024, YY& \ 1024) LOOP UNTIL K% DD% = 900 \ L% H% = DD% + DD% DT% = 100 - DD% YPlace2% = H% + DT% YPlace1% = H% \ 30 + DT% X1% = X1% + 1: LINE (X1%, YPlace1%)-(X1%, YPlace2%), K% X1% = X1% + 1: LINE (X1%, YPlace1%)-(X1%, YPlace2%), K% X1% = X1% + 1: LINE (X1%, YPlace1%)-(X1%, YPlace2%), K% X1% = X1% + 1: LINE (X1%, YPlace1%)-(X1%, YPlace2%), K% X1% = X1% + 1: LINE (X1%, YPlace1%)-(X1%, YPlace2%), K% NEXT SWAP WorkPG%, ViewPG%: SCREEN , , WorkPG%, ViewPG% LOOP REM -------------------------->END MAIN LOOP<-------------------------------- DEF SEG : SCREEN 0: WIDTH 80, 25: END REM %%%%%%%%%%%%%%%%%%%%%%%%%%%%%LEVEL DATA%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% DATA 1, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 9 DATA 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 DATA 1, 0, 2, 10, 0, 0, 0, 0, 0, 0, 0, 9 DATA 9, 0, 10, 2, 0, 0, 0, 0, 0, 0, 0, 1 DATA 1, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 9 DATA 9, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 1 DATA 1, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 9 DATA 9, 0, 7, 0, 0, 4, 0, 0, 0, 13, 0, 1 DATA 1, 0, 8, 0, 0, 6, 0, 0, 0, 0, 0, 9 DATA 9, 0, 7, 0, 0, 0, 0, 0, 0, 5, 0, 1 DATA 1, 0, 8, 0, 0, 0, 0, 0, 0, 13, 0, 9 DATA 9, 9, 9, 9, 1, 9, 1, 9, 1, 1, 1, 1