I am making game sort of like Minecraft using python. I have a world that the user can walk around and look around in but I don't know how to make it so they can break and place blocks.
I need to know how to calculate the block that they are looking at from a 3d array of the blocks in the world (blocks
, format:[[[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]]]
), their position (x
,y
,z
) and head rotation (xrot
,yrot
).
I also only need it in a certain distance away from where they are, maybe 5 blocks. I tried to find a function for a line and kind of follow it but that didn't work out and I looked around on the internet and I couldn't find what I needed.
I need to be able to figure out which block they would break or where a new block would go based of the side they are looking at.
I need to find which face of which cube I am looking at. This is the code I made but some of the math must be off because it isn't working.
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