Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: mazemaker on August 21, 2008
-
hi i made a 3d maze
EDIT ***** now has diagonal walls! ****
' ****** 3D MAZE ******
' use arrow keys to turn and move
#define SCRWIDTH 800
#define SCRHEIGHT 600
#define BLOCKSIZE 32
#define MAXGRIDSIZE 32
screenres SCRWIDTH,SCRHEIGHT,32,2
dim as single blocktop,blockbot,screenmid
dim as integer gridmask
gridmask=MAXGRIDSIZE-1
blocktop=(3000*SCRHEIGHT/480)
blockbot=(4000*SCRHEIGHT/480)
screenmid=SCRHEIGHT/2
dim as single viewvec(2),viewangle,viewpos(2),viewangle_vel,viewvel(2)
dim as uinteger colourtable_floor(8),colourtable_wallx(8),colourtable_wally(8)
dim as uinteger colourtable_diag(8)
dim as integer grid(MAXGRIDSIZE,MAXGRIDSIZE)
dim as single raystep
raystep=2/SCRWIDTH
' calc colourtable
dim as integer i
i=0
for r as integer=0 to 1
for g as integer=0 to 1
for b as integer=0 to 1
colourtable_floor(i)=((r*128) shl 16)or((g*128) shl 8)or(b*128)
colourtable_wallx(i)=((r*255) shl 16)or((g*255) shl 8)or(b*255)
dim as integer r2,g2,b2
r2=r*255+64
g2=g*255+64
b2=b*255+64
if r2>255 then r2=255
if g2>255 then g2=255
if b2>255 then b2=255
colourtable_diag(i)=(r2 shl 16)or(g2 shl 8)or b2
r2+=64
g2+=64
b2+=64
if r2>255 then r2=255
if g2>255 then g2=255
if b2>255 then b2=255
colourtable_wally(i)=(r2 shl 16)or(g2 shl 8)or b2
i+=1
next
next
next
viewangle_vel=0
' load the level
restore lev1
dim as integer mazewidth,mazeheight
read viewpos(0),viewpos(1),mazewidth,mazeheight
for y as integer=0 to mazewidth-1
for x as integer=0 to mazeheight-1
read grid(x,y)
next
next
' enter refresh loop
dim as integer flipper
dim as double nextupdate
nextupdate=timer
do
' update view state
do until nextupdate>timer
if multikey(&h4B) then viewangle_vel-=0.01
if multikey(&h4D) then viewangle_vel+=0.01
viewangle+=viewangle_vel
viewangle_vel*=0.8
viewvec(0)=cos(viewangle)
viewvec(1)=sin(viewangle)
if multikey(&h48) then
viewvel(0)+=viewvec(1)*0.4
viewvel(1)+=viewvec(0)*0.4
end if
if multikey(&h50) then
viewvel(0)-=viewvec(1)*0.4
viewvel(1)-=viewvec(0)*0.4
end if
viewpos(0)+=viewvel(0)
viewpos(1)+=viewvel(1)
viewvel(0)*=0.8
viewvel(1)*=0.8
nextupdate=nextupdate+0.015
loop
' render the view
screensync
screenset flipper,1-flipper
flipper=1-flipper
cls
dim as single rayvec(2),blockpos(2),blockpos2(2),rx
dim as integer blockindex(2)
rx=-1
' loop through columns
for x as integer=0 to SCRWIDTH-1
blockindex(0)=int(viewpos(0)/BLOCKSIZE)
blockindex(1)=int(viewpos(1)/BLOCKSIZE)
blockpos(0)=blockindex(0)*BLOCKSIZE
blockpos(1)=blockindex(1)*BLOCKSIZE
blockpos2(0)=blockpos(0)
blockpos2(1)=blockpos(1)
rayvec(0)=viewvec(0)*rx + viewvec(1)
rayvec(1)=-viewvec(1)*rx + viewvec(0)
if rayvec(0)>0 then blockpos(0)+=BLOCKSIZE
if rayvec(1)>0 then blockpos(1)+=BLOCKSIZE
dim as integer hit,edge,prevhit
dim as single xsect,ysect,minsect,linbot,lintop
prevhit=grid(blockindex(0) and gridmask,blockindex(1) and gridmask) and 7
hit=0
linbot=SCRHEIGHT
dim as single t(4),w,diasect,dist
t(0)=rayvec(0)*0.707+rayvec(1)*0.707
t(1)=rayvec(0)*-0.707+rayvec(1)*0.707
t(2)=rayvec(0)*0.707+rayvec(1)*-0.707
t(3)=rayvec(0)*-0.707+rayvec(1)*-0.707
' skip through blocks until we hit a wall
do
minsect=8000
edge=-1
xsect=(blockpos(0)-viewpos(0))/rayvec(0)
ysect=(blockpos(1)-viewpos(1))/rayvec(1)
if xsect>0 and xsect<ysect then
minsect=xsect
edge=0
elseif ysect>0 and ysect<xsect then
minsect=ysect
edge=1
end if
blockindex(edge)+=sgn(rayvec(edge))
hit=grid(blockindex(0) and gridmask,blockindex(1) and gridmask)
if (hit>31) then
select case (hit shr 5)
case 1
w=blockpos2(0)*0.707+blockpos2(1)*0.707
diasect=((viewpos(0)*0.707+viewpos(1)*0.707)-w)/-t(0)
case 2
w=(blockpos2(0)+BLOCKSIZE)*-0.707+blockpos2(1)*0.707
diasect=((viewpos(0)*-0.707+viewpos(1)*0.707)-w)/-t(1)
case 3
w=blockpos2(0)*0.707+(blockpos2(1)+BLOCKSIZE)*-0.707
diasect=((viewpos(0)*0.707+viewpos(1)*-0.707)-w)/-t(2)
case 4
w=(blockpos2(0)+BLOCKSIZE)*-0.707+(blockpos2(1)+BLOCKSIZE)*-0.707
diasect=((viewpos(0)*-0.707+viewpos(1)*-0.707)-w)/-t(3)
end select
if (diasect>xsect and diasect<ysect) or (diasect>ysect and diasect<xsect) then
if not hit=prevhit then
lintop=screenmid+blockbot/minsect
' fill in the floor
line (x,linbot)-(x,lintop),colourtable_floor(prevhit)
linbot=lintop
prevhit=hit and 7
end if
edge=2
minsect=diasect
else
hit=hit and 7
end if
end if
if edge=0 or edge=1 then
blockpos(edge)+=sgn(rayvec(edge))*BLOCKSIZE
blockpos2(edge)+=sgn(rayvec(edge))*BLOCKSIZE
end if
if not hit=prevhit then
lintop=screenmid+blockbot/minsect
' fill in the floor
line (x,linbot)-(x,lintop),colourtable_floor(prevhit and 7)
linbot=lintop
prevhit=hit
end if
loop while hit<16 and edge>-1
if edge=0 then
color colourtable_wallx(hit and 7)
elseif edge=1 then
color colourtable_wally(hit and 7)
else
color colourtable_diag(hit and 7)
end if
' fill in the wall
line (x,screenmid-blocktop/minsect)-(x,lintop)
rx+=raystep
next
loop until multikey(1)
' block format: in &hXY, X indicates a wall, and Y is the colour (1-8)
lev1:
data 266,266 ' start x, start z
data 16,16 ' width, height
data &h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11,&h11
data &h11,&h21,&h01,&h01,&h04,&h01,&h14,&h04,&h04,&h04,&h00,&h00,&h05,&h05,&h05,&h15
data &h11,&h01,&h01,&h11,&h14,&h24,&h04,&h44,&h14,&h04,&h00,&h00,&h05,&h05,&h05,&h15
data &h11,&h01,&h81,&h02,&h02,&h04,&h04,&h04,&h04,&h04,&h02,&h05,&h85,&h15,&h05,&h15
data &h11,&h01,&h11,&h02,&h00,&h04,&h04,&h02,&h02,&h00,&h02,&h15,&h35,&h05,&h05,&h15
data &h11,&h01,&h12,&h02,&h00,&h00,&h00,&h00,&h00,&h00,&h02,&h00,&h05,&h00,&h05,&h15
data &h11,&h12,&h02,&h02,&h00,&h82,&h11,&h11,&h00,&h00,&h02,&h00,&h00,&h00,&h05,&h15
data &h11,&h02,&h02,&h02,&h82,&h22,&h02,&h11,&h82,&h12,&h02,&h12,&h62,&h02,&h05,&h15
data &h11,&h02,&h01,&h12,&h22,&h02,&h01,&h11,&h12,&h02,&h02,&h02,&h12,&h02,&h05,&h15
data &h11,&h01,&h03,&h01,&h02,&h01,&h02,&h11,&h12,&h02,&h02,&h02,&h12,&h02,&h05,&h15
data &h11,&h03,&h01,&h03,&h01,&h02,&h01,&h11,&h12,&h02,&h82,&h62,&h12,&h02,&h05,&h15
data &h11,&h01,&h03,&h01,&h83,&h11,&h11,&h11,&h12,&h12,&h26,&h46,&h12,&h02,&h05,&h15
data &h11,&h03,&h01,&h03,&h11,&h00,&h00,&h16,&h06,&h06,&h06,&h06,&h06,&h00,&h05,&h15
data &h11,&h01,&h03,&h01,&h11,&h00,&h00,&h16,&h06,&h06,&h06,&h06,&h06,&h00,&h05,&h15
data &h11,&h03,&h01,&h03,&h11,&h00,&h00,&h16,&h06,&h06,&h06,&h06,&h06,&h00,&h05,&h15
data &h11,&h11,&h11,&h11,&h11,&h11,&h11,&h16,&h16,&h16,&h16,&h16,&h16,&h11,&h11,&h11
it uses wolfenstein
:boxer: DUDUDUDUDUDUDUDUDU
-
Sounds very nice and the source seems tidy. If you attach an executable to your post, the non-basic-users can have a look at it, too.
-
Welcome aboard dude, very clever stuff there.
-
thanks, bro.
actually the first time i've tried the 'wolf3d' way. before this it was ray-versus-segment and marching, rather than this ray-versus-cells.
i did try fading out to the distance, but the floors didn't look right. i want to improve this, add collision detection, and maybe sprites.
-
It looks really cool :D And movement is smooth !
i want to improve this, add collision detection, and maybe sprites.
Cool :D 'hope you'll code it !
-
:hi: and nice work dude
-
I always have had a soft spot for raycasters :)
:hi: aboard Mazemaker! Really nice first code post there. K+
-
Yeah. Welcome to this forum.
Your raycaster runs very smooth. Looks nice. Good work.
And of course K++ for sharing code.
-
Very nice - I like that if you go out through the walls you end up in an infinite landscape with seemingly no z cutoff. Can you exploit that?
Jim
-
Very nice - I like that if you go out through the walls you end up in an infinite landscape with seemingly no z cutoff. Can you exploit that?
Jim
i don't know what you mean. it's 'infinite' because the rays wrap around the map.
the only exploit i can think of here is special blocks that transform rays, like mirrors or portals. you could create an endless corridor and other physically impossible structures that way.
-
Cool diagonals now :p
Very nice - I like that if you go out through the walls you end up in an infinite landscape with seemingly no z cutoff. Can you exploit that?
Jim
I didn't noticed it the first time ! yeah, it's really a nice effect in fact ^^
the only exploit i can think of here is special blocks that transform rays, like mirrors or portals. you could create an endless corridor and other physically impossible structures that way.
It makes me think about some topology stuff (n-Dimensions Spaces where you return on your start point whatever your direction is :p)
It'd be cool to exploit that in any way :)
-
Cool I just love non orthagonal walls though there is an issue with slices being missed if the edge of a wall is only barely visible (if most of wall is off screen). Not to worry though cos the speed is very good