Hello!
I just started to program a roguelike, and I ran into a problem with my shadowcast. Perhaps someone can help.
(This is only 1/8 of a shadowcast so far, so only one octant)
This is what happens:
(@ = player, S = shadow, . = visible, # = wall)
@......
S......
S##S...
SSSSS..
When I move closer to the wall, I can see around the corner:
SSSSSSS
@......
S##....
SSSSSS.
Similar behaviour occurs in similar situations. Can someone give me a hint what might be the case?
The relevant code:
def shadowcast(self,start_slope, end_slope, dx):
# iterative shadowcast
if dx < 30: #30 is the maximal range of vision
# dx is the distance from the @ the current iteration is looking at
# a few renames for our convenience
pc_x = PC.position[0]
pc_y = PC.position[1]
original_end_slope = end_slope
# calculate the starting point of this column
starting_point = int(math.floor(start_slope*dx))
# checks if the starting point is still on the map
if (starting_point + pc_y) > (MAP_HEIGHT - 1):
starting_point = (MAP_HEIGHT - 1) - pc_y
end_point = int(math.ceil(end_slope*dx))
# does the calculation for the column start with a blocked los?
prior_blocked = map.content[pc_x + dx][pc_y + starting_point].block_los
# some cosmetic changes. Make more walls visible
cosmetic_y = starting_point + 1
if (pc_y + cosmetic_y) < (MAP_HEIGHT):
if (map.content[pc_x+dx][pc_y + cosmetic_y].block_los):
if not(map.content[pc_x+dx-1][pc_y + starting_point].block_los):
map.content[pc_x+dx][pc_y + cosmetic_y].visible = True
for dy in range(starting_point, end_point-1, -1):
# The tile that is checked
tile_x = pc_x + dx
tile_y = pc_y + dy
# every tile checked is visible, or we wouldn't check it.
map.content[tile_x][tile_y].visible=True
# If we go from unblocked to blocked, new end_slope is
# calculated and recursive call is executed
if (not prior_blocked) and map.content[tile_x][tile_y].block_los:
end_slope = (dy+.5) /float(dx-.5)
if (tile_x+1)<MAP_WIDTH:
# Recursively continue to calculate
self.shadowcast(start_slope, end_slope, dx+1)
prior_blocked = True
# If we geo from blocked to unblocked, a new start_slope is
# calculated for later recursive calls
if prior_blocked and (not(map.content[tile_x][tile_y].block_los)):
start_slope = (dy+.5) /float(dx+.5)
prior_blocked = False
# if we are still on the map, recursively calculate the next column
if (pc_x+dx+1)<MAP_WIDTH and (not map.content[pc_x+dx][pc_y+end_point].block_los):
self.shadowcast(start_slope, original_end_slope, dx+1)