[img_left]
http://bisqwit.iki.fi/kala/snap/qbasicnovatron.png[/img_left][img_right]
http://bisqwit.iki.fi/kala/snap/novatron_000.png[/img_right]
There was once this game called NOVATRON. I still suck at it btw.
This is something like that except with no sounds and with a weaker AI.
On the left: QuickBasic game, source code below
On the right: Original Novatron
DEFINT A-Z
DECLARE SUB plot(screenx, screeny)
DECLARE SUB setp(fieldx,fieldy, pal)
DECLARE FUNCTION shadows(fieldx,fieldy,fieldz)
DECLARE SUB AI(botx,boty,botdir)
CONST xdim = 200
CONST ydim = 110
CONST wallheight = 15
TYPE dircfg
x AS INTEGER
y AS INTEGER
k AS STRING*1
END TYPE
OPTION BASE 0
DIM SHARED fld(xdim-1, ydim-1), palettes(1 TO 3,9), dircfg(3) AS dircfg
SCREEN 13 ' 320x200 256-color mode, very popular
' configure input and axial directions
DATA 0,-1,H, 0,1,P, -1,0,K, 1,0,M
FOR n=0 TO 3: READ dircfg(n).x, dircfg(n).y, dircfg(n).k: NEXT
' Colors
FOR p=1 TO 3:FOR c=0 TO 9:READ palettes(p,c):NEXT c,p
DATA 11, 11,3, 3,1, 9, 9,1, 3,1 : REM Wall colours
DATA 14, 14,6, 6,4, 12,12,4, 6,4 : REM Protagonist colours
DATA 13, 13,5, 5,1, 9, 9,1, 3,1 : REM Antagonist colours
' Create edge walls
FOR y = 0 TO ydim - 1: fld(0,y)=1: fld(xdim-1,y)=1: NEXT
FOR x = 0 TO xdim - 1: fld(x,0)=1: fld(x,ydim-1)=1: NEXT
' Render the entire field
FOR y = 50 TO 199-20
FOR x = 50 TO 319-30
plot x,y
NEXT x,y
botx=xdim*3\4 : yourx=xdim\2
boty=ydim*3\4 : youry=ydim\2
dir=3
win=0
botdir=2
DO
IF fld(botx,boty) THEN win=1: EXIT DO
setp botx,boty, 3
IF fld(yourx,youry) THEN win=0: EXIT DO
setp yourx,youry, 2
y$ = RIGHT$(INKEY$,1)
IF y$ = CHR$(27) THEN win=2: EXIT DO
FOR n=0 TO 3
IF y$ = dircfg(n).k THEN dir = n
NEXT
AI botx,boty,botdir
yourx = yourx + dircfg(dir).x
youry = youry + dircfg(dir).y
botx = botx + dircfg(botdir).x
boty = boty + dircfg(botdir).y
LOOP
IF win=1 THEN PRINT "You win" ELSE IF win=0 THEN PRINT "You lose"
WHILE INKEY$<>"":WEND
PRINT "Game over; press any key"; : s$ = INPUT$(1)
SCREEN 0,1,0,0 : WIDTH 80,25
END
' Field is mapped with fieldx,fieldy. fieldz = vertical(0=root of wall, positive=up).
' Screen is mapped with screenx,screeny.
'
' screenx = fieldx + fieldy*0.3 + 50
' screeny = fieldy - fieldz + 70
'
' This gives us:
' fieldy = (screeny+fieldz-70)
' fieldx = screenx - ((screeny+fieldz-70)*0.3 + 50)
'
' The light vector is (field coordinates) x=0.4, y=0.6, z=0.2
'
SUB plot(screenx, screeny)
xorpt = 1 AND (screenx XOR screeny)
FOR fieldz = wallheight TO 0 STEP -1
fieldy = (screeny + fieldz - 70)
fieldx = screenx - (fieldy*3\10 + 50)
IF fieldx>=0 AND fieldx<xdim _
AND fieldy>=0 AND fieldy<ydim THEN
pal = fld(fieldx,fieldy)
IF pal THEN
palindex = 5 ' Default wall colour
IF fieldz >= wallheight THEN palindex = 0 ' Top of the wall
' Check shadow
SELECT CASE shadows(fieldx,fieldy,fieldz)
CASE 1: palindex = palindex + 1+xorpt 'shadowing thing on the right side
CASE 2: palindex = palindex + 3+xorpt 'shadowing thing on the left side
END SELECT
' Plot the wall pixel
PSET(screenx,screeny), palettes(pal,palindex)
EXIT SUB
END IF
ELSE
IF fieldz=0 THEN EXIT SUB 'always out of bounds
IF fieldx<-15 OR fieldy<-15 THEN EXIT SUB
IF fieldx>=xdim+15 OR fieldy>=ydim+15 THEN EXIT SUB
END IF
NEXT
'Plot floor
c = xorpt
fieldz = 0
fieldy = (screeny + fieldz - 70)
fieldx = screenx - (fieldy*3\10 + 50)
IF shadows(fieldx,fieldy,fieldz) THEN
c = c AND ((2 AND (screenx XOR screeny))\2) ' any shadow
END IF
PSET (screenx,screeny), c
END SUB
' Calculate whether there is something that shadows this spot
FUNCTION shadows(fieldx,fieldy,fieldz)
FOR shadowvec = 1 TO wallheight ' (upper limit must be >= ceil(wallheight))
fx = CINT(fieldx + 0.4 * shadowvec)
fy = (fieldy + shadowvec)
fz = (fieldz + shadowvec)
IF fz > wallheight OR fx >= xdim OR fy >= ydim THEN EXIT FOR ' out of bounds
IF fld(fx, fy) THEN shadows = 1: EXIT FUNCTION
NEXT
FOR shadowvec = 1 TO wallheight ' (upper limit must be >= ceil(wallheight))
fx = CINT(fieldx - 0.7 * shadowvec)
fy = (fieldy + shadowvec)
fz = (fieldz + shadowvec)
IF fz > wallheight OR fx < 0 OR fy >= ydim THEN EXIT FOR ' out of bounds
IF fld(fx, fy) THEN shadows = 2: EXIT FUNCTION
NEXT
END FUNCTION
' Set this pixel and plot the field
SUB setp(fieldx,fieldy, pal)
fld(fieldx,fieldy)=pal
screenx = fieldx+fieldy*0.3+50
screeny = fieldy +70
FOR x=screenx-12 TO screenx+8
FOR y=screeny-23 TO screeny
plot x,y
NEXT y,x
END SUB
' The computer player's AI. Quite bad.
SUB AI(botx,boty, botdir)
DIM dists(3)
FOR n=0 TO 3: dists(n) = 9: NEXT
FOR dist=8 TO 1 STEP -1
FOR n=0 TO 3
IF fld(botx + dist*dircfg(n).x, boty + dist*dircfg(n).y) THEN dists(n) = dist
NEXT n,dist
' Go to whichever direction that is furthest away from any walls
IF RND > 0.93 THEN botdir = INT(RND*4) 'randomly change direction
bestdist=0: dir=botdir
FOR n=0 TO 3
testdir=(botdir+n)AND 3
IF dists(testdir) > bestdist THEN bestdist=dists(testdir): dir=testdir
NEXT
botdir=dir AND 3
END SUB