跳转到主要内容 链接 搜索 菜单 展开 文档 (外部链接)

常见 UI 问题 - 项目 3: BYOW

不可见文本

让文本显示在屏幕上可能有点棘手。需要正确处理以下几点:

  • 字体颜色需要设置为可见的颜色(例如白色)
  • 文本的位置需要在边界内
  • 在绘制文本后需要调用 StdDraw.show() 以使其显示在屏幕上
  • 需要确保文本在绘制后不会被立即覆盖或清除(例如, TERenderer.renderTiles 会清除整个屏幕)

以下是正确绘制文本的示例代码:

TERenderer ter = new TERenderer();
ter.initialize(80, 40, 0, 0);
StdDraw.setPenColor(Color.WHITE);
StdDraw.text(40, 30, "I like cheese");
StdDraw.show();

奇怪的图块

问题

一个常见的故障是,在实现 UI 的其他部分后,图块字符会突然出现异常行为。 这里有一个演示此问题的程序 ;如果你想跟着操作,可以将其粘贴到你的 core 文件夹中。

你会注意到花朵不再看起来像花朵了。这是因为字体大小太大了,所以每个图块的字符溢出到了其他图块中。

解决方案

问题是图块使用的字体太大,所以我们需要使用一种重置字体大小的方法。在你的 TERenderer 类中调用 resetFont 方法:

/** Sets the font to the correct font for drawing tiles */
public void resetFont() {
    Font font = new Font("Monaco", Font.BOLD, TILE_SIZE - 2);
    StdDraw.setFont(font);
}

然后,在绘制图块之前调用该方法:

修改前 修改后
// render frame
ter.renderFrame(tiles);
// render frame
ter.resetFont();
ter.renderFrame(tiles);

现在,当你运行 FlowerWorld 时,图块应该能正确绘制了。

闪烁的 UI

问题

一个常见的故障是 UI 闪烁。 这里有一个演示此问题的程序 ;如果你想跟着操作,可以将其粘贴到你的 core 文件夹中。

你会注意到文本"HUD goes here"应该会闪烁。原因是每帧有多个 StdDraw.show() 调用——一个在 renderFrame 调用内部,一个在第 31 行。这意味着实际上每轮循环在屏幕上绘制了两帧——一帧没有文本,一帧有文本。你看到哪一帧是随机的,这就是 UI 在两者之间闪烁的原因。

解决方案

问题是 renderFrame 内部有一个额外的 StdDraw.show() 调用, 所以我们要创建一个没有这个调用的方法版本。请使用 TERenderer 类中的 drawTiles 方法:

    /**
     * Like renderFrame, but does not clear the screen or show the tiles
     */
    public void drawTiles(TETile[][] world) {
        for (int x = 0; x < world.length; x += 1) {
            for (int y = 0; y < world[x].length; y += 1) {
                world[x][y].draw(x + xOffset, y + yOffset);
            }
        }
    }

在你的主游戏循环中将 renderFrame 调用替换为:

修改前 修改后
// main game loop
while (true) {
    ter.renderFrame(tiles);
    ...
}
// main game loop
while (true) {
    StdDraw.clear(Color.BLACK);
    ter.drawTiles(tiles);
    ...
}

现在,当你运行 WaterWorld 时,文本应该不再闪烁了。