0

我目前正在尝试创建一个滚动文本方法,其中将采用String. 很快,它将开始从左到右绘制,并随着时间的推移进入新的行,因此它不会从屏幕上绘制出来。我正在使用FontMetrics来尝试实现我的目标。

RollingText.render(Graphics g, int x, int y)从我的主类中的渲染方法将参数传递给我。在我的render方法中,我开始设置Graphics字体和颜色,并抓取所有 . FontMetrics,然后我开始从FontMetrics. 同样,我进入一个用于将文本绘制到字符串的 for 循环。

public void render(Graphics g, int x, int y) {
    // text is the field that a grab the index of the string from
    // the index is the max part of the string I'm grabbing from,
    // increments using the update() method
    String str = text.substring(0, index);
    String[] words = str.split(" ");

    Font f = new Font(g.getFont().getName(), 0, 24);
    FontMetrics fmetrics = g.getFontMetrics(f);
    g.setColor(Color.white);
    g.setFont(f);

    int line = 1;
    int charsDrawn = 0;
    int wordsDrawn = 0;
    int charWidth = fmetrics.charWidth('a');
    int fontHeight = fmetrics.getHeight();
    for (int i = 0; i < words.length; i++) {
        int wordWidth = fmetrics.stringWidth(words[i]);
        if (wordWidth* wordsDrawn + charWidth * charsDrawn > game.getWidth()) {
            line++;
            charsDrawn = 0;
            wordsDrawn = 0;
        }

        g.drawString(words[i], x * charsDrawn + charWidth, y + fontHeight * line);

        charsDrawn += words[i].length();
        wordsDrawn += 1;
    }
}

目前,此时一切都会正常工作,但留下的问题是drawString方法中每个单词之间的空格被严重夸大了,如下所示:

滚动文本演示

该行:

g.drawString(words[i], x * charsDrawn + charWidth, y + fontHeight * line);

我目前遇到的唯一问题是找到正确的方法来计算 x 位置。目前,它的间距很大且动态取决于字长,我无法弄清楚如何让它看起来至少正常。我用我当前定义的整数尝试了不同的组合,等等。出现的问题包括不正确的间距、不恰当的定位和闪烁,以及一起运行的文本。

最后,我的问题是,将使用哪种算法来帮助我正确定位 x 坐标以使文本看起来正确?

4

1 回答 1

1

我不确定您为什么要尝试根据各种不同的变量计算 x/y 位置,而在我看来,简单地将FontMetrics#stringWidthor添加FontMetrics#getHeight到 x/y 值会更简单......

您似乎还FontMetrics#stringWidth根据“样本”宽度在使用和计算单个字符的宽度之间切换... wordsDrawn + charWidth,这使您的计算变得简单...令人困惑。您似乎也有优先级问题...

x * charsDrawn + charWidth应该x + (charsDrawn * charWidth)吗?

我实际上无法让您的示例代码重现您的结果,相反,我简化了它......

文本布局

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class RenderText {

    public static void main(String[] args) {
        new RenderText();
    }

    public RenderText() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private String text;
        private int index;

        public TestPane() {
            text = "A long time ago, in a galaxy far, far, away..."
                    + "A vast sea of stars serves as the backdrop for the main title. "
                    + "War drums echo through the heavens as a rollup slowly crawls "
                    + "into infinity."
                    + "     It is a period of civil war. Rebel spaceships, "
                    + "     striking from a hidden base, have won their first "
                    + "     victory against the evil Galactic Empire."
                    + "     During the battle, Rebel spies managed to steal "
                    + "     secret plans to the Empire's ultimate weapon, the "
                    + "     Death Star, an armored space station with enough "
                    + "     power to destroy an entire planet."
                    + "     Pursued by the Empire's sinister agents, Princess "
                    + "     Leia races home aboard her starship, custodian of "
                    + "     the stolen plans that can save her people and "
                    + "     restore freedom to the galaxy...";

            index = text.length() - 1;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            render(g, 0, 0);
            g2d.dispose();
        }

        public void render(Graphics g, int x, int y) {
            // text is the field that a grab the index of the string from
            // the index is the max part of the string I'm grabbing from,
            // increments using the update() method
            String str = text.substring(0, index);
            String[] words = str.split(" ");

            Font f = new Font(g.getFont().getName(), 0, 24);
            FontMetrics fmetrics = g.getFontMetrics(f);
//            g.setColor(Color.white);
            g.setFont(f);

            int fontHeight = fmetrics.getHeight();

            int spaceWidth = fmetrics.stringWidth(" ");

            int xPos = x;
            int yPos = y;
            for (String word : words) {
                int wordWidth = fmetrics.stringWidth(word);
                if (wordWidth + xPos > getWidth()) {
                    yPos += fontHeight;
                    xPos = x;
                }
                g.drawString(word, x + xPos, yPos + fmetrics.getAscent());
                xPos += wordWidth + spaceWidth;
            }
        }
    }

}

在您可以提供一个实际的可运行示例来演示您的问题之前,这是我能做的最好的......

于 2014-05-20T01:22:56.757 回答