【问题标题】:Java JScrollBar set value with doubleJava JScrollBar 用双精度设置值
【发布时间】:2021-03-25 23:20:22
【问题描述】:

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

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

坦克图片以北向东旋转 14 度向上平移:

澄清:当我用“A”和“D”键旋转坦克的身体时,不会有 x 或 y 平移。当我按下“W”或“S”键,使坦克向前或向后移动(它向前或向后移动的方向取决于坦克身体所处的角度),然后会有 x和你的翻译

发生这种情况是因为我在 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 和 1 之间, - 不适用于双精度值。该值必须是介于 0 到滚动条最大值之间的 int。发布您的minimal reproducible example,说明您认为需要使用双精度值的问题。
  • @camickr 我修改了我的帖子,现在可能更清楚了。
  • 不,不清楚。正如您在上一篇文章中所建议的,旋转是围绕中心点进行的。因此,如果您的中心点是 (200, 200) 并且您将图像从 13 度旋转到 14 度,那么中心点仍然是 (200, 200)。如果您随后使用键沿 x 方向移动,则将中心点更改为 (201, 200)。我不知道双值在哪里进入等式。就像你的最后一个问题和这个问题我还在等待minimal reproducible example
  • @camickr 我明白你在说什么,但是坦克是静止的——它通过移动 jscrollbars 来移动(实际上是在 tilemap 上“移动”坦克),这就是为什么我需要改变jscrollbars 值放在首位。我会看到最小的可重现示例,但我希望这个评论能解释这种情况。
  • 因此,当您旋转水箱时,滚动条不会发生变化,只会在面板上绘制图像的位置发生变化。然后,当您沿 x/y 方向移动时,您会移动滚动条。

标签: java swing double setvalue jscrollbar


【解决方案1】:

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

提高滚动精度的例子:

//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);

如果您希望精确到小数点后,则滚动条范围需要是地图/图像大小的两倍。如果您希望精确到小数点后 1 位,则滚动条范围需要是地图大小的 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);

同样,我不推荐这种解决方案,它可能不会改变任何东西,因为屏幕上不会显示小的增量,或者它可能会出现断断续续的情况。

【讨论】:

  • 所以我在考虑翻译,我同意也许我需要从滚动条切换。但是您的带有滚动条的解决方案似乎非常好,我会先试一试,看看它是否符合我的喜好。感谢您花时间回答。
猜你喜欢
  • 2013-01-28
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
相关资源
最近更新 更多