0

I'm making a 2D card game. In it I have a custom font uses drawString from the Graphics library to draw it in with custom color and size. Problem is that this seems incredibly unoptimized. I can't seem to find out why. With 5 cards on screen, each one using this method 4 times each, I got from 3,800 fps down to 350 fps. Here's the way I draw text:

public static void drawString(Graphics g, String text, int xPos, int yPos, boolean center, Color c, Font font) {
    g.setColor(c);
    g.setFont(font);
    int x = xPos;
    int y = yPos;

    if (center) {
        FontMetrics fm = g.getFontMetrics(font);
        x = xPos - fm.stringWidth(text) / 2;
        y = (yPos - fm.getHeight() / 2) + fm.getAscent();
    }
    g.drawString(text, x, y);
} 
  • Perhaps you should consider caching the result (to an image) and re-use the image when the parameters match - it's possible that rendering the font itself is slowing it down - but I'm only going on guess work and previous experience – MadProgrammer Jul 03 '20 at 01:19
  • Would you mind elaborating on your solution? I'm not entirely sure what you mean. I'm a bit of a noob – GooseWithDaGibus Jul 03 '20 at 01:21
  • So, rather then trying to draw the string on every frame, you draw it once, to a backing buffer/image and when needed, you return that instead, only creating a new image as needed - then, you would render the image, which is faster, to your graphics context – MadProgrammer Jul 03 '20 at 01:29
  • That's what I thought you meant, thanks for the help. I'll get started working in that! – GooseWithDaGibus Jul 03 '20 at 01:31

1 Answers1

0

After a bit of googling here's how I did it. This image is created when a Card UI element is added to the screen. Then is used to just overlay on the card's image. The x and y scaling is done in a separate class. The code mentioned in the original comment is in the Text class, along with the other drawRestrictedText method:

public BufferedImage createTextOverlayImage(){

    BufferedImage overlay = new BufferedImage(imageWidth, height, BufferedImage.TYPE_INT_ARGB);
    Graphics g = overlay.createGraphics();

    Text.drawString(g, name,
            (imageWidth / 2) + wd.getScaleX(18),
            wd.getScaleY(21),
            true,
            Color.black, Assets.font20Bold);

    Text.drawString(g, cost + "",
            wd.getScaleX(28),
            wd.getScaleY(28),
            true,
            Color.blue, Assets.font28Bold);

    Text.drawRestrictedString(g, keyWords,
            wd.getScaleX(20),
            wd.getScaleY(162),
            imageWidth,
            Color.magenta,
            Assets.font18Bold);

    Text.drawRestrictedString(g, description,
             wd.getScaleX(20),
             wd.getScaleY(185),
            imageWidth - wd.getScaleX(35),
            Color.black,
            Assets.font18);

    return overlay;
} 

Here's the site I used for reference: http://www.java2s.com/Tutorials/Java/Graphics_How_to/Text/Write_text_onto_image.htm