Oops left an unwanted set sprite command in that reduced the frame rate around 10 fold. It's not really the LOS calcs that were killing the framerate but the sprites. Have amended above code & here it is again now runs at around 320fps on my PC.
`##############################################
`# 2D FOV (Field Of View) example by DeepBlue #
`# Sorry no comments, but may be usefull #
`##############################################
if check display mode(800,600,32)=1:set display mode 800,600,32:else
if check display mode(800,600,16)=1:set display mode 800,600,16:endif:endif
set text font "Arial":set text size 14
scrWidth=screen width()
scrHeight=screen Height()
sync on:sync rate 0
backdrop off:hide mouse
draw sprites first
randomize timer()
gosub makeTextures
gosub getMapData
gosub makeMap
tileCount=mapWidth*mapHeight
playerX=400
playerY=300
playerSprite=spriteMapEnd+1
losTestSprite=spriteMapEnd+2
`Set update timers
playerInterval=10
fovInterval=100
baseTimer=Timer()
playerTimer=baseTimer
fovTimer=baseTimer
do
baseTimer=Timer()
if playerTimer < baseTimer Then Gosub playerRoutine
if fovTimer < baseTimer Then Gosub playerFOV
text 4,4,"Use Arrow Keys to Move"
text 4,16,"Checking "+str$(tileCount)+" objects every "+str$(fovInterval)+"ms"
text 4,28,"FPS: "+str$(screen fps())+" (FOV loop time "+str$(fovLoopTime)+"ms)"
sync
loop
playerFOV:
fovTimer=baseTimer+fovInterval
fovStartTime=Timer()
spriteCount=spriteMapStart
for yTest=1 to mapHeight
for xTest=1 to mapWidth
losRes=losTest(playerX+25,playerY+25,(xTest*50)-25,(yTest*50)-25)
if losRes=1
set sprite diffuse spriteCount,255,255,255
else
if mapArray(xTest,yTest)=0
set sprite diffuse spriteCount,64,64,64
endif
endif
inc spriteCount
next xTest
next yTest
fovLoopTime=Timer()-fovStartTime
return
function losTest(x1#,y1#,x2#,y2#)
`main line of sight function
`returns 1=line of sight 0=no line of sight
losRet=1
vectStart=1
vectEnd=2
vectDiff=3
vectNorm=4
vectNewLength=5
vectRes=6
null = make vector2(vectStart)
null = make vector2(vectEnd)
null = make vector2(vectDiff)
null = make vector2(vectNorm)
set vector2 vectStart, x1#,y1#
set vector2 vectEnd, x2#,y2#
set vector2 vectDiff, x2# - x1#, y2# - y1#
maxVectLength = length vector2(vectDiff)
normalize vector2 vectNorm,vectDiff
for vLength=1 to int(maxVectLength) step 25
null = make vector2(vectNewLength)
null = make vector2(vectRes)
copy vector2 vectNewLength,vectNorm
multiply vector2 vectNewLength,abs(vLength)
add vector2 vectRes,vectStart,vectNewLength
targetX=x vector2(vectRes)
targetY=y vector2(vectRes)
tile=mapArray((int(targetX/50))+1,(int(targetY/50))+1)
if tile=1 then losRet=0
null = delete vector2(vectRes)
null = delete vector2(vectNewLength)
next vLength
null = delete vector2(vectStart)
null = delete vector2(vectEnd)
null = delete vector2(vectDiff)
null = delete vector2(vectNorm)
endfunction losRet
playerRoutine:
playerTimer=baseTimer+playerInterval
If Upkey()=true then playerY=playerY+2
If Downkey()=true then playerY=playerY-2
If Leftkey()=true then playerX=playerX+2
If Rightkey()=true then playerX=playerX-2
sprite playerSprite,playerX,playerY,3
Return
makeMap:
spriteMapStart=1
spriteMapEnd=1
mapWidth=16
mapHeight=12
dim mapArray(mapWidth,mapHeight)
for mY=1 to mapHeight
for mX=1 to mapWidth
read mapData
xP=(mX*50)-50
yP=(mY*50)-50
mapArray(mX,mY)=mapData
select mapData
`=Wall
case 1
sprite spriteMapEnd,xP,yP,2
set sprite spriteMapEnd,0,0
endcase
`!=Wall (Floor)
case default
sprite spriteMapEnd,xP,yP,1
set sprite spriteMapEnd,0,0
set sprite diffuse spriteMapEnd,64,64,64
endcase
endselect
inc spriteMapEnd
next mX
next mY
set current bitmap 0
return
getMapData:
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1
Data 1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1
Data 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,1,1,1,0,0,0,0,1,0,0,1,1
Data 1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1
Data 1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,1
Data 1,0,0,0,1,1,1,0,0,0,0,1,0,0,1,1
Data 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1
Data 1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1
Data 1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1
Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
return
makeTextures:
set current bitmap 0
ink 0,0
box 1,1,51,51
for x=1 to 50 step 2
for y=1 to 50 step 2
rc=rnd(32)
ink rgb(rc+124,rc+104,rc+56),0
box x,y,x+2,y+2
next y
next x
get image 1,1,1,51,51,1
ink rgb(255,255,255),0
set current bitmap 0
ink 0,0
box 1,1,51,51
for x=2 to 49
for y=2 to 49
rc=rnd(16)
dot x, y, rgb(rc+32,rc+32,rc+32)
next y
next x
get image 2,1,1,51,51,1
ink rgb(255,255,255),0
set current bitmap 0
ink 0,0
box 1,1,51,51
ink rgb(0,64,192),0
box 15,1,35,50
box 1,15,50,35
get image 3,1,1,51,51,1
ink rgb(255,255,255),0
return
As it was originally used to show someone how to do LOS checks for enemy objects it had to be done real time, but if you just wanted it for static walls as in the demo yes it could be pre calculated.
DeepBlue
The coder formerly known as Twynklet.