Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (764)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (852)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Libgdx how to display monster name above their head  (Read 12727 times)
0 Members and 1 Guest are viewing this topic.
Offline printer

Junior Devvie


Medals: 1



« Posted 2016-07-17 11:20:42 »

Hello,

It has been days for trying and failing to pull this off. Also asked for help, but seems none can help me either.

I were able to create HUD for the player, that was really easy. But then i got stuck about creating HUD for the monsters. Such as i want to draw their name above the head and also maybe add a health bar aswell.



As you see, the player hud works perfect, but when i move the monster name moves with me. Instead to get attached to the monster.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
public void update(float deltaTime) {
        // update creatures
        world.getPlayer().onThink(deltaTime);
        for (Monster monster : world.getMonsters()) {
            monster.onThink(deltaTime);
        }

        // update camera to the player
        camera.position.set(world.getPlayer().getPosition(), 0);
        camera.update();
    }

    @Override
    public void render(float deltaTime) {
        // clear screen
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        // seprate update logic
        update(deltaTime);

        // set camera to what we see
        worldRenderer.renderer.setView(camera);
        worldRenderer.renderer.render();

        // draw world
        game.spriteBatch.setProjectionMatrix(camera.combined);
        worldRenderer.render();

        // monster UI
        game.spriteBatch.setProjectionMatrix(uiCam.combined);
        for (Monster monster : world.getMonsters()) {
            uiCam.project(uiPosition.set(monster.getPosition().x, monster.getPosition().y, 0));
        }

        game.spriteBatch.begin();
        Assets.font.draw(game.spriteBatch, "Firefox", uiPosition.x / 2, uiPosition.y / 2);
        game.spriteBatch.end();

        // Player Hud
        game.spriteBatch.setProjectionMatrix(hud.stage.getCamera().combined);
        hud.stage.draw();
    }


Thanks!
Offline MrPork
« Reply #1 - Posted 2016-07-17 17:40:32 »

What exactly is happening? I can't tell by the picture. Is that mushroom the monster?

"f**k it, maybe it'll work." -Me
Offline printer

Junior Devvie


Medals: 1



« Reply #2 - Posted 2016-07-17 17:57:59 »

Haha nope, the fox is the monster. When i scale down the font, it does not display whole text. The mushroom does not overlap the text, if you may wonder xD
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline MrPork
« Reply #3 - Posted 2016-07-17 18:14:20 »

Would you mind providing the code which has the instance of Sprite Batch you're using there?

"f**k it, maybe it'll work." -Me
Offline printer

Junior Devvie


Medals: 1



« Reply #4 - Posted 2016-07-17 19:07:38 »

Sure:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
package com.game.newproejctx.World;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.game.newproejctx.Entity.Monster;

public class GameRenderer {

    private GameWorld world;
    public OrthogonalTiledMapRenderer renderer;
    private SpriteBatch spriteBatch;

    public GameRenderer(SpriteBatch spriteBatch, GameWorld world) {
        this.spriteBatch = spriteBatch;
        this.world = world;
        this.renderer = new OrthogonalTiledMapRenderer(world.getMap(), world.unitScale);
    }

    public void render() {
        spriteBatch.begin();
        world.getPlayer().render(spriteBatch);
        for (Monster monster : world.getMonsters()) {
            monster.render(spriteBatch);
        }
        spriteBatch.end();
    }
}


I wonder if it's possible to use Scene2D to display monsters name and maybe later on i will add healthbar by using progress bar or something.
Offline MrPork
« Reply #5 - Posted 2016-07-17 21:33:49 »

Yes it is possible. Is the projection matrix of that spritebatch you're using set to the camera's combined one?

"f**k it, maybe it'll work." -Me
Offline MrPork
« Reply #6 - Posted 2016-07-17 21:34:39 »

I had this similar problem before a long time ago, I am trying to narrow down what it could possibly be.

"f**k it, maybe it'll work." -Me
Offline SuperMario
« Reply #7 - Posted 2016-07-18 00:38:07 »

Are you doing anything special in some overriden draw methods of custom actors? That could be the case.
Offline printer

Junior Devvie


Medals: 1



« Reply #8 - Posted 2016-07-18 09:39:31 »

Well i found out why my font is way to big, i should use a seprate camera to display UI stuff and do not use the same one as the game cam.

But you said it's possible to use Scen2d to display monsters name, here is my Hud and GameScreen:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
package com.game.newproejctx.Scenes;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.game.newproejctx.Entity.Player;
import com.game.newproejctx.Main;

