gpt4 book ai didi

java - 如何使用 Slick2D 渲染最后一个字符字形的一部分

转载 作者:行者123 更新时间:2023-11-30 07:02:17 24 4
gpt4 key购买 nike

我目前正在使用 Slick 在游戏中呈现自定义聊天。

我想要做的是,我希望能够为聊天创建自定义的“淡入淡出”效果,顺利从右向左逐渐消失。我不太擅长用文字解释事物,所以我将展示一个我想要的例子。

例子:

我想渲染文本 bernhardkiv: hello world! ,运行我的常规字体渲染器,结果如下:

enter image description here

而我希望能够做到的,就是将文字平滑的截断,如下;

enter image description here

我不知道该怎么做!我相信使用 glScissoring 可以做到这一点,但我一直在尝试使用它,但似乎没有任何效果(根本没有任何 react ,一切都保持不变)。

我会感谢任何人的帮助,我基本上希望能够,而不是在 x,y 处渲染,我希望能够在 x,y 处渲染,宽度为 string_width - smooth_cut,以便能够产生一点褪色效果。

最佳答案

免责声明:

  • 这对我来说是一个新领域,但由于似乎没有其他人在回答,我会尝试一下,因为这个问题对我来说似乎有点有趣。我还没有彻底测试这些代码修改,所以可能存在我不知道的错误/副作用。使用风险自负。 :-)
  • org.newdawn.slick.Font Slick2D 库中的实现类(和支持类)似乎不是扩展友好的(私有(private)成员和方法)。据我所知,为了达到预期的效果,需要对其中一些内部 Slick2D 类进行更改。 (替代方法是复制整个类和包。)据我从提问者的评论中了解到,Slick2D 源代码包含在提问者的项目中,因此在这种情况下对内部 Slick2D 类进行更改应该是可行的。
  • 可以说,出于某种原因,上述类不是对扩展友好的,并且可能有更好的方法来进行必要的更改以使其可扩展。如果有一个实际的项目和更多的时间,我什至可能会以不同的方式去做。 然而,这个答案的目的是向提问者展示我如何通过对内部 Slick2D 类的最小代码更改来达到预期效果的本质。 提问者可以自行决定如何将这些更改应用于他/她的项目的细节。

  • 此代码使用 Slick build 237。

    您可以在 github repo 查看完整的代码更改.下面我只展示了与实现所需淡入淡出效果最相关的代码更改。

    将每个字符想象成一个 GL_QUAD 中的四个角,每个角都有一个 RGBA 值(如 here 所述,这张图片来自哪里):
     (x,x,x,1)       (x,x,x,0)
    -----------------
    | |
    | |
    | |
    | |
    | |
    | |
    -----------------
    (x,x,x,1) (x,x,x,0)

    我们正在做的是保持左上角和左下角的颜色不变,并将右上角和右下角的颜色更改为 alpha 为 0(透明)。 OpenGL会逐渐为我们淡化透明度。为此,我们扩展 org.newdawn.slick.Image创建 FadableImage使用以下方法(与 ImagedrawEmbedded 方法非常相似,但不会覆盖它):
    public class FadableImage extends Image {

    //.....

    public void drawEmbeddedFaded(float x,float y,float width,float height, Color color, float fadePercentWidth) {
    init();

    //if percent width is set to an invalid amount, default it to 1.
    if(fadePercentWidth < 0.0f || fadePercentWidth > 1.0f)
    fadePercentWidth = 1.0f;

    if (corners == null) {
    GL.glTexCoord2f(textureOffsetX, textureOffsetY);
    GL.glVertex3f(x, y, 0);
    GL.glTexCoord2f(textureOffsetX, textureOffsetY + textureHeight);
    GL.glVertex3f(x, y + height, 0);

    //set the color of x2 and y2 of the quad to 0 alpha
    GL.glColor4f(color.r, color.g, color.b, 0.0f);
    GL.glTexCoord2f(textureOffsetX + textureWidth*fadePercentWidth, textureOffsetY
    + textureHeight);
    GL.glVertex3f(x + width*fadePercentWidth, y + height, 0);
    GL.glTexCoord2f(textureOffsetX + textureWidth*fadePercentWidth, textureOffsetY);
    GL.glVertex3f(x + width*fadePercentWidth, y, 0);
    //reset the color
    GL.glColor4f(color.r, color.g, color.b, color.a);
    } else {
    corners[TOP_LEFT].bind();
    GL.glTexCoord2f(textureOffsetX, textureOffsetY);
    GL.glVertex3f(x, y, 0);
    corners[BOTTOM_LEFT].bind();
    GL.glTexCoord2f(textureOffsetX, textureOffsetY + textureHeight);
    GL.glVertex3f(x, y + height, 0);
    //set the color of x2 and y2 of the quad to 0 alpha
    GL.glColor4f(color.r, color.g, color.b, 0.0f);
    //corners[BOTTOM_RIGHT].bind();
    GL.glTexCoord2f(textureOffsetX + textureWidth*fadePercentWidth, textureOffsetY
    + textureHeight);
    GL.glVertex3f(x + width*fadePercentWidth, y + height, 0);
    //corners[TOP_RIGHT].bind();
    GL.glTexCoord2f(textureOffsetX + textureWidth*fadePercentWidth, textureOffsetY);
    GL.glVertex3f(x + width*fadePercentWidth, y, 0);
    //reset the color
    GL.glColor4f(color.r, color.g, color.b, color.a);
    }
    }

    }

    你可以看到 diff我将要描述的内容。

    为了使用 FadableImage ,我们还需要扩展 org.newdawn.slick.font.GlyphPage创建 FadableGlyphPage .支持 FadableGlyphPage我们需要修改 org.newdawn.slick.font.GlyphPage的构造函数并添加一个新的。

    然后我们需要修改 org.newdawn.slick.UnicodeFont使用我们的 FadableGlyphPageUnicodeFont加载 loadGlyphs 中的字形.

    我们改 UnicodeFontdrawDisplayList(...)方法来调用我们的 FadableImage的特辑 drawEmbeddedFaded(...)给定字符串的指定结束索引处的字符的方法。我们还必须进行修改,以便 DisplayList缓存将被正确处理。

    我们在 UnicodeFont 中添加了一个方便的方法绘制一个字符串,其中 endIndex-1 处的字符褪色并绘制到由 fadePercentWidth 指定的宽度百分比:
    public void drawString(float x, float y, String text, int endIndex, float fadePercentWidth) {
    drawDisplayList(x, y, text, Color.white, 0, endIndex, fadePercentWidth);
    }

    所以这个想法是最后呈现的字符将是 endIndex-1 处的字符。渐变宽度百分比是将要绘制的包含 endIndex-1 字符的四边形的宽度百分比。因此,您可以使用该参数来微调您想要的效果( 0.0f1.0f )。渐变宽度百分比设置为 0.5f ,将绘制四边形总宽度的 50%。并且淡入淡出将达到 50% 的宽度:
     (x,x,x,1)       (x,x,x,0)

    ------------|------------
    | | |
    | drawn | not |
    | | drawn |
    | | |
    | | |
    | | |
    ------------|------------

    (x,x,x,1) (x,x,x,0)

    现在让我们用这段代码来测试它:
    import java.awt.Font;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    import org.newdawn.slick.AppGameContainer;
    import org.newdawn.slick.BasicGame;
    import org.newdawn.slick.Color;
    import org.newdawn.slick.GameContainer;
    import org.newdawn.slick.Graphics;
    import org.newdawn.slick.SlickException;
    import org.newdawn.slick.UnicodeFont;
    import org.newdawn.slick.font.effects.ColorEffect;

    public class TextFadeTest extends BasicGame {

    private final int Y_OFFSET = 50;
    private final org.newdawn.slick.Color bgColor = new org.newdawn.slick.Color(126, 166, 240);

    private UnicodeFont unicodeFont;

    public TextFadeTest(String gamename) {
    super(gamename);
    }

    @Override
    public void init(GameContainer gc) throws SlickException {
    gc.setShowFPS(false);
    gc.getGraphics().setBackground(bgColor);

    Font awtFont = new Font(Font.SERIF, Font.PLAIN, 36);
    unicodeFont = new UnicodeFont(awtFont);
    unicodeFont.getEffects().add(new ColorEffect(java.awt.Color.WHITE));
    unicodeFont.addAsciiGlyphs();
    unicodeFont.loadGlyphs();
    }

    @Override
    public void update(GameContainer gc, int i) throws SlickException {}

    @Override
    public void render(GameContainer gc, Graphics g) throws SlickException {

    String str = "bernhardkiv: hello world!";
    int y = 0;
    unicodeFont.drawString(10, y, str);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, Color.white, 0, 22);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0.10f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0.25f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0.50f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0.75f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 0.90f);
    unicodeFont.drawString(10, y+=Y_OFFSET, str, 22, 1.0f);

    }

    public static void main(String[] args) {
    try {
    AppGameContainer appgc;
    appgc = new AppGameContainer(new TextFadeTest("TextFadeTest"));
    appgc.setDisplayMode(640, 480, false);
    appgc.start();
    }
    catch(SlickException ex) {
    Logger.getLogger(TextFadeTest.class.getName()).log(Level.SEVERE, null, ex);
    }
    }

    }

    这给出了这个结果:

    result

    关于java - 如何使用 Slick2D 渲染最后一个字符字形的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29200102/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com