Я делаю игру вроде Minecraft, используя python.У меня есть мир, в котором пользователь может ходить и смотреть по сторонам, но я не знаю, как сделать так, чтобы они могли разбивать и размещать блоки.
Мне нужно знать, как рассчитать блок, которым он являетсяглядя на трехмерный массив блоков в мире (blocks
, формат: [[[a,b,c],[d,e,f],[g,h,i]],[[j,k,l],[m,n,o],[p,q,r]],[[s,t,u],[v,w,x],[y,z,0]]]
), их положение (x
, y
, z
) и вращение головы (xrot
, yrot
)).
Мне также нужно это только на определенном расстоянии от того места, где они находятся, может быть, 5 блоков.Я попытался найти функцию для линии и отчасти следовать ей, но это не сработало, и я осмотрелся в Интернете и не смог найти то, что мне нужно.
Мне нужно иметь возможностьвыяснить, какой блок они сломают или куда пойдет новый блок, основываясь на стороне, на которую они смотрят.
Мне не нужно знать, как перебирать трехмерную сетку, и мне не нужно, чтобы это былотолько один раз для каждого куба мне нужно выяснить, на какой блок они смотрят и на какое лицо смотрят.Я сделал этот код, используя свои математические знания, но по какой-то причине он просто не работает как 80% времени, но иногда он может определить, на какой куб я смотрю (Обратите внимание, 0,0,0 кубав центре внизу)
def get_looking_at(xrot, yrot, xpos, ypos, zpos, blocks, reach):
xrot, yrot = math.radians(xrot), math.radians(yrot)
xform = sin(xrot)*cos(yrot)+xpos
yform = sin(yrot)+ypos
zform = -(cos(xrot)*cos(yrot))+zpos
xforward = xform-xpos >= 0
yforward = yform-ypos >= 0
zforward = zform-zpos >= 0
if xforward:
xset = [floor(x+xpos+.5)+.5 for x in range(reach)]
else:
xset = [floor((-x)+xpos+.5)-.5 for x in range(reach)]
if yforward:
yset = [ceil(y+ypos) for y in range(reach)]
else:
yset = [floor((-y)+ypos) for y in range(reach)]
if zforward:
zset = [floor(z+zpos+.5)+.5 for z in range(reach)]
else:
zset = [floor((-x)+xpos+.5)-.5 for x in range(reach)]
xint = []
yint = []
zint = []
for x in xset:
y = ((yform-ypos)*x)/(xform-xpos)
z = ((zform-zpos)*x)/(xform-xpos)
xint.append((x, y+ypos, z+zpos))
for y in yset:
x = ((xform-xpos)*y)/(yform-ypos)
z = ((zform-zpos)*y)/(yform-ypos)
yint.append((x+xpos, y, z+zpos))
for z in zset:
x = ((xform-xpos)*z)/(zform-zpos)
y = ((yform-ypos)*z)/(zform-zpos)
zint.append((x+xpos,y+ypos,z))
intercepts = dict()
for pos in xint:
intercepts[(pos[0]-xpos)**2+(pos[1]-ypos)**2+(pos[2]-zpos)**2] = (pos[0], pos[1], pos[2], "x")
for pos in yint:
intercepts[(pos[0]-xpos)**2+(pos[1]-ypos)**2+(pos[2]-zpos)**2] = (pos[0], pos[1], pos[2], "y")
for pos in zint:
intercepts[(pos[0]-xpos)**2+(pos[1]-ypos)**2+(pos[2]-zpos)**2] = (pos[0], pos[1], pos[2], "z")
indices = [x for x in intercepts]
indices.sort()
for index in indices:
connection = intercepts[index]
if xforward:
x = floor(connection[0]+.5)
xdir = "e"
else:
x = ceil(connection[0]-.5)
xdir = "w"
if yforward:
y = floor(connection[1])
ydir = "d"
else:
y = floor(connection[1])+1
ydir = "u"
if zforward:
z = ceil(connection[2]-.5)
zdir = "n"
else:
z = floor(connection[2]+.5)
zdir = "s"
print(x,y,z)
try:
if blocks.get_data(x, y, z) != None:
if math.sqrt(index) <= reach:
if connection[3] == "x":
return x, y, z, xdir
if connection[3] == "y":
return x, y, z, ydir
if connection[3] == "z":
return x, y, z, zdir
else:
return
else:
continue
except IndexError:
continue
return