(Java)在保留方向和方向参考的同时围绕中心旋转

时间:2013-12-10 01:49:06

标签: java rotation translation graphics2d affinetransform

我正在设计一款自上而下的游戏,其中有一个“相机”用于平移游戏区域。相机可以旋转和翻译;翻译是大多数自上而下游戏的典型代表。

为了实现这一点,我使用了一个名为“Center”的类。在这些中心周围绘制了一组物体(例如,“Car”可能会延伸到中心,而Car有部件“轮子”和“引擎盖”。无论在什么位置和方向都有汽车,轮子和引擎盖也是如此。


我想要的东西:

(1)中心始终围绕屏幕中心旋转。 EG,旋转180度的屏幕中心左侧中心五个像素,最终将在屏幕中心右侧五个像素处。

(2)中心保持相对于屏幕中心的方向。因此,“面向”屏幕中心的汽车在旋转时会继续“面对”中心,反之亦然。

(3)向上,向下,向左和向右平移总是向上,向下,向左和向右移动“相机”。例如,无论汽车是朝上还是朝下,按下“向上”键都应该使轿厢向上移动。将汽车旋转180度(或完全)不应旋转平移方向(例如,使“向上”键平移)。


我可以一次获得一个,有时两个,但是无法获得所有这三个。这是我玩过的主要代码块,在draw函数之前调用:

protected void setCanvas(Graphics2D g){
    at = g.getTransform();                        //Used to restore the original
    Point screenCenter = Grid.FRAME_CENTER;
                  //Grid is the abstract class maintaining all
                  //properties of the frame and game grid
    g.translate(xloc,yloc);
    g.translate(screenCenter.x+xloc,screenCenter.y+yloc);
    g.rotate(rotation);
    g.scale(scale, scale);
    g.translate(-screenCenter.x-xloc, -screenCenter.y-yloc);
}

我知道变换以“相反”的顺序发生,因此上面的顺序应该是正确的,但我已经尝试了每一种排列,因为,你知道,为什么不这样做。

我也尝试过使用rotate函数同时改变位置:

public void addRotation(int rot){
    double pi = Math.PI;

    rotation = rotation + ((double) (rot))*pi/180;

    if(rotation > 2*pi){
        rotation = rotation - 2*pi;
    }else if(rotation < 0){
        rotation = rotation + 2*pi;
    }
    double hypoteneuse = Math.sqrt((double) (xloc*xloc+yloc*yloc));
    xloc = Math.cos(rotation)*hypoteneuse;
    yloc = Math.sin(rotation)*hypoteneuse;
}

无济于事。请注意,输入以度为单位,Center以弧度为单位存储当前旋转,这是Math和变换函数所需的。中心存储的所有变量都是双倍的 - 使用整数导致在很多轮换中出现一些(偶尔热闹的)舍入错误。

对于记录,这是我的translaterotate函数:

public void translate(int dx, int dy){
    xloc = xloc + dx;
    yloc = yloc + dy;
}

public void addRotation(int rot){
    rotation = rotation + ((double) (rot))*Math.PI/180;
}

显然xloc和`yloc是屏幕上对象的x和y位置,而且当没有旋转时,translate函数总能正常工作。


另一个注意事项(我可以想象一下,如果我能弄清楚上面的情况,但也可能),它不想保留三角形的形状 - 旋转后,x和y距离屏幕的中心总是一样的。

HALP?

1 个答案:

答案 0 :(得分:1)

看起来您需要将对象的位置和方向与屏幕/摄像头分开。我建议保持屏幕/摄像机的位置和旋转,然后每个物体都有自己的位置和旋转。

然后在绘图时,您可以先根据屏幕/摄像机值变换屏幕,然后绘制每个对象,最后反转屏幕的变换。

您可以使用AffineTransform对象来跟踪屏幕。

  AffineTransform at = new AffineTransform();
  at.translate(screenCenter.x, screenCenter.y);

每次用户移动或旋转时,都会将其添加到变换中。 E.g。

  at.rotate(ANGLE_CHOSEN_BY_USER);

然后当你准备好先画你时:

  g.tranform(at);
  //draw you object
  g.transform(at.createInverse());

每个对象都可以在需要的任何旋转或平移时绘制,而无需担心相机。