Я смотрел в Интернете на приведение лучей для python и решил исследовать некоторый код, который был размещен;поэтому большая часть этого не мой код изначально.Я просто хочу понять, как это работает.
Программа запускает свои карты чтения текстовых документов, каждый из которых состоит из «1» и пробелов, например:
11111111111111111
1 11 11
1 111 11 11 11 11
1 1 1 11 11
1 1 1 1 11
1 1 111 11 1
1 1 1111 11
1 1 11 11 11
1 1 1 11
1 1 11 1 11
1 1 1 1 111 11
1 1 11 1 11
1 1 1 1 11
1 11 1 1 1
1 1 111
11111111111111111
Чтениекод, который компилирует это в полезную информацию, показывает, что ...
Преобразует строку в список, заменяет пробелы на "0", перечисляет список дважды (так что каждый отдельный символ может быть изолирован) изатем отправляет его в виде сетки для карты (где каждый «1» или «0» является отдельным элементом в списке).
Эта часть кода выглядит следующим образом:
def create_level(file):
if file[-4:] != '.txt': file += '.txt'
f = open(os.path.join(path, file), 'r')
file = f.readlines()
for i, line in enumerate(file):
file[i] = list(line.rstrip('\n'))
for j, char in enumerate(file[i]):
if char == ' ':
file[i][j] = 0
else:
file[i][j] = int(char)
f.close()
mapBoundX = len(file)
mapBoundY = len(file[0])
mapGrid = []
for i, line in enumerate(file):
mapGrid.append([])
for j, char2 in enumerate(file[i]):
if char2 != 0:
mapGrid[i].append(char2)
else:
mapGrid[i].append(0)
return mapBoundX, mapBoundY, mapGrid
В некоторых следующих функциях данные, взятые из предыдущего кода, преобразуются в фактическое приведение лучей.Я не совсем понимаю, что все это значит, но я учусь по ходу дела.Вот эта часть:
def main():
mapBoundX, mapBoundY, mapGrid = create_level(levelNum)
posX, posY = 8.5, 10.5
dirX, dirY = 1.0, 0.0
planeX, planeY = 0.0, 0.66
while True:
#Input handling
for event in pygame.event.get():
if event.type == QUIT:
Quit()
return
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
Quit()
return
#CEILING AND FLOOR
pygame.draw.rect(SCREEN, ceiling_colour, (0, 0, WIDTH, (HEIGHT - map_size) / 2))
pygame.draw.rect(SCREEN, floor_colour, (0, (HEIGHT - map_size) / 2, WIDTH, (HEIGHT - map_size) / 2))
for x in range(0, WIDTH, resolution):
#Initial setup
cameraX = 2 * x / WIDTH - 1
rayPosX = posX
rayPosY = posY
rayDirX = dirX + planeX * cameraX + 0.000000000000001 #Add small value to avoid division by 0
rayDirY = dirY + planeY * cameraX + 0.000000000000001 #Add small value to avoid division by 0
#Which square on the map the ray is in
mapX = int(rayPosX)
mapY = int(rayPosY)
#The length of one ray from one x-side or y-side to the next x-side or y-side
deltaDistX = sqrt(1 + rayDirY ** 2 / rayDirX ** 2)
deltaDistY = sqrt(1 + rayDirX ** 2 / rayDirY ** 2)
zBuffer = []
#Calculate step and initial sideDist
if rayDirX < 0:
stepX = -1
sideDistX = (rayPosX - mapX) * deltaDistX
else:
stepX = 1
sideDistX = (mapX + 1 - rayPosX) * deltaDistX
if rayDirY < 0:
stepY = -1
sideDistY = (rayPosY - mapY) * deltaDistY
else:
stepY = 1
sideDistY = (mapY + 1 - rayPosY) * deltaDistY
#Digital differential analysis (DDA)
while True:
#Jump to next map square
if sideDistX < sideDistY:
sideDistX += deltaDistX
mapX += stepX
side = 0
else:
sideDistY += deltaDistY
mapY += stepY
side = 1
#Check if ray hits wall or leaves the map boundries
if mapX >= mapBoundX or mapY >= mapBoundY or mapX < 0 or mapY < 0 or mapGrid[mapX][mapY] > 0:
break
#Calculate the total length of the ray
if side == 0: rayLength = (mapX - rayPosX + (1 - stepX) / 2) / rayDirX
else: rayLength = (mapY - rayPosY + (1 - stepY) / 2) / rayDirY
#Calculate the length of the line to draw on the screen
lineHeight = (HEIGHT / rayLength) * wall_height
#Calculate the start and end point of each line
drawStart = -lineHeight / 2 + (HEIGHT - map_size) / 2
drawEnd = lineHeight / 2 + (HEIGHT - map_size) / 2
#Calculate where exactly the wall was hit
if side == 0: wallX = rayPosY + rayLength * rayDirY
else: wallX = rayPosX + rayLength * rayDirX
wallX = abs((wallX - floor(wallX)) - 1)
#Find the x coordinate on the texture
texX = int(wallX * texWidth)
if side == 1 and rayDirX > 0: texX = texWidth - texX - 1
if side == 1 and rayDirY < 0: texX = texWidth - texX - 1
c = max(1, (255.0 - rayLength * 27.2) * (1 - side * .25))
yStart = max(0, drawStart)
yStop = min(HEIGHT, drawEnd)
pixelsPerTexel = lineHeight / texHeight
colStart = int((yStart - drawStart) / pixelsPerTexel + .5)
colHeight = int((yStop - yStart) / pixelsPerTexel + .5)
yStart = int(colStart * pixelsPerTexel + drawStart + .5)
yHeight = int(colHeight * pixelsPerTexel + .5)
column = texture.subsurface((texX, colStart, 1, colHeight))
column = column.copy()
column.fill((c, c, c), special_flags=BLEND_MULT)
column = pygame.transform.scale(column, (resolution, yHeight))
SCREEN.blit(column, (x, yStart))
Теперь, к моей главной проблеме:
Я вижу ссылку на текстуру в разделе столбца, и она инициализируется ранее, но я не могу показатьсячтобы он загружал две разные текстуры одновременно.В идеале я хочу, чтобы некоторые блоки стен были одной текстурой, а некоторые - другой.Я попытался добавить третий символ, «2», в исходные текстовые документы карты, чтобы посмотреть, сможет ли программа их различить, но я не могу заставить это работать.
Если кто-то может объяснить, пожалуйстамне, как это работает, или что я могу делать неправильно при редактировании, эта помощь будет очень признательна.Спасибо!