Dark Bit Factory & Gravity

PROGRAMMING => Other languages => Blitz => Topic started by: Paul on January 16, 2007

Title: another raycaster[BB2D]
Post by: Paul on January 16, 2007
Hi,
as i might have said i have been working on a ray caster but when Tetra got there first i didn't bother for a while but started again today and the finished(mote or less) version is here now :) 
Instead of having 64*64 blocks I've got 1*1 so it's possible to have rounded curves ;)   I also added a feature for looking up and down... 

http://www.yourfilehost.com/media.php?cat=other&file=ray.rar

the code is pretty messed up but you can have it if you like :D




Title: Re: another raycaster
Post by: Clyde on January 16, 2007
Wow mate, thats fantastic :)

Welldone & Cheers,
Clyde.
Title: Re: another raycaster
Post by: rdc on January 16, 2007
Looks good. Doing a ray caster is something I want to do one day when my schedule frees up some.
Title: Re: another raycaster
Post by: mike_g on January 16, 2007
Wow thats very nice :) Tetra might have done a raycaster first but the curvy walls in yours make it look quite different.

I had a go at using the map editor but all I got was a black screen with a yellow border and a mouse cursor and using the mouse dident seem to do anything ??? I guess this might be something you are still working on.

Oh yeah and it I'd like to have a peek at your code if you feel like posting it, well done!  ;)

 
Title: Re: another raycaster
Post by: benny! on January 16, 2007
I love raycasting. Nice one. Looking forward to see some enemies ;-)
Title: Re: another raycaster
Post by: rain_storm on January 17, 2007
Man thats great work! How did you plot the intersections with the walls being curved? thats what I wanna know. I am workin on my own raycaster and can appreciate how difficult that is to incorporate. Thanks for posting the link Paul.
Title: Re: another raycaster
Post by: Paul on January 17, 2007
Forgot to say this, scroll the mousewheel to change color in the map editor. and press Rmousebutton to delete walls, and 1 to reset the map.

thx for liking it

;:;:;:;:;:;
The code is a bit(at least) messed up but I've tried to put some coments in:)
;:;:;:

Code: [Select]

Code
[table][tr][td]
AppTitle "Raycaster"

Const FoV = 75;field of view
Const FoV2 =FoV/2

Const GX  = 640;600; graphicswidth
Const GY = (GX*3/4);-II-     height

Const CGX = GX / 2
Const CGY = GY / 2

Const Size=128

Global Playerdist#=CGX*Tan(FoV2);distance to viewplane

tmp#=Fov
tmp#=tmp#/GX
Global RaySpace#=tmp#;angle between rays

Graphics GX,GY,32,2
SetBuffer BackBuffer()

Global PlayerX#=100;player starting pos
Global PlayerY#=100
Global PlayerA#=45;-II-             angle
Global PlayerAZ#=0

Global maxdist=100000;max view distance


Dim Colour(10);dim the colors to be used
R=1010 :G=200 :B=300
colour(1)=R Shl 16 Or G Shl 8 Or B

R=10   :G=100 :B=100
colour(2)=R Shl 16 Or G Shl 8 Or B

R=243  :G=67  :B=0
colour(3)=R Shl 16 Or G Shl 8 Or B

R=24   :G=155 :B=78
colour(4)=R Shl 16 Or G Shl 8 Or B

R=255  :G=255 :B=0
colour(5)=R Shl 16 Or G Shl 8 Or B

R=100  :G=255 :B=0
colour(6)=R Shl 16 Or G Shl 8 Or B

R=0    :G=255 :B=255
colour(7)=R Shl 16 Or G Shl 8 Or B

R=255  :G=255 :B=253
colour(8)=R Shl 16 Or G Shl 8 Or B


Const MapX=800+1;mapsize
Const MapY=600+1

Dim World(MapX,MapY);map

fil=ReadFile("data.dat");read the map from a file
For x=0 To 800-1
For y=0 To 600
world(x+1,y+1)=ReadByte(fil)
Next
Next
CloseFile(fil)

DebugLog "***************************************"
DebugLog "GraphicsWidth                ="+GX
DebugLog "Graphicsheight               ="+GY
DebugLog "---------------------------------------"
DebugLog "Half GraphicsWidth           ="+CGX
DebugLog "Half Graphicsheight          ="+CGY
DebugLog "---------------------------------------"
DebugLog "distance To Projection Plane ="+Playerdist
DebugLog "---------------------------------------"
DebugLog "Angle betwen rays            ="+RaySpace#
DebugLog "---------------------------------------"
DebugLog "Field of view                ="+FoV
DebugLog "Half field of view           ="+FoV2
DebugLog "---------------------------------------"
DebugLog "Player angle                 ="+PlayerA#
DebugLog "Player Y position            ="+PlayerX#
DebugLog "Player X position            ="+PlayerY#
DebugLog "Player X position            ="+PlayerAZ#
DebugLog "***************************************"

MoveMouse(CGX,CGY)


While Not KeyHit(1)
debug=MouseZ()
Render
Text 0,0,frames
Flip 0
inputs()
Cls
fps=fps+1
If MilliSecs()-fpstimer>1000
fpstimer=MilliSecs()
frames=fps
fps=0
EndIf

Wend

End

