如何修复Python Raycaster(光线投射器)中的鱼眼效应?
修复Python光线投射器中的鱼眼效应问题
我始终无法修复Python光线投射器(Raycaster)中的鱼眼效应,代码可正常运行,但查阅相关方案后仍怀疑存在更深层问题。代表“墙体”的竖线本该笔直却呈现弯曲,推测原因是玩家发出的射线与直墙交互时长度存在差异。我是Python新手,曾尝试将原始射线长度乘以玩家方向与射线方向差值的余弦值,但未见效果。
相关代码如下:
# imports import turtle, math # variables raycastAngle = 90 raycastRayNum = 100 raycastRayRange = 100 raycastRayStep = 2 screenX, screenY = 800, 600 screen = turtle.Screen() screen.screensize(screenX, screenY) screen.tracer(0) screen.bgcolor(0, 0, 0) raycaster = turtle.Turtle() raycaster.penup() raycaster.hideturtle() player = turtle.Turtle() player.penup() player.setheading(45) player.hideturtle() sceneStamp = turtle.Turtle() sceneStamp.penup() sceneStamp.hideturtle() walls = { 'test wall1':{ 'x': 70, 'y': 70, 'width': 100, 'height': 100 }, } # subprograms def distFromCoords(startCoord, endCoord): xDist = endCoord[0] - startCoord[0] yDist = endCoord[1] - startCoord[1] distance = math.sqrt((xDist * xDist) + (yDist * yDist)) roundedDistance = round(distance) return roundedDistance def isInsideWall(turtle): turtleX, turtleY = turtle.xcor(), turtle.ycor() for wall in walls.values(): wallX, wallY = wall['x'], wall['y'] wallWidth, wallHeight = wall['width'], wall['height'] left = wallX - wallWidth / 2 right = wallX + wallWidth / 2 bottom = wallY - wallHeight / 2 top = wallY + wallHeight / 2 if left <= turtleX <= right and bottom <= turtleY <= top: return True return False def raycast(angle, rayNum, rayRange, rayStep, showRay): raycaster.clear() startAngle = player.heading() - (angle / 2) rayLengths = [] for i in range(rayNum): raycaster.penup() raycaster.goto(player.xcor(), player.ycor()) raycaster.setheading(startAngle + (i * (angle / rayNum))) if showRay: raycaster.pendown() for j in range(rayRange // rayStep): raycaster.forward(rayStep) if isInsideWall(raycaster): break rayLengths.append(distFromCoords([player.xcor(), player.ycor()], [raycaster.xcor(), raycaster.ycor()])) return rayLengths def drawScreen(rayLengths): global screenX, screenY global raycastAngle, raycastRayNum, raycastRayRange, raycastRayStep sceneStamp.clear() sceneStamp.penup() sceneStamp.pensize(3) sceneStamp.goto(-(screenX // 2), 0) for i in range(len(rayLengths)): rayLength = rayLengths[i] height = screenY * (1 - (rayLength / raycastRayRange)) height = max(0, min(screenY, height)) sceneStamp.color(0, 0, (0 + (height / screenY))) sceneStamp.sety(height / 2) sceneStamp.pendown() sceneStamp.sety(-height / 2) sceneStamp.penup() sceneStamp.setx(sceneStamp.xcor() + (screenX / raycastRayNum)) def gameUpdate(): screen.update() drawScreen(raycast(raycastAngle, raycastRayNum, raycastRayRange, raycastRayStep, True)) turtle.ontimer(gameUpdate, 15) # main program gameUpdate() screen.listen() screen.mainloop()
效果截图:
内容的提问来源于stack exchange,提问作者George Hyde
相关产品推荐
相关产品推荐

