I am making a ray caster in python with pygame. https://youtu.be/gYRrGTC7GtA?t=407 The problem is the cast_rays function. I have commented out the previous method that I was using.I used the above video written in C and adapted it to Python. I wanted to use the raycasting algorithm in the above video since it would be casted then checking pixel by pixel.I have tried checking only horizontal lines and checking to see if there is a wall there. But, it doesn't work.
import pygame
import sys
import math
pygame.init()
screen_height = 480
screen_width = screen_height * 2
map_size = 8
tile_size = screen_height / 8
player_x = screen_width / 4
player_y = screen_width / 4
FOV = math.pi / 3
HALF_FOV = FOV / 2
player_angle = math.pi + math.pi / 2
casted_rays = 120
step_angle = FOV / casted_rays
scale = screen_height / casted_rays
MAP = (
'########'
'# # #'
'# # #'
'# ## #'
'# #'
'### #'
'### #'
'########'
)
def draw_map():
for row in range(8):
for col in range(8):
# square index
square = row * map_size + col
pygame.draw.rect(win, (200,200,200) if MAP[square] == '#' else (100,100,100),(row * tile_size, col * tile_size, tile_size - 2, tile_size - 2))
pygame.draw.circle(win, (255,0,0), (player_x, player_y), 8)
#pygame.draw.line(win, (0,255,0), (player_x, player_y), (player_x + math.cos(player_angle) * 50, player_y + math.sin(player_angle) * 50) ,3)
#pygame.draw.line(win, (0,255,0), (player_x, player_y), (player_x + math.cos(player_angle - HALF_FOV) * 50, player_y + math.sin(player_angle - HALF_FOV) * 50) ,3)
#pygame.draw.line(win, (0,255,0), (player_x, player_y), (player_x + math.cos(player_angle + HALF_FOV) * 50, player_y + math.sin(player_angle + HALF_FOV) * 50) ,3)
def cast_rays():
'''
start_angle = player_angle - HALF_FOV
for ray in range(casted_rays):
for depth in range(screen_height):
target_x = player_x + math.cos(start_angle) * depth
target_y = player_y + math.sin(start_angle) * depth
pygame.draw.line(win, (255,255,0), (player_x, player_y), (target_x, target_y) ,3)
row = int(target_x / tile_size)
col = int(target_y / tile_size)
square = int(row * map_size + col)
if MAP[square] == "#":
pygame.draw.rect(win, (0,255, 0),(row * tile_size, col * tile_size, tile_size - 2, tile_size - 2))
wall_height = 21000 / (depth + 0.00001)
pygame.draw.rect(win, (100,100,100), (screen_height + ray * scale, (screen_height - wall_height) / 2 ,scale,wall_height))
break
start_angle += step_angle
'''
#dof = 0
r = 0
ra = player_angle
ry = 0
rx = 0
while r < 1:
dof = 0
aTan = -1/math.tan(ra);
if ra > math.pi:
ry = ((ry * tile_size) / tile_size) - 0.0001
rx = (player_y - ry) * aTan + player_x
yo = -64
xo = -yo * aTan
if ra < math.pi:
ry = ((ry * tile_size) / tile_size) + 64
rx = (player_y - ry) * aTan + player_x
yo = 64
xo = -yo * aTan
if ra == 0 or ra == math.pi:
dof = 8
ra = 0
rx = player_x
ry = player_y
while dof < 8:
mx = rx * tile_size
my = ry * tile_size
mp = my * tile_size
if mp < tile_size * 8 * tile_size * 8 and MAP[int(mp)] == '#':
dof = 8
else:
rx += xo
ry += yo
pygame.draw.line(win, (255,255,0), (player_x, player_y), (rx, ry) ,3)
r += 1
win = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.draw.rect(win, (0,0,0), (0, 0, screen_width, screen_height))
draw_map()
cast_rays()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_angle -= 0.1
if keys[pygame.K_RIGHT]:
player_angle += 0.1
if keys[pygame.K_UP]:
player_x, player_y = player_x + math.cos(player_angle) * 3, player_y + math.sin(player_angle) * 3
if keys[pygame.K_DOWN]:
player_x, player_y = player_x - math.cos(player_angle) * 3, player_y - math.sin(player_angle) * 3
pygame.display.flip()
clock.tick(30)

