Basic Raycatter

Made in about an hour, in QB64

'(c) 2021, @_sorceress

' wasd + mouse to move.
' mouse control doesn't seem to work on linux. this is a bug in QB64.

SCREEN _NEWIMAGE(640, 480, 256)
_TITLE "Basic Raycatter"

'generate random test map
RANDOMIZE TIMER
DIM g(15, 15)
FOR x = 0 TO 15: FOR y = 0 TO 15
IF RND < .3 THEN gv = 1 ELSE gv = 0
IF x MOD 15 = 0 OR y MOD 15 = 0 THEN gv = 1
IF ABS(x - 5) + ABS(y - 5) < 3 THEN gv = 0
g(x, y) = gv
NEXT: NEXT

'player behaviour
px = 5: py = 5: pa = 0: pelev = 0
turnspeed = 5: walkspeed = 2.5

FPS = 30: dt = 1 / FPS

DO
'### input
fv = 0: sv = 0
IF ScanKey%(17) THEN fv = fv + walkspeed
IF ScanKey%(31) THEN fv = fv - walkspeed
IF ScanKey%(30) THEN sv = sv + walkspeed
IF ScanKey%(32) THEN sv = sv - walkspeed
WHILE _MOUSEINPUT
pa = pa + turnspeed * (_MOUSEMOVEMENTX / 1000)
pelev = pelev + turnspeed * (_MOUSEMOVEMENTY / 1000)
IF ABS(pelev) > 1 THEN pelev = SGN(pelev)
WEND

'### physics
pacos = COS(pa): pasin = SIN(pa)
xvt = fv * pacos + sv * pasin
yvt = fv * pasin - sv * pacos
xv = xv + (xvt - xv) * 4 * dt
yv = yv + (yvt - yv) * 4 * dt
px1 = px + xv * dt: py1 = py + yv * dt
x1 = px1: y1 = py: GOSUB cbox: IF ok = 0 THEN px = px1
x1 = px: y1 = py1: GOSUB cbox: IF ok = 0 THEN py = py1

'### raycatter
h0 = 240 - 240 * pelev
LINE (0, 0)-(639, h0), 11, BF
LINE (0, h0)-(639, 479), 8, BF
x = 320 * (1 - TAN(pa - 3.141 / 2)): y = h0 - 320
IF pasin > 0 THEN CIRCLE (x, y), 32, 14: PAINT (x, y + 30), 14, 14
FOR sx = 0 TO 639: e = sx / 320 - 1 'x-fov
x = px: y = py 'ray origin
rx = pacos - e * pasin: ry = pasin + e * pacos 'ray vector
d = 0: dd = .01 'terribly inefficient way of catting rays
WHILE g(INT(x), INT(y)) = 0
x = x + rx * dd: y = y + ry * dd: d = d + dd: dd = dd * 1.005
WEND
h = 100 / d 'draw column
LINE (sx, h0 - h)-(sx, h0 + h), (3 * INT(x) + INT(y)) MOD 7 + 1
NEXT

'### draw minimap
m = 8
FOR x = 0 TO 15: FOR y = 0 TO 15
LINE (x * m, y * m)-(x * m + m, y * m + m), g(x, y) * 8, BF
NEXT: NEXT
x = m * px: y = m * py: ux = m * pacos: uy = m * pasin
LINE (x - ux, y - uy)-(x + ux, y + uy), 3: LINE -(x - uy, y + ux), 3: LINE -(x + uy, y - ux), 3: LINE -(x + ux, y + uy), 3

'### text feedback
LOCATE 1, 20: PRINT px; py; pa; pelev
_DISPLAY: _LIMIT FPS
LOOP

'################################################################################

'collision box test. a must be smaller than 0.5 to work properly.
cbox:
a = .2
ok = g(INT(x1 - a), INT(y1 - a)) + g(INT(x1 + a), INT(y1 - a)) + g(INT(x1 - a), INT(y1 + a)) + g(INT(x1 + a), INT(y1 + a))
RETURN

'is key down?
FUNCTION ScanKey% (scancode%)
STATIC Ready%, keyflags%()
IF NOT Ready% THEN REDIM keyflags%(0 TO 127): Ready% = -1
i% = INP(&H60)
IF (i% AND 128) THEN keyflags%(i% XOR 128) = 0
IF (i% AND 128) = 0 THEN keyflags%(i%) = -1
K$ = INKEY$
ScanKey% = keyflags%(scancode%)
END FUNCTION

Comments (6)

toasty
 • 3 months ago • 

The code is the manual. So cool B-)

This is really cool, @sorceress: not just that you built a raycaster in basic, and in so few lines, but in under an hour. Wow! I expect this would fit right in in a demoscene event.

The mipmap is a nice touch too. What more could we ask for? Well, perhaps a cat, given the name :P

remco
 • 3 months ago • 

You made this in an hour? I can hardly type that fast :-D Very impressive.

QBasic, now that's a name I haven't heard in a long time. Neat that there're people out there still updating some kind of version of it!

You probably know this already (and also the least important thing ever), but; sometimes an inwards corner is missing a small sliver.

For anyone running Linux, you can put in some keyboard controls for view-direction by adding this to the source, between the other key handling (Q, E, R, F keys are used … the numbers seem to be the order in which they are on the keyboard, so maybe it's other keys in other layouts):

    IF ScanKey%(16) THEN pa = pa - turnspeed / 50
    IF ScanKey%(18) THEN pa = pa + turnspeed / 50
    IF ScanKey%(19) THEN pelev = pelev - turnspeed / 100
    IF ScanKey%(33) THEN pelev = pelev + turnspeed / 100
    IF ABS(pelev) > 1 THEN pelev = SGN(pelev)

Otherwise it would seem I'm a bit too tired right now to mess with source code :-D

P.S. I'm with toasty, where's the cats?

sorceress
  • 3 months ago • 

Pretty! Yeah, the sliver is when the raycasts clip through a corner of the grid. I didn't feel like working out the correct ray-boundary stuff when I wrote this, and it wouldn't have been a one hour entry then either :p

I hope it gave you some joy, at least :-)

Wan
 • 3 months ago • 

Nice job making a raycatter, map generation and even a fancy minimap in a few dozens lines of code!

remco
 • 3 months ago • 

I hope it gave you some joy, at least :-)

Oh, sure! All of the entries I've seen so far have brought something different and unexpected/quirky/different to the table (including yours!), so I'm really enjoying reviewing these more than I usually do for game jams!

yozy
 • 3 months ago • 

The only thing that would make this more nostalgic is if the code came printed out in a magasine. Thanks!

Login to comment

Links

Code is in the description. Get QB64 here:

Author

sorceress

Details