Raycasting in python
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
#!/usr/bin/python
# This code is public domain.
# By init. initd5@gmail.com
import sys # For terminal output
W = 24 # Width/Height
H = 79
RAYS = 360 # Should be 360!
STEP = 3 # The step of for cycle. More = Faster, but large steps may
# cause artifacts. Step 3 is great for radius 10.
RAD = 10 # FOV radius.
# Tables of precalculated values of sin(x / (180 / pi)) and cos(x / (180 / pi))
sintable = [
0.00000, 0.01745, 0.03490, 0.05234, 0.06976, 0.08716, 0.10453,
0.12187, 0.13917, 0.15643, 0.17365, 0.19081, 0.20791, 0.22495, 0.24192,
0.25882, 0.27564, 0.29237, 0.30902, 0.32557, 0.34202, 0.35837, 0.37461,
0.39073, 0.40674, 0.42262, 0.43837, 0.45399, 0.46947, 0.48481, 0.50000,
0.51504, 0.52992, 0.54464, 0.55919, 0.57358, 0.58779, 0.60182, 0.61566,
0.62932, 0.64279, 0.65606, 0.66913, 0.68200, 0.69466, 0.70711, 0.71934,
0.73135, 0.74314, 0.75471, 0.76604, 0.77715, 0.78801, 0.79864, 0.80902,
0.81915, 0.82904, 0.83867, 0.84805, 0.85717, 0.86603, 0.87462, 0.88295,
0.89101, 0.89879, 0.90631, 0.91355, 0.92050, 0.92718, 0.93358, 0.93969,
0.94552, 0.95106, 0.95630, 0.96126, 0.96593, 0.97030, 0.97437, 0.97815,
0.98163, 0.98481, 0.98769, 0.99027, 0.99255, 0.99452, 0.99619, 0.99756,
0.99863, 0.99939, 0.99985, 1.00000, 0.99985, 0.99939, 0.99863, 0.99756,
0.99619, 0.99452, 0.99255, 0.99027, 0.98769, 0.98481, 0.98163, 0.97815,
0.97437, 0.97030, 0.96593, 0.96126, 0.95630, 0.95106, 0.94552, 0.93969,
0.93358, 0.92718, 0.92050, 0.91355, 0.90631, 0.89879, 0.89101, 0.88295,
0.87462, 0.86603, 0.85717, 0.84805, 0.83867, 0.82904, 0.81915, 0.80902,
0.79864, 0.78801, 0.77715, 0.76604, 0.75471, 0.74314, 0.73135, 0.71934,
0.70711, 0.69466, 0.68200, 0.66913, 0.65606, 0.64279, 0.62932, 0.61566,
0.60182, 0.58779, 0.57358, 0.55919, 0.54464, 0.52992, 0.51504, 0.50000,
0.48481, 0.46947, 0.45399, 0.43837, 0.42262, 0.40674, 0.39073, 0.37461,
0.35837, 0.34202, 0.32557, 0.30902, 0.29237, 0.27564, 0.25882, 0.24192,
0.22495, 0.20791, 0.19081, 0.17365, 0.15643, 0.13917, 0.12187, 0.10453,
0.08716, 0.06976, 0.05234, 0.03490, 0.01745, 0.00000, -0.01745, -0.03490,
-0.05234, -0.06976, -0.08716, -0.10453, -0.12187, -0.13917, -0.15643,
-0.17365, -0.19081, -0.20791, -0.22495, -0.24192, -0.25882, -0.27564,
-0.29237, -0.30902, -0.32557, -0.34202, -0.35837, -0.37461, -0.39073,
-0.40674, -0.42262, -0.43837, -0.45399, -0.46947, -0.48481, -0.50000,
-0.51504, -0.52992, -0.54464, -0.55919, -0.57358, -0.58779, -0.60182,
-0.61566, -0.62932, -0.64279, -0.65606, -0.66913, -0.68200, -0.69466,
-0.70711, -0.71934, -0.73135, -0.74314, -0.75471, -0.76604, -0.77715,
-0.78801, -0.79864, -0.80902, -0.81915, -0.82904, -0.83867, -0.84805,
-0.85717, -0.86603, -0.87462, -0.88295, -0.89101, -0.89879, -0.90631,
-0.91355, -0.92050, -0.92718, -0.93358, -0.93969, -0.94552, -0.95106,
-0.95630, -0.96126, -0.96593, -0.97030, -0.97437, -0.97815, -0.98163,
-0.98481, -0.98769, -0.99027, -0.99255, -0.99452, -0.99619, -0.99756,
-0.99863, -0.99939, -0.99985, -1.00000, -0.99985, -0.99939, -0.99863,
-0.99756, -0.99619, -0.99452, -0.99255, -0.99027, -0.98769, -0.98481,
-0.98163, -0.97815, -0.97437, -0.97030, -0.96593, -0.96126, -0.95630,
-0.95106, -0.94552, -0.93969, -0.93358, -0.92718, -0.92050, -0.91355,
-0.90631, -0.89879, -0.89101, -0.88295, -0.87462, -0.86603, -0.85717,
-0.84805, -0.83867, -0.82904, -0.81915, -0.80902, -0.79864, -0.78801,
-0.77715, -0.76604, -0.75471, -0.74314, -0.73135, -0.71934, -0.70711,
-0.69466, -0.68200, -0.66913, -0.65606, -0.64279, -0.62932, -0.61566,
-0.60182, -0.58779, -0.57358, -0.55919, -0.54464, -0.52992, -0.51504,
-0.50000, -0.48481, -0.46947, -0.45399, -0.43837, -0.42262, -0.40674,
-0.39073, -0.37461, -0.35837, -0.34202, -0.32557, -0.30902, -0.29237,
-0.27564, -0.25882, -0.24192, -0.22495, -0.20791, -0.19081, -0.17365,
-0.15643, -0.13917, -0.12187, -0.10453, -0.08716, -0.06976, -0.05234,
-0.03490, -0.01745, -0.00000
]
costable = [
1.00000, 0.99985, 0.99939, 0.99863, 0.99756, 0.99619, 0.99452,
0.99255, 0.99027, 0.98769, 0.98481, 0.98163, 0.97815, 0.97437, 0.97030,
0.96593, 0.96126, 0.95630, 0.95106, 0.94552, 0.93969, 0.93358, 0.92718,
0.92050, 0.91355, 0.90631, 0.89879, 0.89101, 0.88295, 0.87462, 0.86603,
0.85717, 0.84805, 0.83867, 0.82904, 0.81915, 0.80902, 0.79864, 0.78801,
0.77715, 0.76604, 0.75471, 0.74314, 0.73135, 0.71934, 0.70711, 0.69466,
0.68200, 0.66913, 0.65606, 0.64279, 0.62932, 0.61566, 0.60182, 0.58779,
0.57358, 0.55919, 0.54464, 0.52992, 0.51504, 0.50000, 0.48481, 0.46947,
0.45399, 0.43837, 0.42262, 0.40674, 0.39073, 0.37461, 0.35837, 0.34202,
0.32557, 0.30902, 0.29237, 0.27564, 0.25882, 0.24192, 0.22495, 0.20791,
0.19081, 0.17365, 0.15643, 0.13917, 0.12187, 0.10453, 0.08716, 0.06976,
0.05234, 0.03490, 0.01745, 0.00000, -0.01745, -0.03490, -0.05234, -0.06976,
-0.08716, -0.10453, -0.12187, -0.13917, -0.15643, -0.17365, -0.19081,
-0.20791, -0.22495, -0.24192, -0.25882, -0.27564, -0.29237, -0.30902,
-0.32557, -0.34202, -0.35837, -0.37461, -0.39073, -0.40674, -0.42262,
-0.43837, -0.45399, -0.46947, -0.48481, -0.50000, -0.51504, -0.52992,
-0.54464, -0.55919, -0.57358, -0.58779, -0.60182, -0.61566, -0.62932,
-0.64279, -0.65606, -0.66913, -0.68200, -0.69466, -0.70711, -0.71934,
-0.73135, -0.74314, -0.75471, -0.76604, -0.77715, -0.78801, -0.79864,
-0.80902, -0.81915, -0.82904, -0.83867, -0.84805, -0.85717, -0.86603,
-0.87462, -0.88295, -0.89101, -0.89879, -0.90631, -0.91355, -0.92050,
-0.92718, -0.93358, -0.93969, -0.94552, -0.95106, -0.95630, -0.96126,
-0.96593, -0.97030, -0.97437, -0.97815, -0.98163, -0.98481, -0.98769,
-0.99027, -0.99255, -0.99452, -0.99619, -0.99756, -0.99863, -0.99939,
-0.99985, -1.00000, -0.99985, -0.99939, -0.99863, -0.99756, -0.99619,
-0.99452, -0.99255, -0.99027, -0.98769, -0.98481, -0.98163, -0.97815,
-0.97437, -0.97030, -0.96593, -0.96126, -0.95630, -0.95106, -0.94552,
-0.93969, -0.93358, -0.92718, -0.92050, -0.91355, -0.90631, -0.89879,
-0.89101, -0.88295, -0.87462, -0.86603, -0.85717, -0.84805, -0.83867,
-0.82904, -0.81915, -0.80902, -0.79864, -0.78801, -0.77715, -0.76604,
-0.75471, -0.74314, -0.73135, -0.71934, -0.70711, -0.69466, -0.68200,
-0.66913, -0.65606, -0.64279, -0.62932, -0.61566, -0.60182, -0.58779,
-0.57358, -0.55919, -0.54464, -0.52992, -0.51504, -0.50000, -0.48481,
-0.46947, -0.45399, -0.43837, -0.42262, -0.40674, -0.39073, -0.37461,
-0.35837, -0.34202, -0.32557, -0.30902, -0.29237, -0.27564, -0.25882,
-0.24192, -0.22495, -0.20791, -0.19081, -0.17365, -0.15643, -0.13917,
-0.12187, -0.10453, -0.08716, -0.06976, -0.05234, -0.03490, -0.01745,
-0.00000, 0.01745, 0.03490, 0.05234, 0.06976, 0.08716, 0.10453, 0.12187,
0.13917, 0.15643, 0.17365, 0.19081, 0.20791, 0.22495, 0.24192, 0.25882,
0.27564, 0.29237, 0.30902, 0.32557, 0.34202, 0.35837, 0.37461, 0.39073,
0.40674, 0.42262, 0.43837, 0.45399, 0.46947, 0.48481, 0.50000, 0.51504,
0.52992, 0.54464, 0.55919, 0.57358, 0.58779, 0.60182, 0.61566, 0.62932,
0.64279, 0.65606, 0.66913, 0.68200, 0.69466, 0.70711, 0.71934, 0.73135,
0.74314, 0.75471, 0.76604, 0.77715, 0.78801, 0.79864, 0.80902, 0.81915,
0.82904, 0.83867, 0.84805, 0.85717, 0.86603, 0.87462, 0.88295, 0.89101,
0.89879, 0.90631, 0.91355, 0.92050, 0.92718, 0.93358, 0.93969, 0.94552,
0.95106, 0.95630, 0.96126, 0.96593, 0.97030, 0.97437, 0.97815, 0.98163,
0.98481, 0.98769, 0.99027, 0.99255, 0.99452, 0.99619, 0.99756, 0.99863,
0.99939, 0.99985, 1.00000
]
level = [] # Map.
fov = []
for x in range(W + 1):
fov.append([]) # Reset FOV
level.append([])
for y in range(H + 1):
fov[x].append(False)
level[x].append(False) # Every tile is floor
level[5][5] = 1 # Add some walls
level[11][11] = 1
level[10][16] = 1
level[11][17] = 1
px = 10 # Player coordinates
py = 10
# The FOV algo itself.
# It works like this:
# It starts at player coordinates and cast 360 rays
# (if step is 1, less is step is more than 1) in every direction,
# until it hits a wall.
# When ray hits floor, it is set as visible.
# Ray is casted by adding to x (initialy it is player's x coord)
# value of sin(i degrees) and to y (player's y) value of cos(i degrees),
# RAD times, and checking for collision with wall every step.
for i in range(0, RAYS + 1, STEP):
ax = sintable[i] # Get precalculated value sin(x / (180 / pi))
ay = costable[i] # cos(x / (180 / pi))
x = px # Player's x
y = py # Player's y
for z in range(RAD): # Cast the ray
x += ax
y += ay
if x < 0 or y < 0 or x > W or y > H: # If ray is out of range
break
fov[int(round(x))][int(round(y))] = 1 # Make tile visible
if level[int(round(x))][int(round(y))] == 1: # Stop ray if it hit
break # a wall.
# Let's draw it in console to show how pretty is that FOV!
for x in range(W + 1):
for y in range(H + 1):
if (x, y) == (px, py):
sys.stdout.write("@") # Player
elif fov[x][y] == 1:
if level[x][y] == 0: # Seen
sys.stdout.write(".")
else:
sys.stdout.write("#")
else:
sys.stdout.write("?") # Unseen
print