我正在设计一款自上而下的游戏,其中有一个“相机”用于平移游戏区域。相机可以旋转和翻译;翻译是大多数自上而下游戏的典型代表。
为了实现这一点,我使用了一个名为“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
和变换函数所需的。中心存储的所有变量都是双倍的 - 使用整数导致在很多轮换中出现一些(偶尔热闹的)舍入错误。
对于记录,这是我的translate
和rotate
函数:
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?
答案 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());
每个对象都可以在需要的任何旋转或平移时绘制,而无需担心相机。