|
Post by Rod on Feb 1, 2022 16:08:04 GMT
Well not quite yet but I am excited to have found a tutorial I half understand. www.lexaloffle.com/bbs/?tid=35767This is a port of the basic road drawing demo. Lots to do. Pick it up and run with it if it interests you. global ct,tu,numcnr dim road(7,2) ct=1 tu=2 road(1,ct)=10 road(1,tu)=0 road(2,ct)=6 road(2,tu)=-1 road(3,ct)=8 road(3,tu)=0 road(4,ct)=4 road(4,tu)=1.5 road(5,ct)=10 road(5,tu)=0.2 road(6,ct)=4 road(6,tu)=0 road(7,ct)=5 road(7,tu)=-1 dim camxyz(3)'camx camy camz dim xyz(3) 'xyz numcnr=7 camcnr=1 camseg=1
nomainwin WindowWidth = 800 : WindowHeight = 600 UpperLeftX = INT((DisplayWidth-WindowWidth)/2) UpperLeftY = INT((DisplayHeight-WindowHeight)/2) Open "Graphic" for graphics_nsb_nf as #main #main "trapclose [quit]" #main "down;fill white;color black"
'timer 33,[update] '30 fps timer 16,[update]
[update] camxyz(3)=camxyz(3)+0.1 'speed if camxyz(3)>1 then camxyz(3)=camxyz(3)-1 nul=advance(camcnr,camseg) camcnr=xyz(1) camseg=xyz(2) end if
[draw] #main "cls"
'direction camang=camxyz(3)*road(camcnr,tu) xd=camang*-1 yd=0 zd=1
'skew camera to account for direction nul=skew(xd,yd) cx=xyz(1) cy=xyz(2) cz=xyz(3)
'cursor, relative to skewed camera x=cx*-1 y=cy*-1+1 z=cz*-1+1
'road position cnr=camcnr seg=camseg
'draw forward for i=1 to 30 scan
'project nul=project(x,y,z) px=xyz(1) py=xyz(2) scale=xyz(3)
'draw road width=3*scale #main "line ";px-width;" ";py;" ";px+width;" ";py
'move forward x=x+xd y=y+yd z=z+zd
'turn xd=xd+road(cnr,tu)
'advance along road nul=advance(cnr,seg) cnr=xyz(1) seg=xyz(2) next wait
function project(x,y,z) scale=64/z xyz(1)=x*scale+400 xyz(2)=y*scale+300 xyz(3)=scale end function
function advance(cnr,seg) seg=seg+1 if seg>road(cnr,ct) then seg=1 cnr=cnr+1 end if if cnr>numcnr then cnr=1 xyz(1)=cnr xyz(2)=seg end function
function skew(xd,yd) xyz(1)=camxyz(1)+z*xd xyz(2)=camxyz(2)+z*yd xyz(3)=camxyz(3) end function
[quit] timer 0 close #main : end
|
|
|
Post by Brandon Parker on Feb 2, 2022 5:13:18 GMT
Rod, Here is one little update. We now have edges to the road. You can comment out the horizontal segments if you wish as I have. You can also set edgeWidth to change the with of the road's edge.
Please not the comment within the For...Next loop...
Here is the code...
global ct,tu,numcnr dim road(7,2) ct=1 tu=2 road(1,ct)=10 road(1,tu)=0 road(2,ct)=6 road(2,tu)=-1 road(3,ct)=8 road(3,tu)=0 road(4,ct)=4 road(4,tu)=1.5 road(5,ct)=10 road(5,tu)=0.2 road(6,ct)=4 road(6,tu)=0 road(7,ct)=5 road(7,tu)=-1 dim camxyz(3)'camx camy camz dim xyz(3) 'xyz numcnr=7 camcnr=1 camseg=1 edgeWidth=10
nomainwin WindowWidth = 800 : WindowHeight = 600 UpperLeftX = INT((DisplayWidth-WindowWidth)/2) UpperLeftY = INT((DisplayHeight-WindowHeight)/2) Open "Graphic" for graphics_nsb_nf as #main #main "trapclose [quit]" #main "down;fill white;color black; size 1"
'timer 33,[update] '30 fps timer 15,[update]
[update] Scan camxyz(3)=camxyz(3)+0.1 'speed if camxyz(3)>1 then camxyz(3)=camxyz(3)-1 nul=advance(camcnr,camseg) camcnr=xyz(1) camseg=xyz(2) end if
[draw] #main "cls"
'direction camang=camxyz(3)*road(camcnr,tu) xd=camang*-1 yd=0 zd=1
'skew camera to account for direction nul=skew(xd,yd) cx=xyz(1) cy=xyz(2) cz=xyz(3)
'cursor, relative to skewed camera x=cx*-1 y=cy*-1+1 z=cz*-1+1
'road position cnr=camcnr seg=camseg
oldWidth = WindowWidth pyOld = WindowHeight 'draw forward for i=1 to 30 'scan
'project nul=project(x,y,z) px=xyz(1) py=xyz(2)
scale=xyz(3)
'draw road width=3*scale
'This If...Then is here because sometimes there 'is a small segment that is drawn in the upper left 'corner of the GraphicBox 'I did not try to figure out why that is occuring; I 'chose to just prevent drawing based on it If (py > 25) And ((px-width) > 0) Then '#main "line ";px-width;" ";py;" ";px+width;" ";py If (i = 1) Then pxOld = px 'Draw the outer edge #main "line ";pxOld-oldWidth;" ";pyOld;" ";px-width;" ";py #main "line ";pxOld+oldWidth;" ";pyOld;" ";px+width;" ";py oldDivisor = i For edge = 1 To edgeWidth 'Draw the inner edge #main "line ";pxOld-oldWidth-edge;" ";pyOld;" ";px-width-edge;" ";py #main "line ";pxOld+oldWidth+edge;" ";pyOld;" ";px+width+edge;" ";py
Next edge pxOld = px pyOld = py
oldWidth = width End If
'move forward x=x+xd y=y+yd z=z+zd
'turn xd=xd+road(cnr,tu)
'advance along road nul=advance(cnr,seg) cnr=xyz(1) seg=xyz(2) next i wait
function project(x,y,z) scale=64/z xyz(1)=x*scale+400 xyz(2)=y*scale+300 xyz(3)=scale end function
function advance(cnr,seg) seg=seg+1 if seg>road(cnr,ct) then seg=1 cnr=cnr+1 end if if cnr>numcnr then cnr=1 xyz(1)=cnr xyz(2)=seg end function
function skew(xd,yd) xyz(1)=camxyz(1)+z*xd xyz(2)=camxyz(2)+z*yd xyz(3)=camxyz(3) end function
[quit] timer 0 close #main : end
{:0)
Brandon Parker
|
|
|
Post by Brandon Parker on Feb 2, 2022 6:11:28 GMT
Ok, here is another quick update. I have had a bit of fun here.
global ct,tu,numcnr dim road(7,2) ct=1 tu=2 road(1,ct)=10 road(1,tu)=0 road(2,ct)=6 road(2,tu)=-1 road(3,ct)=8 road(3,tu)=0 road(4,ct)=4 road(4,tu)=1.5 road(5,ct)=10 road(5,tu)=0.2 road(6,ct)=4 road(6,tu)=0 road(7,ct)=5 road(7,tu)=-1 dim camxyz(3)'camx camy camz dim xyz(3) 'xyz
nomainwin WindowWidth = 800 : WindowHeight = 600
numcnr=7 camcnr=1 camseg=1 edgeWidth=10 sunPosition = (WindowWidth/ 2)
UpperLeftX = INT((DisplayWidth-WindowWidth)/2) UpperLeftY = INT((DisplayHeight-WindowHeight)/2) Open "Graphic" for graphics_nsb_nf as #main #main "trapclose [quit]" #main "down;fill white;color black; size 1"
'timer 33,[update] '30 fps timer 15,[update]
[update] Scan camxyz(3)=camxyz(3)+0.1 'speed if camxyz(3)>1 then camxyz(3)=camxyz(3)-1 nul=advance(camcnr,camseg) camcnr=xyz(1) camseg=xyz(2) end if
[draw] #main "CLS" #main "Color Cyan; BackColor Cyan" #main "Place 0 0; BoxFilled ";WindowWidth;" ";pyOld; #main "Color Yellow; BackColor Yellow" sunAdjustment = ((WindowWidth/ 4) * road(camcnr,tu)) If (sunAdjustment < 0) Then sunPosition = sunPosition - Max(sunAdjustment, (sunAdjustment/ 200)) Else sunPosition = sunPosition - Min(sunAdjustment, (sunAdjustment/ 200)) End If #main "Place ";sunPosition;" 100; CircleFilled 50" #main "Color 199 147 118; BackColor 199 147 118" #main "Place 0 ";pyOld;"; BoxFilled ";WindowWidth;" ";WindowHeight #main "Color Black; BackColor Black" 'direction camang=camxyz(3)*road(camcnr,tu)
xd=camang*-1 yd=0 zd=1
'skew camera to account for direction nul=skew(xd,yd) cx=xyz(1) cy=xyz(2) cz=xyz(3)
'cursor, relative to skewed camera x=cx*-1 y=cy*-1+1 z=cz*-1+1
'road position cnr=camcnr seg=camseg
oldWidth = WindowWidth pyOld = WindowHeight 'draw forward for i=1 to 30 'scan
'project nul=project(x,y,z) px=xyz(1) py=xyz(2)
scale=xyz(3)
'draw road width=3*scale
'This If...Then is here because sometimes there 'is a small segment that is drawn in the upper left 'corner of the GraphicBox 'I did not try to figure out why that is occuring; I 'chose to just prevent drawing based on it If (py > 25) And ((px-width) > 0) Then '#main "line ";px-width;" ";py;" ";px+width;" ";py If (i = 1) Then pxOld = px
'Draw the outer edge #main "line ";pxOld-oldWidth;" ";pyOld;" ";px-width;" ";py #main "line ";pxOld+oldWidth;" ";pyOld;" ";px+width;" ";py
For edge = 1 To edgeWidth 'Draw the inner edge #main "line ";pxOld-oldWidth-edge;" ";pyOld;" ";px-width-edge;" ";py #main "line ";pxOld+oldWidth+edge;" ";pyOld;" ";px+width+edge;" ";py
Next edge pxOld = px pyOld = py
oldWidth = width End If
'move forward x=x+xd y=y+yd z=z+zd
'turn xd=xd+road(cnr,tu)
'advance along road nul=advance(cnr,seg) cnr=xyz(1) seg=xyz(2) next i wait
function project(x,y,z) scale=64/z xyz(1)=x*scale+400 xyz(2)=y*scale+300 xyz(3)=scale end function
function advance(cnr,seg) seg=seg+1 if seg>road(cnr,ct) then seg=1 cnr=cnr+1 end if if cnr>numcnr then cnr=1 xyz(1)=cnr xyz(2)=seg end function
function skew(xd,yd) xyz(1)=camxyz(1)+z*xd xyz(2)=camxyz(2)+z*yd xyz(3)=camxyz(3) end function
Function Max(a, b) Max = ((a >= b) * a) + ((b > a) * b) End Function
Function Min(a, b) Min = ((a <= b) * a) + ((b < a) * b) End Function
[quit] timer 0 close #main : end
{:0)
Brandon Parker
|
|
|
Post by Rod on Feb 2, 2022 11:12:46 GMT
Cool, the original port is outputting x,y and width way too large which is why we have the glitch lines at top left. I need to go back and try and get it outputting numbers within range.. not limiting the numbers, just getting the calculation corrected, I must have a bug in how I centre it on an 800x600 screen.
|
|
|
Post by Rod on Feb 2, 2022 12:29:37 GMT
This has some limits on the py position to stop drawing below screen and the numbers are in a better range. But one problem remains. You will see in the tutorial that the camera is meant to skew round to smooth out the curve display. But you can see that the curves still jerk in. I want to get the base model right before I add enhancements. My maths aint good enough to see what is going wrong.
global ct,tu,numcnr dim road(7,2) ct=1 tu=2 road(1,ct)=10 road(1,tu)=0 road(2,ct)=6 road(2,tu)=-1 road(3,ct)=8 road(3,tu)=0 road(4,ct)=4 road(4,tu)=1.5 road(5,ct)=10 road(5,tu)=0.2 road(6,ct)=4 road(6,tu)=0 road(7,ct)=5 road(7,tu)=-1 dim camxyz(3)'camx camy camz dim xyz(3) 'xyz numcnr=7 camcnr=1 camseg=1
'nomainwin WindowWidth = 800 : WindowHeight = 600 UpperLeftX = INT((DisplayWidth-WindowWidth)/2) UpperLeftY = INT((DisplayHeight-WindowHeight)/2) Open "Graphic" for graphics_nsb_nf as #main #main "trapclose [quit]" #main "down;fill white;color black"
'timer 33,[update] '30 fps timer 33,[update]
[update] camxyz(3)=camxyz(3)+0.1 'speed if camxyz(3)>1 then camxyz(3)=camxyz(3)-1 nul=advance(camcnr,camseg) camcnr=xyz(1) camseg=xyz(2) end if
[draw] #main "cls"
'direction camang=camxyz(3)*road(camcnr,tu) xd=camang*-1 yd=0 zd=1
'skew camera to account for direction nul=skew(xd,yd) cx=xyz(1) cy=xyz(2) cz=xyz(3)
'cursor, relative to skewed camera x=cx*-1 y=cy*-1+1 z=cz*-1+1
'road position cnr=camcnr seg=camseg
'draw forward for i= 1 to 24 'distance to see forwards
'project nul=project(x,y,z) px=xyz(1) py=xyz(2) scale=xyz(3)
'draw road width=scale*2 if py<600 then #main "line ";px-width;" ";py;" ";px+width;" ";py
'move forward x=x+xd y=y+yd z=z+zd
'turn xd=xd+road(cnr,tu)
'advance along road nul=advance(cnr,seg) cnr=xyz(1) seg=xyz(2) next wait
function project(x,y,z) scale=64/z xyz(1)=x*scale+400 'mid screen xyz(2)=y*scale+300 'mid screen xyz(3)=scale end function
function advance(cnr,seg) seg=seg+1 if seg>road(cnr,ct) then seg=1 cnr=cnr+1 end if if cnr>numcnr then cnr=1 xyz(1)=cnr xyz(2)=seg end function
function skew(xd,yd) xyz(1)=camxyz(1)+z*xd xyz(2)=camxyz(2)+z*yd xyz(3)=camxyz(3) end function
[quit] timer 0 close #main : end
|
|
|
Post by Rod on Feb 2, 2022 13:05:52 GMT
If you click on the link in the first post and play the intro screen you will see the animation is smooth and the corners don’t jerk in. Click on the little code icon at the foot of the display pane to see the code.
The underscored functions update and draw are two fixed system functions that are called by the system timer. So my timer port is ok but perhaps the order of calculation isn’t or perhaps i use the wrong turn value from road()
|
|
|
Post by Rod on Feb 4, 2022 14:28:26 GMT
The large numbers are coming from division by a very small number in project() I think it is to do with the number formats. On pico-8 the numbers range +-32k to two decimal points. Liberty obviously can divide by very small numbers, indeed project() was heading towards infinity! So I restrict the division to no less than .01 and all seems ok. Banding now.
|
|