LWJGL - 轮换和移动=问题

时间:2015-10-21 20:39:09

标签: java rotation logic 2d lwjgl

长话短说,我正在制作一个LWJGL引擎,我正在绘制一个基本的QUAD。当我绘制此QUAD并使用键盘监听器时,它会完美地向上/向下/向左/向右移动。

然而,当我翻译和旋转时,它也会绕着它的中心点旋转,将它们一起使用,然后你就会遇到问题。旋转开始偏离轴,每次移动时,你都会绕着其他地方的一个奇怪的点转动。

如何制作它以便我可以移动QUAD(不是相对于旋转),还可以旋转它?

修改1

我发现这个QUAD的一个主要问题是,当我转到它时,我的整个屏幕(包括文字)都会旋转......

我目前的结果:

运动前 Before movement.

运动后(希望你注意到它移动了一圈,而不是在我向左移动时左转。) After Movement.

代码:

(显示设置)

try {
    Display.setDisplayMode(new DisplayMode(width, height));
    Display.setVSyncEnabled(vsync);
    Display.create();
    open = true;

    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glLoadIdentity();
    // Sets (0, 0) to the top left corner.
    GL11.glOrtho(0, this.width, this.height, 0, 1, -1);
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
} catch (LWJGLException e) {
    e.printStackTrace();
}

(键盘监听器)

public void userLogic() {
    if (keyboard.isKeyDown(Keyboard.KEY_A)) {
        rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
        rect.setRotation(-1);
    } else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
        rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
        rect.setRotation(1);
    } if (keyboard.isKeyDown(Keyboard.KEY_W)) {
        rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
    } else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
        rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
    }
}

(移动/旋转逻辑)

public void setRotation(float degrees) {
    // TODO: Fix whatever the hell the problem is here.
    GL11.glTranslatef(x + (width / 2), y/* + (height / 2)*/, 0);
    GL11.glRotatef(degrees, 0f, 0f, 1f);
    GL11.glTranslatef(-(x + (width / 2)), -(y/* + (height / 2)*/), 0);
}

public void setLocation(int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}

(绘制QUAD,(与渲染过程的其余部分分开))

public void render() {
    switch(type) {
    case IMAGE:
        // Not ready yet.
        break;
    case TRIANGLE:
        // Not ready yet.
        break;
    case RECTANGLE:
        GL11.glColor3f(colour.red, colour.green, colour.blue);

        // X, Y, WIDTH, HEIGHT are the QUADS coords, not the displays or anything else's.

        GL11.glBegin(GL11.GL_QUADS);
            GL11.glVertex2f(x, y);
            GL11.glVertex2f(x + width, y);
            GL11.glVertex2f(x + width, y + height);
            GL11.glVertex2f(x, y + height);
        GL11.glEnd();
        break;
    }
}

任何帮助都将不胜感激,如果您要进行投票,请提供理由,以便我可以改进这个问题,甚至更好地发表评论。

1 个答案:

答案 0 :(得分:1)

此处的问题是您在setRotation函数中调用OpenGL的翻译和旋转函数的顺序。呼叫顺序必须是翻译(如果有的话) - >旋转(如果有的话) - >缩放。无论如何,您无法更改此调用或混合的顺序。否则你将无法获得理想的结果。这是因为OpenGL在内部处理这些命令的方式。

SetRotation功能更改为

public void setRotation(float degrees) {
    // TODO: Fix whatever the hell the problem is here.
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    GL11.glTranslatef(x , y , 0);       
    GL11.glRotatef(degrees, 0f, 0f, 1f);

}

如果添加行

,您会注意到
GL11.glTranslatef(x , y, 0);

下面

GL11.glRotatef(degrees, 0f, 0f, 1f);

,结果将完全不同。意味着订单很重要。

userLogic()功能也存在一些问题。在这种情况下,您需要创建一个全局变量来存储旋转,然后将其传递给setRotation()

float rotValue = 0;
public void userLogic() {
    if (keyboard.isKeyDown(Keyboard.KEY_A)) {
        rect.setLocation(rect.x - 1, rect.y, rect.width, rect.height);
        rotValue-=.1f;
        rotValue=rotValue<0?rotValue+360:rotValue;
        rect.setRotation(rotValue);
    } else if (keyboard.isKeyDown(Keyboard.KEY_D)) {
        rect.setLocation(rect.x + 1, rect.y, rect.width, rect.height);
        rotValue+=.1f;
        rotValue=rotValue>=360?rotValue-360:rotValue;
        rect.setRotation(rotValue);
    } if (keyboard.isKeyDown(Keyboard.KEY_W)) {
        rect.setLocation(rect.x, rect.y - 1, rect.width, rect.height);
    } else if (keyboard.isKeyDown(Keyboard.KEY_S)) {
        rect.setLocation(rect.x, rect.y + 1, rect.width, rect.height);
    }
}

最后在render()函数内,传入以(0,0)为中心的顶点。 glTranslatef将负责翻译。

case RECTANGLE:
        GL11.glColor3f(colour.red, colour.green, colour.blue);
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glVertex2f(-width/2, -height/2);
        GL11.glVertex2f(width/2, -height/2);
        GL11.glVertex2f(width/2, height/2);
        GL11.glVertex2f(-width/2, height/2);
        GL11.glEnd();
        GL11.glMatrixMode(GL11.GL_MODELVIEW); //resetting the rotation
        GL11.glLoadIdentity();  //and translation so that other
                                //objects are unaffected
            break;

这是一个简单的lwjgl项目,我展示了四边形和三角形的平移和旋转 https://gist.github.com/Coditivity/0eedc86447a509f6b5ef