Original Post
I'm coding a raycaster and the perspective is skewed. I think I am calculating the perpendicular wall distance wrong. My code is in Blitz Basic, I remove all the texturing and stuff to keep the Raycast() function simple.
Const GRAPHICS_W=640
Const GRAPHICS_H=480
Const DRAW_FROM=20
Const TEX_W=64
Const TEX_H=64
Global x_cells=75
Global y_cells=75
Dim map(75, 75)
LoadMap()
Graphics GRAPHICS_W, GRAPHICS_H, 32, 2
SetBuffer BackBuffer()
;PLAYER VARIABLES
Global pos_x#=10, pos_y#=10
Global dir_x#=-1, dir_y#=0
Global cam_x#=0, cam_y#=0.66 ;camera plane
Global mov_spd#=0.3, rot_spd#=3
;FRAME RATE VARIABLES
Global old_time = MilliSecs()
Global frame_count, fps
wait=CreateTimer(20)
;MAIN LOOP
While Not KeyHit(1)
Cls
Raycast()
PlayerMove()
FPS()
Flip
Wend
Function Raycast()
For x=0 To GRAPHICS_W-1
camera_x# = 2 * x / Float(GRAPHICS_W)-1
ray_dir_x# = dir_x# + cam_x# * camera_x#
ray_dir_y# = dir_y# + cam_y# * camera_x#
map_x = pos_x#
map_y = pos_y#
;Ray starts at player
ray_x# = pos_x#
ray_y# = pos_y#
inc_x# = ray_dir_x# * 0.1
inc_y# = ray_dir_y# * 0.1
;move on x then y axis until a wall is hit
Repeat
side =0
ray_x# = ray_x# + inc_x#
map_x = ray_x#
If map(map_x, map_y) > 0 Then Exit
side =1
ray_y# = ray_y# + inc_y#
map_y = ray_y#
If map(map_x, map_y) > 0 Then Exit
Forever
;CALCULATE DISTANCE
If side = 0
perp_wall_dist# = Abs((map_x - pos_x#) / ray_dir_x#)
Else
perp_wall_dist# = Abs((map_y - pos_y#) / ray_dir_y#)
EndIf
line_height = Int(GRAPHICS_H / perp_wall_dist#)
line_start = (-line_height / 2) + (GRAPHICS_H / 2)
If line_start < 0 Then line_start = 0
line_end = (line_height / 2) + (GRAPHICS_H / 2)
If line_end >= GRAPHICS_H Then line_end = GRAPHICS_H-1
col = 255-(perp_wall_dist#*5)
If side = 1 Then col = (col Shr 1) And 8355711
If col < 0 Then col = 0
Color col, col, col
Line x, line_start, x, line_end
Next
End Function
;---------------------------------------------------------------------------------------------------;
;************************************* EXTRA FUNCTIONS *********************************************;
;---------------------------------------------------------------------------------------------------;
Function PlayerMove()
;STRAFE MODE
If KeyDown(42)
If KeyDown(203);left
mov_x# = pos_x# + ((-dir_y#) * mov_spd# *0.5)
mov_y# = pos_y# - ((-dir_x#) * mov_spd# *0.5)
If map(mov_x#, pos_y#) = 0 Then pos_x# = mov_x#
If map(pos_x#, mov_y#) = 0 Then pos_y# = mov_y#
Else If KeyDown(205);right
mov_x# = pos_x# + ((dir_y#) * mov_spd# *0.5)
mov_y# = pos_y# - ((dir_x#) * mov_spd# *0.5)
If map(mov_x#, pos_y#) = 0 Then pos_x# = mov_x#
If map(pos_x#, mov_y#) = 0 Then pos_y# = mov_y#
EndIf
;TURN MODE
Else
;Rotate camera direction and plane
If KeyDown(203);left
old_dir_x# = dir_x#
dir_x# = (dir_x# * Cos(rot_spd#)) - (dir_y# * Sin(rot_spd#))
dir_y# = (old_dir_x# * Sin(rot_spd#)) + (dir_y# * Cos(rot_spd#))
old_cam_x# = cam_x#
cam_x# = (cam_x# * Cos(rot_spd#)) - (cam_y# * Sin(rot_spd#))
cam_y# = (old_cam_x# * Sin(rot_spd#)) + (cam_y# * Cos(rot_spd#))
Else If KeyDown(205);right
old_dir_x# = dir_x#
dir_x# = (dir_x# * Cos(-rot_spd#)) - (dir_y# * Sin(-rot_spd#))
dir_y# = (old_dir_x# * Sin(-rot_spd#)) + (dir_y# * Cos(-rot_spd#))
old_cam_x# = cam_x#
cam_x# = (cam_x# * Cos(-rot_spd#)) - (cam_y# * Sin(-rot_spd#))
cam_y# = (old_cam_x# * Sin(-rot_spd#)) + (cam_y# * Cos(-rot_spd#))
EndIf
EndIf
;MOVE FORWARDS AND BACKWARDS
If KeyDown(200)
mov_x#=pos_x# + (dir_x# * mov_spd#)
mov_y#=pos_y# + (dir_y# * mov_spd#)
If map(mov_x#, pos_y#) = 0 Then pos_x# = mov_x#
If map(pos_x#, mov_y#) = 0 Then pos_y# = mov_y#
Else If KeyDown(208)
mov_x#=pos_x# - (dir_x# * mov_spd# *0.7)
mov_y#=pos_y# - (dir_y# * mov_spd# *0.7)
If map(mov_x#, pos_y#) = 0 Then pos_x# = mov_x#
If map(pos_x#, mov_y#) = 0 Then pos_y# = mov_y#
EndIf
End Function
Function LoadMap()
load$=Input("Enter A Level To Load: ")
file=OpenFile(load$+".lvl")
If file = 0
Print "FILE NOT FOUND"
WaitKey
End
EndIf
x_cells=ReadByte(file)
y_cells=ReadByte(file)
For y=0 To y_cells-1
For x=0 To x_cells-1
map(x, y)=ReadByte(file)
Next
Next
CloseFile(file)
End Function
Function FPS()
If MilliSecs() > old_time+1000
old_time = MilliSecs()
fps=frame_count
frame_count=0
EndIf
Color 255, 255, 255
Text 0, 0, "FPS: "+fps
frame_count=frame_count+1
End Function Also heres a pic of what it looks like: http://i92.photobucket.com/albums/l15/mikegrundel/RaycastProblem.png Can someone tell me what I am doing wrong here? Cheers.