Upgrade to Pro — share decks privately, control downloads, hide ads and more …

libGDX: Screens, Fonts , Preferences and Scene2d

libGDX: Screens, Fonts , Preferences and Scene2d

Jussi Pohjolainen

February 09, 2016
Tweet

More Decks by Jussi Pohjolainen

Other Decks in Technology

Transcript

  1. Screen and Game • Screen – Use to add different

    screens to your game – Screen is a interface and contains all the same methods than ApplicationListener. Also show() and hide() when screen is shown and hidden • Game – Game is an ApplicationListener that holds also methods for changing the screen: setScreen(Screen s)
  2. public class ScreensFontsPref extends Game { private MainMenuScreen mainmenu; //

    Common objects to all screens! private SpriteBatch batch; // Returns the SpriteBatch public SpriteBatch getBatch() { return batch; } @Override public void create () { batch = new SpriteBatch(); // Create MainMenuScreen mainmenu = new MainMenuScreen(this); // Set it visible setScreen(mainmenu); } @Override public void render () { super.render(); // Remember this, otherwise nothing is shown! } }
  3. public class GameScreen implements Screen { private ScreensFontsPref game; private

    SpriteBatch batch; private OrthographicCamera camera; public GameScreen(ScreensFontsPref g) { game = g; batch = game.getBatch(); camera = new OrthographicCamera(); camera.setToOrtho(false, 800, 480); } @Override public void render(float delta) { batch.setProjectionMatrix(camera.combined); Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); batch.begin(); // Do same drawing Gdx.app.log("GameScreen", "render"); batch.end(); if (Gdx.input.isTouched()) { game.setScreen(new LevelScreen(game)); } } ...
  4. About Fonts • libGDX does not support TrueType Fonts (TTF)

    – Rendering vector graphics is costly – Although you can use Freetype - extension • libGDX makes use of bitmap files (pngs) to render fonts • Use external tool to convert TTF to PNG! • Each glyph in the font has a corresponding TextureRegion • Default font Arial provided, other fonts you have to create! • If you use same font in different screens, create font once and share it with other screens.
  5. Tools for Creating own Fonts • Hiero (http://bit.ly/16EpREP) – Free

    and buggy? Java app • Glyphite (https://www.glyphite.com/) – Free web app • Littera (http://kvazars.com/littera/) – Free web app
  6. Littera Usage 1. Upload some .ttf font 2. Export format

    .txt 3. Add to assets (.png and .txt) to libGDX project
  7. Freetype Extension • Generate bitmap font from ttf in runtime

    @Override public void create () { generator = new FreeTypeFontGenerator(Gdx.files.internal("font.ttf")); FreeTypeFontParameter parameter = new FreeTypeFontParameter(); parameter.size = 12; parameter.borderColor = Color.BLACK; parameter.borderWidth = 3; font12 = generator.generateFont(parameter); // Generates BitmapFont }
  8. Fonts and Meters • Fonts don't work very well with

    meters • Create two cameras, one with a world with pixel resolution and on with a world of meter resolution • In render – use the resolution of the fontcamera – draw fonts – use the resolution of the "normal" camera – draw your game objects
  9. Persistent Storage • Simple preferences mechanism for storing and retrieving

    • Windows, Linux, OS X: xml-file in home dir – Windows: %UserProfile%/.prefs/My Preferences – Mac: ~/.prefs/My Preferences • On Android, the system's SharedPreferences class is used. – Preferences will survive app updates, but are deleted when the app is uninstalled.
  10. Usage Preferences prefs = Gdx.app.getPreferences("MyPreferences"); prefs.putString("name", "Donald Duck"); String name

    = prefs.getString("name", "No name stored"); prefs.putBoolean("soundOn", true); prefs.putInteger("highscore", 10); prefs.flush();
  11. Support for Multiple Languages • Create defaults properties file: –

    MyBundle.properties • Create other language files: – MyBundle_fi_FI.properties
  12. In Java Locale locale = new Locale("en", "UK"); Locale defaultLocale

    = Locale.getDefault(); I18NBundle myBundle = I18NBundle.createBundle(Gdx.files.internal("MyBundle"), locale); String title = myBundle.get("title"); String score = myBundle.format("score");
  13. Notes • If you don't specify locale, default locale is

    used • Charset is UTF-8 (without BOM) • See: – https://github.com/libgdx/libgdx/wiki/Internation alization-and-Localization
  14. Scene2D? • It’s optional, you don’t need it. But you

    may want to use it. • May be useful for "board games" • Higher level framework for creating games • Provides UI Toolkit also: Scene2d.ui • Tutorial – https://github.com/libgdx/libgdx/wiki/Scene2d
  15. Concepts • Stage – “Screens”, “Stages”, “Levels” – Camera watching

    the stage – Contains group of actors • Actors – “Sprites”
  16. Roughly the Idea in Code Stage gameStage = new Stage(new

    FitViewport(width, heigth), batch); // PlayerActor extends Actor { .. } PlayerActor player = new PlayerActor(); // Let's add the actor to the stage gameStage.addActor(player);
  17. Possibilities • Event system for actors; when actor is touched,

    dragged .. – Hit detection; dragging / touching within the bounds of actor • Action system: rotate, move, scale actors in parallel – Also rotation and scaling of group of actors
  18. Stage • Stage implements InputProcessor, so it can directly input

    events from keyboard and touch • Add to your ApplicationAdapter – Gdx.input.setInputProcessor(myStage); • Stage distributes input to actors • Stage has act method, by calling this, every act method of every actor is called
  19. Actors • Actor has an position, rect size, scale, rotation…

    • Position is the left corner of the actor • Position is relative to the actor’s parent • Actor may have actions – Change the presentation of the actor (move, resize) • Actor can react to events
  20. public class StageGame extends ApplicationAdapter { // Stage contains hierarcy

    of actors private Stage stage; // We will have player actor in the stage private BlueBirdActor playerActor; private float width = 8.0f; private float heigth = 4.8f; @Override public void create () { // Creating the stage stage = new Stage(new FitViewport(width, height), batch); // Creating the actors playerActor = new BlueBirdActor(); // add actors to stage stage.addActor(playerActor); } @Override public void render () { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Call act on every actor stage.act(Gdx.graphics.getDeltaTime()); // Call draw on every actor stage.draw(); } }
  21. public class BlueBirdActor extends Actor { private Texture texture; public

    BlueBirdActor() { texture = new Texture(Gdx.files.internal("blue-bird-icon.png")); } @Override public void draw(Batch batch, float alpha) { batch.draw(texture, getX(), getY(), getWidth(), getHeigth()); } @Override public void act(float delta) { super.act(delta); } }
  22. Event System • Stage will be responsible for getting user

    input – Gdx.input.setInputProcessor(stage); • Stage will fire events to actors • Actor may receive events if it has a listener – actor.addListener(new InputListener() { … } ); • Actor must specify bounds in order to receive input events within those bounds! • To handle key input, actor has to have keyboard focus
  23. Specify Bounds public class PlayerActor extends Actor { private Texture

    texture; public PlayerActor() { texture = new Texture(Gdx.files.internal("badlogic.jpg")); setWidth(texture.getWidth() / 100f); setHeight(texture.getHeight() / 100f); setBounds(0, 0, getWidth(), getHeight()); ...
  24. public class StageGame extends ApplicationAdapter { // Stage contains hierarcy

    of actors private Stage stage; // We will have player actor in the stage private BlueBirdActor playerActor; @Override public void create () { // Creating the stage stage = new Stage(...); // Sets the InputProcessor that will receive all touch and key input events. // It will be called before the ApplicationListener.render() method each frame. // // Stage handles the calling the inputlisteners for each actor. Gdx.input.setInputProcessor(stage); // Creating the actors playerActor = new BlueBirdActor(); // add actors to stage stage.addActor(playerActor); stage.setKeyboardFocus(playerActor); } @Override public void render () { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Call act on every actor stage.act(Gdx.graphics.getDeltaTime()); // Call draw on every actor stage.draw(); } }
  25. public class BlueBirdActor extends Actor { private boolean up, down,

    left, right public BlueBirdActor() { addListener(new PlayerListener()); } @Override public void act(float delta) { if(up) { setY(getY() + speed * delta); } } // InputListener implements EventListener, just override the methods you need // Also ActorGestureListener available: fling, pan, zoom, pinch.. class PlayerListener extends InputListener { @Override public void touchDown(...) { } } }
  26. Actions • Each actor has a list of actions •

    Updated on every frame (act-method) • Many actions available – MoveToAction – RotateToAction – ScaleToAction • Example – MoveToAction action = new MoveToAction(); – action.setPosition(300f, 700f); – action.setDuration(2f); – actor.addAction(action);
  27. Grouping Actions in Sequence SequenceAction sequenceAction = new SequenceAction(); MoveToAction

    moveAction = new MoveToAction(); RotateToAction rotateAction = new RotateToAction(); ScaleToAction scaleAction = new ScaleToAction(); moveAction.setPosition(200f, 400f); moveAction.setDuration(1f); rotateAction.setRotation(45f); rotateAction.setDuration(1f); scaleAction.setScale(0.5f); scaleAction.setDuration(1f); sequenceAction.addAction(moveAction); sequenceAction.addAction(rotateAction); sequenceAction.addAction(scaleAction); actor.addAction(sequenceAction);
  28. Grouping Actions in Parallel ParallelAction parallel = new ParallelAction ();

    MoveToAction moveAction = new MoveToAction(); RotateToAction rotateAction = new RotateToAction(); ScaleToAction scaleAction = new ScaleToAction(); moveAction.setPosition(200f, 400f); moveAction.setDuration(1f); rotateAction.setRotation(rotate); rotateAction.setDuration(1f); scaleAction.setScale(0.5f); scaleAction.setDuration(1f); parallel.addAction(moveAction); parallel.addAction(rotateAction); parallel.addAction(scaleAction); actor.addAction(parallel);
  29. Actions Complete? SequenceAction sequenceAction = new SequenceAction(); ParallelAction parallelAction =

    new ParallelAction(); MoveToAction moveAction = new MoveToAction(); RotateToAction rotateAction = new RotateToAction(); RunnableAction runnableAction = new RunnableAction(); moveAction.setPosition(200f, 400f); moveAction.setDuration(1f); moveAction.setInterpolation(Interpolation.bounceOut); rotateAction.setRotation(rotate); rotateAction.setDuration(1f); runnableAction.setRunnable(new Runnable() { public void run() { System.out.println("done!"); } }); parallelAction.addAction(rotateAction); parallelAction.addAction(moveAction); sequenceAction.addAction(parallelAction); sequenceAction.addAction(runnableAction);
  30. Enable rotate and scale in drawing @Override public void draw(Batch

    batch, float alpha){ batch.draw(texture, this.getX(), this.getY(), this.getOriginX(), this.getOriginY(), this.getWidth(), this.getHeight(), this.getScaleX(), this.getScaleY(), this.getRotation(),0,0, texture.getWidth(), texture.getHeight(), false, false); }
  31. Scene2D.UI • Tutorial – https://github.com/libgdx/libgdx/wiki/Scene2d.ui • To quickly get started,

    add following to your project – uiskin.png, uiskin.atlas, uiskin.json, default.fnt, https://github.com/libgdx/libgdx/tree/master/test s/gdx-tests-android/assets/data • More skins available – https://github.com/libgdx/libgdx/wiki/Skin
  32. TextButton example Skin skin = new Skin( Gdx.files.internal("uiskin.json") ); final

    TextButton button = new TextButton("Hello", skin); button.setWidth(200f); button.setHeight(20f); button.setPosition(Gdx.graphics.getWidth() /2 - 100f, Gdx.graphics.getHeight()/2 - 10f); startStage.addActor(button); Gdx.input.setInputProcessor(startStage); button.addListener(new ClickListener(){ @Override public void clicked(InputEvent event, float x, float y){ whichScreen = !whichScreen; Gdx.input.setInputProcessor(gameStage); } });