创建UI和glRotatef()时出现问题

2024-09-26 18:16:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用PythonPyGameLegacy PyOpenGL制作一个最小的Doom风格的FPS游戏引擎。我希望玩家能够通过按左右箭头键来使用glRotatef()朝着四个方向看——向前、向后、向左和向右。你知道吗

出现了一些问题:

  1. 一把枪(一个应用了纹理的立方体,根据玩家面对的方向改变纹理坐标)应该总是出现在相机前面0.5个单位的位置,在相应的x和z位置,这取决于角度glRotatef()将其设置为面向,移动到一个奇怪的位置,如果我在x轴上移动,然后向左看,除非我站在房间的中心。当我向左和向右移动时,立方体看起来也是静态的,尽管我提供了从glGetDoublev()获得的x值;当我向前移动时,枪看起来是缩放的,尽管我从未实现过这样的功能。

  2. 当我打电话的时候

    if event.type == pygame.KEYDOWN: # key pressed events
                    if event.key == pygame.K_LEFT:
                        glRotatef(-90,0,1,0)
                        if direction == 0:
                            direction = 3
                        else:
                            direction -= 1
    

    往房间的左边看,我偶尔会被移到墙里面,这有时会进一步影响枪的位置。你知道吗

    我尝试过添加固定的x和z变量(x_stepsz_steps),每次玩家移动时都会增加0.1。我不太清楚为什么这会消除“静电枪”的问题,但它确实解决了。然而,当我旋转相机时,同样的问题(枪移动到一个奇怪的位置)仍然发生。你知道吗

    ## pygame/opengl initialisation code
    def main():
        pygame.init()
        display = (800,600)
        global displaySurface
        displaySurface = pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
        pygame.display.set_caption("Wolfenstein 4D")
        glEnable(GL_TEXTURE_2D)
        glEnable(GL_DEPTH_TEST)
        gluPerspective(45, (display[0]/display[1]),0.1,50.0)
    
    ## game loop, obtaining x,y,z positions and looking around the room
    def room1():
        direction = 3 ## 3 = forward, 2 = left, 1 = backward, 0 = right
        while True:
            pos = glGetDoublev(GL_MODELVIEW_MATRIX)
            x = pos[3][0]
            y = pos[3][1]
            z = pos[3][2]
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
    
                if event.type == pygame.KEYDOWN: # key pressed events
                    if event.key == pygame.K_LEFT:
                        glRotatef(-90,0,1,0)
                        if direction == 0:
                            direction = 3
                        else:
                            direction -= 1
                        x_steps = 0
                        z_steps = 0
    
                    if event.key == pygame.K_RIGHT:
                        glRotatef(90,0,1,0)
                        if direction == 3:
                            direction = 0
                        else:
                            direction += 1
                        x_steps = 0
                        z_steps = 0
    
    ## movement code
            spd = 0.1
            keys = pygame.key.get_pressed()
            if direction == 3:
                if keys[pygame.K_a]:
                        glTranslatef(spd,0,0)
                        x_steps -= spd
                if keys[pygame.K_d]:
                        glTranslatef(-spd,0,0)
                        x_steps += spd
                if keys[pygame.K_w]:
                        glTranslatef(0,0,spd)
                        z_steps -= spd
                if keys[pygame.K_s]:
                        glTranslatef(0,0,-spd)
                        z_steps += spd
            if direction == 2:
                if keys[pygame.K_a]:
                        glTranslatef(0,0,-spd)
                        x_steps += spd
                if keys[pygame.K_d]:
                        glTranslatef(0,0,spd)
                        x_steps -= spd
                if keys[pygame.K_w]:
                        glTranslatef(spd,0,0)
                        z_steps -= spd
                if keys[pygame.K_s]:
                        glTranslatef(-spd,0,0)
                        z_steps += spd
    
    ## gun drawing code in game loop
                if direction == 3:
                    loadTexture("gun1.png")
                    drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
                if direction == 2:
                    loadTexture("gun.png")
                    drawHUDGun(z-0.5,-0.1,x+0.5,2,0.1,0.1,0.1)
    
    ## gun drawing function
    def drawHUDGun(x,y,z,angle,width,height,depth=0.5,color = ((1,1,1))):
        vertices = (
            (width+x,-height+y,-depth+z),
            (width+x,height+y,-depth+z),
            (-width+x,height+y,-depth+z),
            (-width+x,-height+y,-depth+z),
            (width+x,-height+y,depth+z),
            (width+x,height+y,depth+z),
            (-width+x,-height+y,depth+z),
            (-width+x,height+y,depth+z)
        )
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        glBegin(GL_QUADS)
        if angle == 3:
            j = 0
        if angle == 2:
            j = 8
    
        i = 0
        for surface in surfaces:
            i += 1
            for vertex in surface:
                glColor4f(1,1,1,1)
                setTexCoord(0, texCoords, j)
                if angle == 3:
                    if i >= 0 and i < 4:
                        if j < 4:
                            j += 1
                if angle == 2:
                    if i == 2:
                        if j < 12:
                            j += 1
                glVertex3fv(vertices[vertex])
        glEnd()
        glDisable(GL_BLEND)
    
        glBegin(GL_LINES)
        for edge in edges:
            glColor3fv((0,1,0))
            for vertex in edge:
                glVertex3fv(vertices[vertex])
        glEnd()
    
    ## implementation of the functions
    
    main()
    room1()
    

    我预计枪在任何方向上都会出现在玩家前面0.5个单位的位置,而不管他们在房间里的什么位置,但是枪常常因为被分配了不正确的x或z坐标而不在视线范围内。


Tags: keyineventifdisplaykeysstepswidth
1条回答
网友
1楼 · 发布于 2024-09-26 18:16:13

在传统的OpenGL中,存在不同的当前矩阵。受矩阵运算影响的当前矩阵可由^{}选择。每个矩阵都组织在一个堆栈上。矩阵可以由^{}/^{}推送和弹出。你知道吗

投影矩阵应设置为投影矩阵堆栈,视图和模型转换为modelview矩阵堆栈:

// choose projection matrix stack
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]),0.1,50.0)

// choose modelview matrix stack, for the following matrix operations
glMatrixMode(GL_MODELVIEW)

枪应该放在第一人称视角(“在你面前”)。实现这一点最简单的方法是在viewspace中绘制枪,这意味着您必须取消对modelview矩阵的所有先前转换。矩阵可以用identity matrix替换为^{}
将modelview矩阵保存到堆栈中,设置标识矩阵,绘制枪,最后还原modelview矩阵。例如:

glPushMatrix()
glLoadIdentity()
drawHUDGun(x,-0.1,z-0.5,3,0.1,0.1,0.1)
glPopMatrix()

相关问题 更多 >

    热门问题