Function Render(debug=0)
LockBuffer BackBuffer()
For TX=0 To GX-1
tmpx#=Sin((RaySpace#*(TX))+PlayerA#-FoV2);calculat x step ;for the ray
tmpy#=Cos((RaySpace#*(TX))+PlayerA#-FoV2);calculate y step -II-

For D=1 To maxdist
PX=tmpx#*D+PlayerX#;get the ray position
PY=tmpy#*D+PlayerY#
If PX>0 And PX<mapX And PY>0 And PY<MapY;check if the ray is inside the map
;If Debug=1
; WritePixelFast(PX,PY,255)
;EndIf
tmpworld=world(PX,PY);get the color from the map array
If tmpworld>0
Length=D*Cos(RaySpace#*(TX)-FoV2); get the undistorted length


;calculate the wall height;;; I think
tmp#=Length
tmp#=64/tmp#
tmp#=tmp#*Playerdist

;If debug=0
tmpcol#=(D*0.02);calculate the color from the distance*0.02
;this could be done using rect but that would be tu much of a job for me ;P
If tmpcol<1 Then tmpcol=1
R=(Colour(world(px,py)) Shr 16 And $ff)/TmpCol#
G=(Colour(world(px,py)) Shr 8  And $ff)/TmpCol#
B=(Colour(world(px,py))        And $ff)/TmpCol#
For y=CGY-tmp#+PlayerAZ# To CGY+tmp#+PlayerAZ#
If y>GY-1 Then Exit
If y=>0
WritePixelFast(TX,y,R Shl 16 Or G Shl 8 Or B)
EndIf
Next
;EndIf

For TY=CGY+tmp#+PlayerAZ# To GY-1;Floor
If Not TY<0
tmpcol=(PlayerAZ#/2+GY-ty*Cos((cgx-tx)/20)*0.6)*0.02
If tmpcol<1 Then tmpcol=1
WritePixelFast(TX,TY,(255/tmpcol) Shl 8)
;draw a line from the bottom of the wall to the bottom of the screen
EndIf
Next
For TY=CGY-tmp#+PlayerAZ# To 0 Step -1;Roof
If Not TY>GY
tmpcol=(PlayerAZ#+GY-ty)*0.02
If tmpcol<1 Then tmpcol=1
WritePixelFast(TX,TY,255/tmpcol)
;draw a line from the top of the wall to the top of the screen
EndIf
Next

Exit
EndIf
Else
Exit
EndIf
Next


Next
UnlockBuffer BackBuffer()
End Function
Function inputs()
PlayerA#=PlayerA#+(MouseX()-CGX)/2
PlayerAZ#=PlayerAZ# - (MouseY()-CGY)
If PlayerAZ#> cgx Then PlayerAZ#= cgx
If PlayerAZ#<-gx Then PlayerAZ#=-gx

If KeyDown(205) Then PlayerA#=PlayerA#+2;MouseX()-CGX
If KeyDown(203) Then PlayerA#=PlayerA#-2;MouseX()-CGX
MoveMouse(CGX,CGY)
If KeyDown(200) Or KeyDown(17)
For i=-90 To 90
tmpx=((playerX#)+(Sin(PlayerA#+i)*10))
tmpy=((playery#)+(Cos(PlayerA#+i)*10))
If Not tmpx<0 And tmpy<0 And tmpx>MapX And tmpy>MapY
If world(tmpx,tmpy)=0 Then tmp=tmp+1
EndIf

;If world(((playerX#)+(Sin(PlayerA#+i)*10)),((playery#)+(Cos(PlayerA#+i)*10)))=0 Then tmp=tmp+1
Next
If tmp=181
PlayerX#=PlayerX#+Sin(PlayerA#)*4
PlayerY#=PlayerY#+Cos(PlayerA#)*4
EndIf
tmp=0
EndIf
If KeyDown(208) Or KeyDown(31)
For i=-30 To 30
tmpx=((playerX#)-(Sin(PlayerA#+i)*10))
tmpy=((playery#)-(Cos(PlayerA#+i)*10))
If tmpx=>0 And tmpy=>0 And tmpx<MapX And tmpy<MapY
If world(tmpx,tmpy)=0 Then tmp=tmp+1
EndIf
Next
;If world(((playerX#)-(Sin(PlayerA#)*10)),((playery#)-(Cos(PlayerA#)*10)))=0
If tmp=61
PlayerX#=PlayerX#-Sin(PlayerA#)*4
PlayerY#=PlayerY#-Cos(PlayerA#)*4
EndIf
tmp=0
EndIf

If KeyDown(30) And 1=3
TmpA=PlayerA#+90
If world(((playerX#)-(Sin(TmpA)*10)),((playery#)-(Cos(TmpA)*10)))=0
PlayerX#=PlayerX#-Sin(TmpA)*4
PlayerY#=PlayerY#-Cos(TmpA)*4
EndIf
EndIf
If KeyDown(32) And 1=2
TmpA=PlayerA#-90
If world(((playerX#)-(Sin(TmpA)*10)),((playery#)-(Cos(TmpA)*10)))=0
PlayerX#=PlayerX#-Sin(TmpA)*4
PlayerY#=PlayerY#-Cos(TmpA)*4
EndIf
EndIf

End Function