问题描述
我正在制作像德军总部 3D 那样的 2.5d 光线投射引擎。我需要帮助纠正鱼眼效果。我了解正在发生的事情并且已经做了我自己的数学来尝试摆脱它,但它并没有完全摆脱影响:“n *= math.cos(fish_eye/(180/3.1415))” n 是欧几里得距离和fish_eye从45到0到45(90度FOV)“/(180/3.1415)”是从度数转换为弧度。当您离得远一些时,鱼眼看起来并不坏,但是当您靠近时,您几乎看不出它应该是 3D 的。
这是我写的代码(请不要告诉我它有多糟糕,我绝对没有做任何事情来使它更快或更漂亮):
import pygame
from pygame.locals import *
import time
import collections
import numpy as np
import math
pygame.init()
display_width = 500
display_height = 500
px = 3
py = 1
pd = 0
window = pygame.display.set_mode((display_width,display_height),pygame.RESIZABLE)
pygame.display.set_caption("Window")
black = (0,0)
white = (255,255,255)
green = (0,0)
red = (255,0)
font = pygame.font.SysFont("monospace",40)
map1 = np.matrix([[1,1,1],[1,1]])
def game_setup():
global black,white,green,red
window.fill(white)
mapdisp(map1)
pygame.display.update()
gameLoop()
def mapdisp(mapVar):
for y in range(0,50):
for x in range(0,50):
if mapVar[y,x]:
pygame.draw.rect(window,red,pygame.Rect(x,y,1))
def raycast(movement,correct):
global pd,px,py,map1
stepy = math.sin(pd/(180/3.14159))
stepx = math.cos(pd/(180/3.14159))
print("Look angle: ",pd)
print("Step on the X: ",stepx)
print("Step on the Y: ",stepy)
window.fill(white)
mapdisp(map1)
if movement != "none":
if movement == "back":
pstepx = -1*(stepx/4)
pstepy = -1*(stepy/4)
else:
pstepx = stepx/4
pstepy = stepy/4
if map1[int(py),int(px + pstepx)]:
pstepx = 0
if map1[int(py + pstepy),int(px)]:
pstepy = 0
px += pstepx
py += pstepy
for ray in range(-45,45):
fish_eye = abs(ray)
stepy = math.sin((pd + ray) / (180 / 3.14159))
stepx = math.cos((pd + ray) / (180 / 3.14159))
hit = False
n = 0
rx = px
ry = py
while not hit or n >= 100:
rx += stepx
ry += stepy
if map1[int(ry),int(rx)]:
hit = True
if map1[int(ry),int(rx-stepx)]:
color = (100,100,100)
else:
color = (50,50,50)
if correct:
n = n*math.cos(fish_eye/(180/3.1415))
pygame.draw.rect(window,color,pygame.Rect((ray + 45)*5,200 + 2*n,5,200 - 4*n))
else:
n += 1
pygame.draw.rect(window,pygame.Rect(rx,ry,1))
pygame.display.update()
def gameLoop():
global pd
play = True
rotate = 0
movement = "none"
start_time = time.time()
frames = 0
correct = True
while play:
forward = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
rotate = 0
movement = "none"
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
print("left")
rotate = -1
if event.key == pygame.K_RIGHT:
print("right")
rotate = 1
if event.key == pygame.K_ESCAPE:
pygame.quit()
quit()
if event.key == pygame.K_UP:
movement = "forward"
elif event.key == pygame.K_DOWN:
movement = "back"
if event.key == pygame.K_LSHIFT:
correct = True
elif event.key == pygame.K_RSHIFT:
correct = False
if rotate != 0 or movement != "none":
pd += rotate
if pd >= 360:
pd -= 360
elif pd < 0:
pd += 360
raycast(movement,correct)
frames += 1
if time.time()-start_time >= .1:
text1 = font.render(str(frames*10),True,red)
window.blit(text1,(300,1))
pygame.display.update()
frames = 0
start_time = time.time()
game_setup()
time.sleep(10)
我看过很多溢出的帖子,但要么我看不懂,要么不起作用。
这是一张照片:
如果你愿意,你可以将上面的代码复制并粘贴到 pycharm 或其他代码运行器中。只需记住安装所有导入 (:
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)