Dark Bit Factory & Gravity

PROGRAMMING => Freebasic => Topic started by: mazemaker on August 21, 2008

Title: hello i made a 3d maze
Post by: mazemaker on August 21, 2008

hi i made a 3d maze

EDIT            ***** now has diagonal walls! ****


Code: [Select]
'      ****** 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
Title: Re: hello i made a 3d maze
Post by: hellfire on August 21, 2008
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.
Title: Re: hello i made a 3d maze
Post by: Clyde on August 21, 2008
Welcome aboard dude, very clever stuff there.
Title: Re: hello i made a 3d maze
Post by: mazemaker on August 21, 2008
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.
Title: Re: hello i made a 3d maze
Post by: Hezad on August 21, 2008
It looks really cool :D And movement is smooth !

Quote
i want to improve this, add collision detection, and maybe sprites.

Cool :D 'hope you'll code it !
Title: Re: hello i made a 3d maze
Post by: Rbz on August 21, 2008
 :hi: and nice work dude
Title: Re: hello i made a 3d maze
Post by: Shockwave on August 22, 2008
I always have had a soft spot for raycasters :)

 :hi: aboard Mazemaker! Really nice first code post there. K+
Title: Re: hello i made a 3d maze
Post by: benny! on August 22, 2008
Yeah. Welcome to this forum.

Your raycaster runs very smooth. Looks nice. Good work.
And of course K++ for sharing code.
Title: Re: hello i made a 3d maze
Post by: Jim on August 23, 2008
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
Title: Re: hello i made a 3d maze
Post by: mazemaker on August 23, 2008
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.
Title: Re: hello i made a 3d maze
Post by: Hezad on August 23, 2008
Cool diagonals now :p

Quote
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 ^^



Quote
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 :)
Title: Re: hello i made a 3d maze
Post by: rain_storm on August 23, 2008
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