Pyglet 3d控件未按预期工作

问题描述

我目前正在学习pyglet和opengl的基础知识。我已经看过许多教程和网站来学习pyglet和opengl,我认为我会做一个简单的3d游戏。但是,我被相机的运动控制卡住了,我似乎无法弄清楚代码出了什么问题。当我按下def addnew(): n = int(input('ENTER TOTAL NUMBER OF PROCESSES: ')) for i in range(n): newlist = [] newlist.append(input('Enter process name: ')) newlist.append(int(input('Enter process Arrival Time: '))) newlist.append(int(input('Enter Execution Time: '))) print('') print(newlist) p.append(newlist) 时,相机会正常向后移动,但是当我按下S时,相机不会移动,如果再按一次,它的移动速度会比以前快一些。为什么会这样?

W

解决方法

您可能误解了glTranslate函数。

glTranslate的工作方式如下:它采用当前矩阵,并乘以glTranslate参数给定的转换矩阵。

因此,调用glTranslate(x,y,z)会导致以下方程式:

new_position = old_position + (x,y,z)

如果每帧调用glTranslate,则{x,y,z}是变化率(即速度)。

为什么当我按下S和W时它会停止?

好吧,让我们看一下代码和方程式。您将self.position用作glTranslate的参数。因此,self.position不是位置,而是相机的当前速度(或变化率)。

如果按一次S,将调用on_key_press,具有以下效果:

self.change_z = -self.speed
self.position[2] += self.change_z # self.position[2] equals now -self.speed

现在按一次W,然后再次调用on_key_press,结果是:

self.change_z = +self.speed
self.position[2] += self.change_z # self.position[2] equals now 0,because self.position[2] was -self.speed; -self.speed + self.speed = 0

含义是,每次按任意一个控制键,都将离散地加速相机。

假设您在启动程序后按两次S会导致self.position[2]等于2 * -self.speed

如何解决此问题?

更改以下内容

self.position[0] += self.change_x
self.position[2] += self.change_z

self.position[0] = self.change_x
self.position[2] = self.change_z

我真的希望我清楚地说,为什么self.position实际上是速度而不是位置。建议您将self.position重命名为self.velocity或类似的名称。


或者,您每次更改位置时都可以通过执行以下操作来重建矩阵:

    def on_draw(self):
        self.clear()
        glLoadIdentity()
        gluPerspective(90,0.5,0.01,1000)
        glTranslatef(*self.player.position)
        self.quad.vertices.draw(GL_TRIANGLES)

我不得不采取进一步的措施。如果您添加另一种方法,那么self.position只是一个速度(在您的原始版本中!)这一事实变得显而易见:

class Window(...):

    # ...

    def update(self,dt):
        self.clear()
        glTranslatef(*self.player.position)
        self.quad.vertices.draw(GL_TRIANGLES)

并用以下几行扩展Window.__init__

class Window(...):
    def __init__(...):
        # ...

        import pyglet.clock
        pyglet.clock.schedule_interval(self.update,1/60)
        # pyglet now calls update(...) 60 times a second