【问题标题】:Recalculate X and Y Coordinates From New Screensize从新屏幕尺寸重新计算 X 和 Y 坐标
【发布时间】:2016-09-06 04:33:35
【问题描述】:

我正在尝试显示我拥有的数组中的图块,以便它们在绘制在一起时始终填充屏幕的大小。我暂时忽略纵横比。

我的代码是这样工作的。我有传递给tileset(用于管理tile对象数组的类)的tile对象,然后我遍历tileset数组,返回每个tile对象id并根据所述id渲染我的tileset图像的子图像。

这是我的 mapUpdate 方法,每个 JFrame 调整大小事件都会调用它:

public synchronized void mapUpdate(Screen screen) {
    factorX = (float)(screen.getWidth() / scW);
    factorY = (float)(screen.getHeight() / scH);

    for (int i = 0; i < tileset.getRows(); i++) {
        for (int j = 0; j < tileset.getCols(); j++) {
            int x = tileset.getTile(i, j).getX();
            int y = tileset.getTile(i, j).getY();
            tileset.getTile(i, j).setX((int)(x * factorX));
            tileset.getTile(i, j).setY((int)(y * factorY));
        }
    }

    mapTiles.clear();

    for (int i = 0; i * 70 < mapImage.getWidth(); i++) {
        mapTiles.add(mapImage.getSubimage(70 * i, 0, 70, 70).getScaledInstance(screen.getWidth() / 10, screen.getHeight() / 10, Image.SCALE_SMOOTH));
    }
}

mapTiles 是图像的 ArrayList,在每次调整大小事件时,它都会重置数组列表,将我的子图像缩放到 1/10 的宽度和高度,然后重新添加新大小的图像以供我拉出进行渲染(tileset图像只有 3 个图块,原始尺寸为 70x70)。

如果你好奇的话,这里是 componentResized 方法:

public void componentResized(ComponentEvent e) {
    canvas.setSize(app.getContentPane().getWidth(), app.getContentPane().getHeight());
    if (level1 != null) {
        level1.mapUpdate(this);
    }
}

正如您在我的 mapUpdate 方法中看到的那样,我尝试获取一个浮点数以将每个当前 x 和 y 值乘以接收新的正确值(它将对整数进行四舍五入),但这根本不起作用。

是否有任何解决方案可以轻松地重新计算我的 X 和 Y 坐标以便正确绘制图块?

【问题讨论】:

  • 除非您使用null 布局,否则不需要设置组件的大小,假设canvas 是一个组件
  • (float)(screen.getWidth() / scW) 更改为screen.getWidth() / (float)scW,这将删除当前发生的整数截断
  • 另外要注意,componentResized 可以快速连续调用多次,你真的不想在里面做任何耗时的事情,因为它会导致延迟UI的渲染过程,最好使任何缓存无效并在下次更新时重建它们
  • 像素不能是浮点值,这就是为什么需要截断。我知道 componentResized 可以很快被调用,这是我试图解决问题的一部分。
  • 此外,即使将 factorX 和 factorY 更改为浮点数,算法本身或一般截断也会导致渲染问题。瓷砖并没有像预期的那样单独保持,而是彼此分开。

标签: java swing resize awt graphics2d


【解决方案1】:

你的 factorX 不应该是一个浮点数。它应该是一个整数。如果你使用浮点数,你会得到四舍五入,所以有时你会因为四舍五入而在瓷砖之间有像素间隙。如果您只使用 int ,那么您不必担心这一点。那么位置就是因子 * for 循环的索引值。

另一方面,最简单的解决方案是使用带有 GridLayout 的 JPanel。然后你可以添加一个带有图像图标的 JLabel。 GridLayout 将平均调整每个组件的大小。

然后您甚至可以使用Stretch Icon,图像将随着框架大小的调整而动态调整。

【讨论】:

  • 你在开玩笑吧。那是一回事..?我应该知道这个 GridLayout 哈哈。谢谢...
  • @user3059686,有关 GridLayout 和其他布局管理器的信息,请参阅 Layout Manager 上的 Swing 教程部分。
  • 啊,我才意识到。我不相信 GridLayout 解决方案会起作用,因为这个游戏将是一个滚动平台游戏,因此图块需要是可滚动的(这意味着所显示的网格不应该总是相同的尺寸)。
  • @user3059686,然后您可以查看GridBagLayout。每个单元格的大小可以不同。
【解决方案2】:

@MadProgrammer 提供的解决方案 - 解决方案是简单地计算每个图块的新 X 和 Y“原点”。我仍然需要根据新计算的原点来调整已移动的图块的位置,但此解决方案适用于不移动的图块(再次,只需重新计算 X 和 Y 原点位置)。

public synchronized void mapUpdate(Screen screen) {
    int originX = screen.getWidth() / 10;
    int originY = screen.getHeight() / 10;

    for (int i = 0; i < tileset.getRows(); i++) {
        for (int j = 0; j < tileset.getCols(); j++) {
            tileset.getTile(i, j).setX((originX * j));
            tileset.getTile(i, j).setY((originY * i));
        }
    }

    mapTiles.clear();

    for (int i = 0; i * 70 < mapImage.getWidth(); i++) {
        mapTiles.add(mapImage.getSubimage(70 * i, 0, 70, 70).getScaledInstance(screen.getWidth() / 10, screen.getHeight() / 10, Image.SCALE_SMOOTH));
    }
}

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2015-12-21
    • 2012-04-10
    • 2019-11-24
    • 2011-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 2013-01-05
    相关资源
    最近更新 更多