【问题标题】:Is there a way to programmatically set a specific terminal font upon application start up?有没有办法在应用程序启动时以编程方式设置特定的终端字体?
【发布时间】:2019-01-11 14:49:54
【问题描述】:

我正在开发一个用 Java 编写的基于文本的冒险游戏,我想知道是否有办法强制使用某种终端字体,以确保某些字符以一致的方式间隔以“绘制”事物比如关卡地图和 UI 元素。

从这里对 SO 的一些研究中,我看到 System.out 无法使用指定的字体,它实际上取决于最终用户的控制台/终端字体设置是什么。

我已经实现了一个 bash 脚本来获取用户终端在启动期间的当前大小的列数和行数,并将这些值写入我的 Java 代码然后读取的文件。

有没有办法通过 Java 或游戏启动脚本在游戏加载之前让最终用户的终端使用某种字体?有没有人用他们自己的基于文本的游戏处理过这种问题?是否最好只告知最终用户某种字体(等宽字体、无衬线字体)更适合获得最佳游戏体验?

【问题讨论】:

  • 您需要在启动您的应用程序的终端上显示文本吗?大多数文字冒险都不会这样做。相反,他们创建了自己的显示窗口,完全在他们的控制之下,在上面显示游戏文本。这也支持完全没有控制终端的情况,例如从 GUI 启动游戏的情况。
  • 我想知道...使用exec 并传入游戏脚本,以便它使用自己的终端实例;我发现用户选择的字体仍然是默认使用的字体。我已经在野外测试了其他一些基于文本的冒险,它们也以用户选择的字体显示,所以我认为最好用等宽字体设计游戏和通知可能玩的人暂时切换他们的自定义字体。
  • 如果窗口系统是基于 X 的,您可以启动一个终端并传入配置参数来强制启动的终端具有您想要的字体。

标签: java linux terminal game-development


【解决方案1】:

这其实很简单。您应该做的是使用 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;
    }
}

【讨论】:

  • 您当然需要放弃使用 Scanner 并使用 actionPerformed 方法来获取您的输入。如果您需要这方面的帮助,我很乐意提供帮助。
  • 我喜欢这个建议,我没有考虑过利用 Java 的一些实际 GUI 功能。谢谢:)
猜你喜欢
  • 2018-07-12
  • 2010-09-14
  • 1970-01-01
  • 2021-08-28
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多