public class Hud implements Disposable {
    public Stage stage;
    private Viewport viewport;

    // Labels
    private static Label nameLabel;

    public Hud(SpriteBatch spriteBatch, Player player) {
        viewport = new FitViewport(Main.VIRTUAL_WIDTH, Main.VIRTUAL_HEIGHT, new OrthographicCamera());
        stage = new Stage(viewport, spriteBatch);

        nameLabel = new Label(player.getName(), new Label.LabelStyle(new BitmapFont(), Color.GREEN));
        nameLabel.setPosition(Main.VIRTUAL_WIDTH / 2 + player.getName().length(), Main.VIRTUAL_HEIGHT / 2 + player.getHeight(), Align.center);

        stage.addActor(nameLabel);
    }

    @Override
    public void dispose() { stage.dispose(); }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
package com.game.newproejctx.Screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.game.newproejctx.Entity.Monster;
import com.game.newproejctx.Main;
import com.game.newproejctx.Scenes.Hud;
import com.game.newproejctx.World.GameRenderer;
import com.game.newproejctx.World.GameWorld;

public class GameScreen extends AbstractScreen {
    // World
    private GameWorld world;
    private GameRenderer worldRenderer;

    // Camera
    private OrthographicCamera camera;
    private Viewport viewport;

    // Hud
    private Hud hud;

    public GameScreen(Main game) {
        super(game);
    }

    @Override
    public void show() {
        world = new GameWorld("map.tmx");
        worldRenderer = new GameRenderer(game.spriteBatch, world);

        camera = new OrthographicCamera();
        viewport = new FitViewport(Main.VIRTUAL_WIDTH * world.unitScale, Main.VIRTUAL_HEIGHT * world.unitScale, camera);
        viewport.apply();

        camera.position.set(viewport.getWorldWidth() / 2, viewport.getWorldHeight() / 2, 0);

        hud = new Hud(game.spriteBatch, world.getPlayer());
    }

    public void update(float deltaTime) {
        world.getPlayer().onThink(deltaTime);

        camera.position.set(world.getPlayer().getPosition(), 0);
        camera.update();
    }

    @Override
    public void render(float deltaTime) {
        GL20 gl = Gdx.gl;
        gl.glClearColor(0, 0, 0, 1);
        gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        update(deltaTime);

        worldRenderer.renderer.setView(camera);
        worldRenderer.renderer.render();

        game.spriteBatch.setProjectionMatrix(camera.combined);
        worldRenderer.render();

        game.spriteBatch.setProjectionMatrix(hud.stage.getCamera().combined);
        hud.stage.draw();
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height);
    }

    @Override
    public void hide() {
    }
}
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #9 - Posted 2016-07-19 03:32:46 »

gl.glClearColor only needs to be set once, not per frame. gl.glClear(GL_COLOR_BUFFER_BIT) flushes the pixels to the clear color. Disabling the glClear gives a cool effect if motion goes on.

There are a few ways you can put names above heads.

One way would be making a function to convert world coordinates to screen coordination's and utilizing this data, draw and offset text appropriately. That is if you use coordinate systems. I am unfamiliar with such function in libgdx, but it shouldn't be too different then the ones I used when scripting on Roblox. Of course I remember nothing from that in specific - that was a few years ago. If need-be I will look it up.

The other way would be taking your modelview matrix of the entity, and translating from there - explicitly or implicitly ignoring any Z depth (into the screen). Using a base Orthogonal matrix of course. Then you would take this position and translate the text the object's height in pixels in the Y axis.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline printer

Junior Devvie


Medals: 1



« Reply #10 - Posted 2016-07-19 11:25:08 »

Thank you for your answer. Can you provide any examples from what i've posted.
Offline printer

Junior Devvie


Medals: 1



« Reply #11 - Posted 2016-07-20 09:27:15 »

Well i think i'm on the right way. I'm using a second camera and font gets drawn right. But problem is that, if player moves, the text moves with him and do not stand still above monster head.
Offline MrPork
« Reply #12 - Posted 2016-07-21 22:23:11 »

Well i think i'm on the right way. I'm using a second camera and font gets drawn right. But problem is that, if player moves, the text moves with him and do not stand still above monster head.

I'm gonna assume once again that you have not set the projection matrix as it sounds like its moving with the screen. So do this with the camera.

1  
yourSpriteBatch.setProjectionMatrix(secondcamera.combined);


do this where you first created the second camera and began drawing your entities

"f**k it, maybe it'll work." -Me
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #13 - Posted 2016-07-22 03:00:38 »

