【问题标题】:LibGDX resize window - Scaling fontLibGDX 调整窗口大小 - 缩放字体
【发布时间】:2014-10-13 07:43:12
【问题描述】:

我正在编写简单的“Hello World”风格的程序,在屏幕上写下当前的命名日。 我想确保在调整窗口大小后,该文本也可以读取并正确绘制。

在我的create方法中,我尝试使用这段代码(根据这篇文章:https://github.com/libgdx/libgdx/wiki/Viewports

public void create () {

        //if(_isLandscape)
        //    Gdx.graphics.setDisplayMode(1920, 1080, false);

        if(_isLandscape)
            Gdx.graphics.setDisplayMode(960, 540, false);

        camera = new PerspectiveCamera();
        //viewport = new FillViewport(960, 540, camera); - I have also tried to use this
        viewport = new ScreenViewport(camera);
....

在 resize(int, int) 方法中,我有这个代码:

public void resize(int width , int height){
        try {
           viewport.update(width, height);
            System.out.println(width + " " + height);
            if (height > width) {
                _isLandscape = false;
                System.out.println("Portrait");
            } else {
                _isLandscape = true;
                System.out.println("Landscape");
            }
        }catch(Exception ex){
        }
    }

但调整大小后结果仍然是拉伸或不可读的文本。

拜托,我想实现,文本将被缩放,如果窗口很小,文本仍然是相同的,但某些部分将在边框“后面”。如果窗口很大(例如全屏),文本将位于同一位置而不是拉伸。

这是我现在拥有的完整代码:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.loaders.FileHandleResolver;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.badlogic.gdx.utils.viewport.*;

import com.badlogic.gdx.graphics.OrthographicCamera;

import java.io.File;
import java.util.List;

//import com.badlogic.gdx.tools.imagepacker.TexturePacker2;
//import com.badlogic.gdx.tools.texturepacker.TexturePacker;

/**
 * Created by Martin on 30.9.2014.
 */
public class NameDayExampleApp extends HostedGame{
    private Viewport viewport;
    private Camera camera;
    private OrthographicCamera _ortocamera;

    private SpriteBatch _spriteBatch;
    private Texture background;
    private Texture backgroundLandscape;
    private boolean _isLandscape;

    private String name = "";

    private TextureAtlas textureAtlas;

    private static final String TAG = "NameDayExampleApp";
    private static final int VERSION = 1;
    private static final int FONT_SIZE = 30;
    private static final float CLEAR_COLOR = 0.1f;

    private static final int MAX_FONT_SIZE = 40;
    private static final int MIN_FONT_SIZE = 8;

    private IServiceProvider _serviceProvider;
    private ILog _log;
    private BitmapFont _font;
    String _language;

    private int currentFontSize;

    private int currentHeight;
    private int currentWidth;

    boolean isDebugged = true;

    @Override
    public void initialize(IServiceProvider serviceProvider, List<SocialFeedDefinition> feeds, boolean isLandscape, String language)
    {
        _serviceProvider = serviceProvider;
        _log = serviceProvider.getLog().getSubLog(TAG);


        _isLandscape = isLandscape;
        _language = language;

        _serviceProvider.getAppStatusListener().onStateChanged(AppState.Ready);

    }

    @Override
    public void create () {

        _serviceProvider.getLog().log(LogLevel.Info, "[NameDay]: Start creating screen");


        if(_isLandscape)
            Gdx.graphics.setDisplayMode(Gdx.graphics.getHeight(), Gdx.graphics.getWidth(), false);//Gdx.graphics.setDisplayMode(960, 540, false);

        currentHeight = Gdx.graphics.getHeight();
        currentWidth  = Gdx.graphics.getWidth();


       // _ortocamera = new OrthographicCamera(currentWidth, currentHeight);
        //viewport = new ExtendViewport(currentWidth, currentHeight, _ortocamera);
        viewport = new StretchViewport(currentWidth, currentHeight);
        currentFontSize = FONT_SIZE;

        try
        {
            _spriteBatch = new SpriteBatch();


            background = new Texture(_serviceProvider.getAssetHandleResolver().resolve("nameday-portrait.jpg").file().getName());
            backgroundLandscape = new Texture(_serviceProvider.getAssetHandleResolver().resolve("nameday-landscape.jpg").file().getName());

            //FreeTypeFontGenerator generator = new FreeTypeFontGenerator(new FileHandle("fonts/DroidSans_Bold.ttf"));
            // _serviceProvider.getFontGenerator().generateExistenceFont(20,  FontType.NORMAL);

            _font = _serviceProvider.getFontGenerator().generateDefaultFont(currentFontSize,  FontType.NORMAL); //generator.generateFont(40);
            _font.setColor(0,0,0,1);
            //generator.dispose();
        }
        catch(GdxRuntimeException e)
        {
            _log.error("Exception on create: " + e);
            _serviceProvider.getAppStatusListener().onStateChanged(AppState.Error);
        }
    }

    @Override
    public void render () {

        try
        {

            Gdx.gl.glClearColor(1, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

            //background draw
            if(isDebugged) {
                _log.log(LogLevel.Info, "currentWidth: " + currentWidth + " currentHeight: " + currentHeight);
                _log.log(LogLevel.Info, "Window width: " + Gdx.graphics.getWidth() + " Window height: " + Gdx.graphics.getHeight());
                _log.log(LogLevel.Info, "Background width: " + background.getWidth() + " Background height: " + background.getHeight());
                isDebugged = false;
            }


            if(!_isLandscape) {
                _spriteBatch.begin();
                //_spriteBatch.draw(background, 0, 0, currentWidth, currentHeight);
                _spriteBatch.draw(background,0,0);
                _spriteBatch.end();
            }else{
                _spriteBatch.begin();
                //_spriteBatch.draw(backgroundLandscape, 0, 0, currentWidth, currentHeight);
                _spriteBatch.draw(backgroundLandscape, 0, 0);
                _spriteBatch.end();
            }


            //content draw
            _spriteBatch.begin();

            NameDaySAX nameDaySAX = new NameDaySAX();

            //Choose XML according to language
            FileHandle _fileHandle = null;
            File _file = null;
            _fileHandle = _serviceProvider.getAssetHandleResolver().resolve("namesday_" + _language + ".xml");
            _file = _fileHandle.file();
            if(_file.exists()){
              name = nameDaySAX.getCurrentName(_file);
            }else {
                _fileHandle = _serviceProvider.getAssetHandleResolver().resolve("namesday.xml");
                _file = _fileHandle.file();
                name = nameDaySAX.getCurrentName(_file);
            }

            if(!_isLandscape) {
                BitmapFont.TextBounds bounds = _font.getBounds(_serviceProvider.getLocalizer().get("Today celebrates"));//_font.getBounds("Happy Name Day");
                _font.draw(_spriteBatch, _serviceProvider.getLocalizer().get("Today celebrates"), (Gdx.graphics.getWidth()-bounds.width) / 6.0f, Gdx.graphics.getHeight() - 35);
                bounds = _font.getBounds(_serviceProvider.getLocalizer().get("nameday") + " " + name);
                _font.draw(_spriteBatch, _serviceProvider.getLocalizer().get("nameday") + " " + name, (Gdx.graphics.getWidth()-bounds.width) / 5.0f, Gdx.graphics.getHeight() - 70);
            }else{
                BitmapFont.TextBounds bounds = _font.getBounds(_serviceProvider.getLocalizer().get("Happy Name Day"));
                _font.draw(_spriteBatch, _serviceProvider.getLocalizer().get("Today celebrates"), (Gdx.graphics.getWidth()-bounds.width) / 14.0f, Gdx.graphics.getHeight() / 1.7f);
                bounds = _font.getBounds(_serviceProvider.getLocalizer().get("nameday") + " " + name);
                _font.draw(_spriteBatch, _serviceProvider.getLocalizer().get("nameday") + " " + name, (Gdx.graphics.getWidth()-bounds.width) / 11.0f, Gdx.graphics.getHeight() / 2.0f);
            }
        }
        catch(RuntimeException e)
        {
            _log.error("Exception on render: " + e);
            _serviceProvider.getAppStatusListener().onStateChanged(AppState.Error);
        }
        finally {
            _spriteBatch.end();
        }
    }

    @Override
    public void resize(int width , int height){
        try {

            viewport.update(width, height);
            //_ortocamera.update();
            isDebugged = true;
            //Set Landscape flag
            if (height > width) {
                _isLandscape = false;
                _log.log(LogLevel.Info, "Portrait");
            } else {
                _isLandscape = true;
                _log.log(LogLevel.Info, "Landscape");
            }

            float scale = 1.0f, scale1, scale2;
            scale1 = (width * 1.0f) / (currentWidth * 1.0f);
            scale2 = (height * 1.0f) / (currentHeight * 1.0f);

            if(currentWidth<width || currentHeight<height){
                if(scale1>scale2){
                    scale = scale1;
                }else{
                    scale = scale2;
                }
            }

            if(currentWidth>width || currentHeight>height){
                if(scale1<scale2){
                    scale = scale1;
                }else{
                    scale = scale2;
                }
            }

            if(scale<0.9)
                scale=0.9f;
            if(scale>1.2){
                scale=1.2f;
            }

            //Font Scaling
            /*if(!_isLandscape) {
                scale = (width * 1.0f) / (currentWidth * 1.0f);
            }else {
                scale = (height * 1.0f) / (currentHeight * 1.0f);
            }*/

            currentWidth = width;
            currentHeight = height;

            _log.log(LogLevel.Info, "New width: " + width + " New height: " + height);
            _log.log(LogLevel.Info, "Scale: " + scale);

            float fontsize = currentFontSize;
            float fcurrentFontSize;
            _font.dispose();
            fcurrentFontSize = fontsize * scale;

            if(fcurrentFontSize > MAX_FONT_SIZE)
                fcurrentFontSize = MAX_FONT_SIZE;
            if(fcurrentFontSize < MIN_FONT_SIZE)
                fcurrentFontSize = MIN_FONT_SIZE;

            currentFontSize = (int)fcurrentFontSize;
            _font = _serviceProvider.getFontGenerator().generateDefaultFont(currentFontSize,  FontType.NORMAL);
            _font.setColor(0,0,0,1);

            _log.info("Fontsize: " + currentFontSize);
            _log.info(width + "x" + height);
            //End of font scaling


        }catch(Exception e){
            _log.error("Exception on resize: " + e);
            _serviceProvider.getAppStatusListener().onStateChanged(AppState.Error);
        }
    }

    public int getVersion()
    {
        return VERSION;
    }

    @Override
    public void dispose()
    {
        super.dispose();
        _font.dispose();
        background.dispose();
        backgroundLandscape.dispose();
    }
}

【问题讨论】:

  • 您可能应该使用 OrthographicCamera 而不是 PerspectiveCamera 作为文本。如果你需要背景是 3D 的,你可以有两个单独的相机,并且只使用正射相机来拍摄文本。
  • 请问您有一些示例代码,如何设置OrthographicCamera?
  • 使用 Viewport 类来处理您的 OrthographicCamera。阅读此处的文档以确定哪种类型的视口适合您的目的。 github.com/libgdx/libgdx/wiki/Viewports
  • 我还是有点迷茫,因为我尝试了所有的视口,调整屏幕大小后,字体仍然变形。
  • 我的代码:@Override public void create () { _serviceProvider.getLog().log(LogLevel.Info, "[NameDay]: 开始创建屏幕"); if(_isLandscape) Gdx.graphics.setDisplayMode(960, 540, false); OrthographicCamera(viewport.getScreenWidth(), viewport.getScreenHeight()); _ortocamera = new OrthographicCamera(960, 540); viewport = new FitViewport(960, 540, _ortocamera);

标签: java opengl-es fonts libgdx draw


【解决方案1】:

您也应该尝试使用 Libgdx 的 FreeType 扩展...

如果您想在游戏中绘制文本,通常使用 BitmapFont。但是,有一个缺点: BitmapFonts 依赖于图像,因此如果您想要不同的尺寸,则必须对其进行缩放,这可能看起来很难看。

您可以只保存游戏中所需的最大尺寸的 BitmapFont,而无需放大,只需缩小,对吗?的确如此,但这样的 BitmapFont 很容易在您的硬盘驱动器上占用两倍于相应 TrueType 字体 (.ttf) 的空间。现在想象一下,您必须在游戏中附带所有大的 BitmapFonts,并且您的游戏在 Android 设备上使用了十种不同的字体。

您的问题的解决方案是 gdx-freetype 扩展:

  • 只为您的游戏提供轻量级 .ttf 文件
  • 动态生成所需大小的 BitmapFont
  • 用户可能会将自己的字体放入您的游戏中

引用:https://github.com/libgdx/libgdx/wiki/Gdx-freetype

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 2014-11-30
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    相关资源
    最近更新 更多