Sign in to follow this  

Raycaster Perspective Problem

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

If you intended to correct an error in the post then please contact us.

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)
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.

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by mike_g
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.


lol. I shure know how that feels like!

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this