Quick crash course:

Orthogonal matrix is a projection matrix. It maps the screen coordinates you give (X 0-800, Y 0-600) to normalized unit coordinates (X 0-1, Y 0-1). This is for the OpenGL backend of libgdx. It makes it so 100 pixels is 100, not 100/800 or 100/600. (Assuming 800x600 screen)

Model-View matrix is a transformation matrix. Its a matrix made from the position, rotation, and the scale(size, 0 being virtually invisible). This is the base point of where the model would be - in this case a 2d square (two triangles). This doesn't account for the size. If you were to draw all points of the square here, they would be in one corner of the triangle (the origin).

That is why you then transform from the origin to wherever the point needs to be. This is done per vertex (point). You multiply these 3 together in this order. OrthoMatrix * ModelMatrix * Vec3(offsetx,offsety,offsetz).

The Camera matrix, or whatever people want to call it, fits inbetween model and vertex offset. This is a further offset from the Model matrix. It allows to emulate the objects by offsetting them, for the fact there is not such thing as a camera in game programming. "move the world around instead of player"

... bottom line ....

Make sure you have an ortho matrix, camera matrix, and a model matrix generated from the position, rotation, and scale. libgdx may do most of the work for you, so you should research more on libgdx in these areas - not necessarily matrix portion, but make sure something is happening to get the disired result.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline printer

Junior Devvie


Medals: 1



« Reply #14 - Posted 2016-07-22 14:55:58 »

Thank you everyone, for trying to help me. I have updated the first post. Since i know im near to the solution, but it does not work  Sad
Offline Icecore
« Reply #15 - Posted 2016-07-23 11:45:07 »

I newer Used Libgdx  ^^ - but i can show how it must be in layout
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
   @Override
   public void render(float deltaTime) {
      // clear screen
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

      // seprate update logic
      update(deltaTime);

      // set camera to what we see
      worldRenderer.renderer.setView(camera);
      worldRenderer.renderer.render();
      //Why? dublicate render
--      worldRenderer.render();

      //this is painted in 2D - screen space - like GUI (inventory button etc)
      //don't need change projection matrix you already in orthographics projection
      //maybe need reset matrix to base - if Libgdx have same worlds matrix and GUI
--      Assets.font.draw(game.spriteBatch, "Firefox", uiPosition.x / 2, uiPosition.y / 2);
      // Game GUI
++      GUI.draw();
   }
   //////
   public worldRenderer.renderer.render(){
      world.getPlayer().render();
         for (Monster monster : world.getMonsters()) {
            monster.render();
         }
      ///Render Text - HP bars DMG numbers etc
      //Don't need change camera matrix
      world.getPlayer().render_Text(); // + y offset to be over Player head - "Player"
      for (Monster monster : world.getMonsters()) {
         monster.render_Text();// + y offset - "Firefox" (x,y = monster Position)
      }
   }

Because for some unknown reasons ppl that use Libgdx can't answer Tongue

p.s Libgdx is not simple for beginners - maybe try RPG Maker, or Unity, Unreal

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Offline printer

Junior Devvie


Medals: 1



« Reply #16 - Posted 2016-07-24 07:46:43 »

Hello,

Thank you for your respone. About duplicate render, one is render the tiled map and another is rendrering creatures.
Without setting a new projection matrix, then the GUI stuff i render gets unit scaled, which is not ideal.
Offline SuperMario
« Reply #17 - Posted 2016-07-24 19:04:07 »

Just use one camera and use batch.setProjectionMatrix to that camera.
set it to null when drawing gui
Offline printer

Junior Devvie


Medals: 1



« Reply #18 - Posted 2016-07-24 20:49:57 »

Just use one camera and use batch.setProjectionMatrix to that camera.
set it to null when drawing gui

I tried:

1  
game.spriteBatch.setProjectionMatrix(null);


Got NullPointerException error.
Offline SuperMario
« Reply #19 - Posted 2016-07-24 21:19:49 »

Just use one camera and use batch.setProjectionMatrix to that camera.
set it to null when drawing gui

I tried:

1  
game.spriteBatch.setProjectionMatrix(null);


Got NullPointerException error.


Hhhm, you could also use 2 batches, spriteBatch/hudBatch.
Offline printer

Junior Devvie


Medals: 1



« Reply #20 - Posted 2016-07-24 21:35:08 »

Just use one camera and use batch.setProjectionMatrix to that camera.
set it to null when drawing gui

I tried:

1  
game.spriteBatch.setProjectionMatrix(null);


