我正在开发一款用Java编写的基于文本的冒险游戏,我想知道是否有一种方法可以强制使用特定的终端字体,以确保某些字符以一致的方式间隔开,从而"绘制"级别图和UI元素等内容。
从这里对SO的一些研究中,我发现System.out无法使用指定的字体,这实际上取决于最终用户的控制台/终端字体设置。
我已经实现了一个bash脚本来获取用户终端在启动期间当前大小的列和行数,并将这些值写入一个文件中,然后我的Java代码读取该文件。
有没有办法通过Java或游戏启动脚本,在游戏加载之前让最终用户的终端使用某种字体?有人用他们自己的基于文本的游戏处理过这种问题吗?最好只是通知最终用户,某种字体(单格、无衬线(更适合拥有最佳的游戏体验吗?
这实际上相当容易。您应该做的是使用JTextPane或JTextArea创建自己的控制台窗口,并创建重定向到该窗口的打印流。这里有一个例子:
import javax.swing.*;
import java.awt.*;
import java.io.OutputStream;
import java.io.PrintStream;
class Example {
public static void main(String[] args) {
ConsoleWindow printWindow = new ConsoleWindow().fixPosition();
PrintStream stream = new PrintStream(new CustomOutputStream(printWindow.jTextArea));
System.setOut(stream);
System.setErr(stream);
System.out.println("This is a custom console window.");
}
}
class CustomOutputStream extends OutputStream {
private JTextArea textArea;
CustomOutputStream(JTextArea textArea) {
this.textArea = textArea;
}
@Override
public void write(int b) {
textArea.append(String.valueOf((char) b));
textArea.setCaretPosition(textArea.getDocument().getLength());
}
}
class ConsoleWindow {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
JTextArea jTextArea = new JTextArea();
private JScrollPane jScrollPane = new JScrollPane(jTextArea);
ConsoleWindow() {
new Thread(() -> {
setupFrame();
setupPanels();
setupTextArea();
setupScrolling();
makeVisible();
}).start();
}
private void setupFrame() {
frame.setSize(854, 480);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setLayout(null);
}
private void setupPanels() {
panel.setSize(panel.getParent().getSize());
panel.setLayout(new GridLayout());
panel.add(jScrollPane);
}
private void setupTextArea() {
jTextArea.setFont(new Font("Ariel", Font.PLAIN, 20)); // TERMINAL FONT
jTextArea.setBackground(Color.BLACK); // TERMINAL COLOR
jTextArea.setForeground(Color.GREEN); // TEXT COLOR
}
private void setupScrolling() {
}
private void makeVisible() {
frame.setVisible(true);
}
ConsoleWindow fixPosition() {
jScrollPane.getHorizontalScrollBar().setValue(0);
jScrollPane.getVerticalScrollBar().setValue(0);
return this;
}
}