# Raycaster Perspective Problem

This topic is 3991 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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)

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

load$=Input("Enter A Level To Load: ") file=OpenFile(load$+".lvl")
If file = 0
WaitKey
End
EndIf
For y=0 To y_cells-1
For x=0 To x_cells-1
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.

##### Share on other sites
Hi.

I haven't tried your code, since I don't have a Blitz Basic compiler, but I think you're getting a fisheye distortion. Try a google for it with raytracing (one of the search's result is a post here on gamedev: post on gamedev). Basically, you'll have to compensate each ray with the angle it makes with the center of the screen (but I haven't touched this for a long time :( meaning I could be wrong).

##### Share on other sites
Nah, its not fisheye distortion (although that does look kind of cool). The walls look more like sheets of paper that don't connect properly.

##### Share on other sites
Alright, I fixed it. I had to subtract pos_x from ray_x not map_x, the missing floating point remainder was causing trouble. Man that took me ages to figure out.

##### Share on other sites
Quote:
 Original post by mike_gAlright, I fixed it. I had to subtract pos_x from ray_x not map_x, the missing floating point remainder was causing trouble. Man that took me ages to figure out.

lol. I shure know how that feels like!

1. 1
Rutin
24
2. 2
3. 3
JoeJ
18
4. 4
5. 5

• 38
• 23
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631708
• Total Posts
3001840
×