【问题标题】:Detect which cube a user is looking at?检测用户正在查看哪个立方体?
【发布时间】:2019-07-15 21:56:58
【问题描述】:

我正在使用 python 制作类似于 Minecraft 的游戏。我有一个用户可以四处走动并环顾四周的世界,但我不知道如何制作它,以便他们可以打破和放置块。

我需要知道如何从世界上的块的 3d 数组(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]]]),它们的位置(xyz) 和头部旋转 (xrot,yrot)。

我也只需要在离他们所在位置一定距离的地方使用它,也许是 5 个街区。我试图找到一条线的功能并遵循它,但没有成功,我在互联网上四处寻找,找不到我需要的东西。

我需要能够根据他们正在查看的一侧确定他们会破坏哪个方块或新方块会去哪里。

我需要找到我在看哪个立方体的哪个面。这是我编写的代码,但某些数学运算必须关闭,因为它不起作用。

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

【问题讨论】:

  • 给定用户位置和视图方向,您只需遍历 3D 网格并选择第一个占用的单元格。见this answer
  • @NicoSchertler 我所有的立方体都是相同的大小并且它们在一个网格中,我需要一个不涉及大小的更简单的答案
  • 该答案假定大小一致。没有比这更简单的了
  • @NicoSchertler 好的,我会看看
  • @NicoSchertler 您能否展示每个变量所指的内容以及我如何将其应用于我正在尝试做的事情?

标签: python opengl math 3d pyopengl


【解决方案1】:

您可以在玩家周围形成一个接触球,并使用从玩家脸部“突出”的半径。

半径 r 是用户可以看到一个方块并且仍然能够影响它的最大距离。

使用三角形可以检测半径的末端是否在块内等。

【讨论】:

  • 这根本没有意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多