Java JScrollBar 设置值加倍

Java JScrollBar set value with double

所以我在 Java 中制作了一个简单的游戏,其中在瓦片地图中有一个小坦克。虽然我遇到了一个关于 JScrollBars 的问题:当我将坦克的 body 旋转到北偏东的某个角度(特别是 14 或更少)并且我向前移动坦克(使用“W”键)时, tank 不会按预期在 x 和 y 方向上移动,仅在 y 方向上移动。以下是帮助理解我的意思的图片:

在北偏东 14 度旋转的坦克图片未向上平移:

在北偏东 14 度旋转的坦克图片向上翻译:

说明:当我用键“A”和“D”旋转坦克的 body 时,不会有 x 或 y 转换。当我按下“W”或“S”键时,坦克向前或向后移动(向前或向后移动的方向取决于坦克 body 所在的角度),然后将有 x 和 y 翻译

发生这种情况是因为我在 x 方向上移动的值比 double 值太小,并且当转换为 int 时变成 0 从而导致没有x 变化。 (我必须转换为 int,因为 JScrollBar.setValue() 只接受整数)。这是我的代码,可以更好地解释这种情况:

int bodyAngle = 0; //the angle of the tank's body (it will face north as inital direction)
int d_angle = 2; //the change in angle when I click the rotate (see below)

//when I press the "D" key, the tank's body will rotate to the right by d_angle (and will keep rotating until I release "D")
case KeyEvent.VK_D:
    bodyAngle += D_ANGLE;
    ROTATE_TANK_BODY = ImageTool.rotateImage(TANK_BODY, bodyAngle, "body", 0);
    break;

//When the tank's angle is rotated and I press the forward key ("W"), there needs to be some math to calculate the correct x and y translations
case KeyEvent.VK_W:
    moveX = (int) Math.round(Math.sin(Math.toRadians(bodyAngle)));
    moveY = (int) Math.round(Math.cos(Math.toRadians(bodyAngle)));
    vScrollBar.setValue(vScrollBar.getValue() - moveY); //set new scrollbar values
    hScrollBar.setValue(hScrollBar.getValue() + moveX);
    break;

我的问题是,如何提高滚动条位置变化的准确性?准确性的损失显然是由于将我预测的 x 转换为整数,但我不太确定如何解决它。

您应该直接使用图形和翻译图像,而不是尝试使用滚动条,但是,问题是滚动条的范围通常为 0-100。如果您想要更精确的滚动条,则只需更改范围,但请注意,对于 small/fine 调整,它们实际上不能 shown/rendered 在屏幕上显示,因为像素数量有限,因此可能看起来好像什么都没有改变,直到滚动条移动得足够远,使图像移动一个像素。

增加滚动精度的例子:

//If you created the scroll bars yourself then you can set the range as follows:
javax.swing.JScrollBar myBar = new JScrollBar(HORIZONTAL, startValue, extent, minValue, maxValue);

//Or to edit a scroll bars inside an existing jScrollPane then you can change the max value:
yourScrollPane.getHorizontalScrollBar().setMaximum(maxValue);

如果您希望精确到小数点后半位,则滚动条范围需要是 map/image 大小的两倍。如果你想精确到小数点后一位,那么你的滚动条范围需要是地图大小的 10 倍:

//Map size in pixels, for example 400x400
int mapSize = 400;
//Scale factor of 10 for 0.1 decimal place precision, or scale factor of 2 for 0.5 precision
int scaleFactor = 10;
//Scroll bars with 1 decimal place precision (400 x 10 = 4000)
vScrollBar.setMaximum(mapSize * scaleFactor);
hScrollBar.setMaximum(mapSize * scaleFactor);

//Then to scroll to 200.1,200.5 you can use (Note everything has a scale of 10 so 200 needs to be 2000)
vScrollBar.setValue((int)200.1 * scaleFactor);
hScrollBar.setValue((int)200.5 * scaleFactor);

再次强调,我不推荐这个解决方案,它可能不会改变任何东西,因为小的增量不会显示在屏幕上或者它可能会显得卡顿。