Skip to main content
GameDev.net gamedev.net
🔒 Locked

Raycaster Perspective Problem

Started by mike_g Aug 13, 2007 at 3:15 AM 3 replies 950+ views
Original Post
mike_g
mike_g
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.
wolverine
wolverine
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).
mike_g
mike_g
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.
mike_g
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.
wolverine
wolverine
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!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.