常见 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);
}
然后,在绘制图块之前调用该方法:
| 修改前 | 修改后 |
|---|---|
|
|
现在,当你运行
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
调用替换为:
| 修改前 | 修改后 |
|---|---|
|
|
现在,当你运行
WaterWorld
时,文本应该不再闪烁了。