Got NullPointerException error.


Hhhm, you could also use 2 batches, spriteBatch/hudBatch.

Then im back at square one. Where the name does not attach to the monster. If you read my first post, it will happen same thing. Also i'm share same batch with my hud.
Offline SuperMario
« Reply #21 - Posted 2016-07-25 12:52:02 »

draw the name in the monster´s render function not in the hud then it should be fine
Offline printer

Junior Devvie


Medals: 1



« Reply #22 - Posted 2016-07-25 17:46:47 »

draw the name in the monster´s render function not in the hud then it should be fine

Well that would work if i was not using unit scale  Undecided

Also wanna Thank you for trying to help me, really appricate it  Smiley
Offline SuperMario
« Reply #23 - Posted 2016-07-25 18:03:27 »

font.setScale(w.e. you use);
draw name
font.setScale(1); //reset
Offline printer

Junior Devvie


Medals: 1



« Reply #24 - Posted 2016-07-26 10:05:45 »

font.setScale(w.e. you use);
draw name
font.setScale(1); //reset

Sorry, but this did not work. I scaled it down as much as possible, but the font gets disorted and does not display whole name:
Offline Icecore
« Reply #25 - Posted 2016-07-26 22:12:36 »

Sorry, but this did not work. I scaled it down as much as possible, but the font gets disorted and does not display whole name:
Don't try zoom font) its 2d - create new one with prefer size 8-14 ttf

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Offline printer

Junior Devvie


Medals: 1



« Reply #26 - Posted 2016-07-27 06:03:31 »

Sorry, but this did not work. I scaled it down as much as possible, but the font gets disorted and does not display whole name:
Don't try zoom font) its 2d - create new one with prefer size 8-14 ttf

"Fonts in libgdx are scaled in pixel dimensions and not your game world units. The best course of action here is to maintain two sperate cameras to render your game: world, and ui.

The world camera will be in your world units as you have it now. The ui camera will be in pixel units scaled to the game window. Use the project and unproject methods on the camera classes to position your ui elements correctly. Render the world using the world camera then do a ui pass over that with the ui camera."

My way is ideal, but i need help to setup it correctly.
Offline Icecore
« Reply #27 - Posted 2016-07-27 09:21:23 »

My way is ideal, but i need help to setup it correctly.
It's not )
(becouse you scale texture of font Atlas)
wrong stackexchange answer ^^
http://gamedev.stackexchange.com/questions/73688/why-is-my-text-is-too-large-even-when-scaled-to-05f-in-libgdx
//
right one
http://stackoverflow.com/questions/29907063/scale-a-bitmapfont-in-libgdx

Or use official doc
https://github.com/libgdx/libgdx/wiki/Gdx-freetype

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Offline printer

Junior Devvie


Medals: 1



« Reply #28 - Posted 2016-07-27 09:26:59 »

But if it's not ideal, then how will i draw health bar at unit scale aswell?
Offline Icecore
« Reply #29 - Posted 2016-07-27 09:30:32 »

But if it's not ideal, then how will i draw health bar at unit scale aswell?
Create 5-10 fonts that you needed
- they all have same img quality as you create them, if you not try to scale them.

If you have in game zoom and wants to zoom in-out camera with font zoom

you can scale font texture – for 10-20% its ok, but on 200-300% it looks terrible
so you can swap on bigger/smallest Texture font
//
or try use https://github.com/libgdx/libgdx/wiki/Distance-field-fonts

up:
http://stackoverflow.com/questions/14675007/how-to-draw-smooth-text-in-libgdx

Last known State: Reassembled in Cyberspace
End Transmission....
..
.
Journey began Now)
Pages: [1] 2
  ignore  |  Print  
 
 

 
EgonOlsen (580 views)
2018-06-10 19:43:48

EgonOlsen (682 views)
2018-06-10 19:43:44

EgonOlsen (471 views)
2018-06-10 19:43:20

DesertCoockie (822 views)
2018-05-13 18:23:11

nelsongames (1025 views)
2018-04-24 18:15:36

nelsongames (1082 views)
2018-04-24 18:14:32

ivj94 (1662 views)
2018-03-24 14:47:39

ivj94 (589 views)
2018-03-24 14:46:31

ivj94 (1491 views)
2018-03-24 14:43:53

Solater (567 views)
2018-03-17 05:04:08
Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46

Deployment and Packaging
by philfrei
2018-08-19 23:53:08

Deployment and Packaging
by philfrei
2018-08-19 23:50:04

Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!