I'm trying to display a simple text for a menu UI using scene2D, but for some reason nothing is being displayed here. The screen displays pure black.
public class ScreenMenu implements Screen {
MyGame myGame;
SpriteBatch batch;
Stage stage;
Label labelNewGame, labelContinue, labelCredits;
public ScreenMenu(MyGame myGame) {
this.myGame = myGame;
}
#Override
public void show() {
init();
BitmapFont font = initFont();
initLabels(font);
initStage();
}
private void init() {
batch = new SpriteBatch();
}
private BitmapFont initFont() {
return new FontLoader().getMichroma();
}
private void initLabels(BitmapFont font) {
Label.LabelStyle labelStyle = new Label.LabelStyle(font, Color.WHITE);
labelNewGame = new Label("New Game", labelStyle);
labelContinue = new Label("Continue", labelStyle);
labelCredits = new Label("Credits", labelStyle);
}
private void initStage() {
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
stage.addActor(labelNewGame);
}
#Override
public void render(float delta) {
GlHelper.clearScreen();
stage.act(delta);
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
myGame.dispose();
batch.dispose();
stage.dispose();
}
}
The following class contains the clearScreen function. If I don't run it, the entire screen becomes super glitchy, but I can see the New Game text.
public class GlHelper {
public static void clearScreen() {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
public static void clearScreen(float red, float green, float blue, float alpha) {
Gdx.gl.glClearColor(red, green, blue, alpha);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
}
Do you use?
setBounds(x, y, w, h);
before to add stage for example:
labelNewGame.setBounds(0, 0, 100, 100);
maybe he can help you.
I feel stupid now. In the FontLoader implementation I set the FreeTypeFontParameter color to Color.BLACK. Apparently it overrides the Color.WHITE argument from LabelStyle.
Related
I'm not new to libgdx, but when i ended up with my previous university project, and started new one, Android studio or IDEA cannot resolve setScreen method, other stuff works fine. Any ideas ? Hope for help. (project absolutely clear).
Creating a project in LibGdx gives you your core file which implements the ApplicationListener.
What I gather you are referring to is extending the Game class with with you set Screen classes with.
With the ApplicationListener.
public class HelloWorld implements ApplicationListener {
private SpriteBatch batch;
private BitmapFont font;
#Override
public void create() {
batch = new SpriteBatch();
font = new BitmapFont();
font.setColor(Color.RED);
}
#Override
public void dispose() {
batch.dispose();
font.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.begin();
font.draw(batch, "Hello World", 200, 200);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
What you're after: (taken from https://github.com/libgdx/libgdx/wiki/Extending-the-simple-game)
public class Drop extends Game {
public SpriteBatch batch;
public BitmapFont font;
public void create() {
batch = new SpriteBatch();
//Use LibGDX's default Arial font.
font = new BitmapFont();
this.setScreen(new MainMenuScreen(this));
}
public void render() {
super.render(); //important!
}
public void dispose() {
batch.dispose();
font.dispose();
}
}
Which allows you to change screens whenever you need:
public class MainMenuScreen implements Screen {
final Drop game;
OrthographicCamera camera;
public MainMenuScreen(final Drop game) {
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
}
//...Rest of class omitted for succinctness.
}
For default, gdx main Class will extends ApplicationAdapter, you need extends Game class for get use of setScreen()
issue is next one: my game is built for 1080x1920 pixels screen but if I run it in other resolutions my actors' position is switching.
Some pictures if you haven't understood:
~> original resolution
~> other resolution
I looked for an answer for days in Google, Stackoverflow, forums, couldn't find the right answer for my problem, here's my code:
public class PlayScreen implements Screen {
private Main game;
private Stage stage;
Music music;
Sound sound;
private class MenuGame extends Actor {
Texture menu = new Texture(Gdx.files.internal("sprite/menu.png"));
#Override
public void draw(Batch batch, float alpha) {
batch.draw(menu, 0, 0,Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
}
private class NewGame extends Actor {
Texture newgame = new Texture(Gdx.files.internal("sprite/new.png"));
#Override
public void draw(Batch batch, float alpha) {
batch.draw(newgame, 350, 1000);
}
}
private class LoadGame extends Actor {
Texture loadgame = new Texture(Gdx.files.internal("sprite/load.png"));
#Override
public void draw(Batch batch, float alpha) {
batch.draw(loadgame, 350, 830);
}
}
private class CreditsGame extends Actor {
Texture creditsgame = new Texture(Gdx.files.internal("sprite/credits.png"));
#Override
public void draw(Batch batch, float alpha) {
batch.draw(creditsgame, 350, 660);
}
}
private class DonsGame extends Actor {
Texture donsgame = new Texture(Gdx.files.internal("sprite/dons.png"));
#Override
public void draw(Batch batch, float alpha) {
batch.draw(donsgame, 350, 490);
}
}
// our create()
public PlayScreen(final Main game) {
this.game = game;
Gdx.input.setInputProcessor(stage);
final Sound sound = Gdx.audio.newSound(Gdx.files.internal("sound/buttonsound.mp3"));
music = Gdx.audio.newMusic(Gdx.files.internal("sound/brun.mp3"));
music.setLooping(true);
music.setVolume(0.2f);
music.play();
// actors
MenuGame menu = new MenuGame(); // BACKGROUND
stage.addActor(menu);
final NewGame newGame = new NewGame(); // BOUTON NEW
stage.addActor(newGame);
newGame.setX(350);
newGame.setY(1000);
newGame.setWidth(410);
newGame.setHeight(100);
LoadGame loadGame = new LoadGame(); // BOUTON LOAD
stage.addActor(loadGame);
loadGame.setX(350);
loadGame.setY(830);
loadGame.setWidth(410);
loadGame.setHeight(100);
CreditsGame creditsGame = new CreditsGame(); // BOUTON CREDITS
stage.addActor(creditsGame);
creditsGame.setX(350);
creditsGame.setY(660);
creditsGame.setWidth(410);
creditsGame.setHeight(100);
DonsGame donsGame = new DonsGame(); // BOUTON DONS
stage.addActor(donsGame);
donsGame.setX(350);
donsGame.setY(490);
donsGame.setWidth(410);
donsGame.setHeight(100);
// actions
newGame.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) // NEW BOUTON ACTION
{
sound.play(0.2f);
music.stop();
game.setScreen(new Story(game));
return true;
}
});
loadGame.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) // LOAD BOUTON ACTION
{
sound.play(0.2f); //faire un truc ici
return true;
}
});
creditsGame.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) // CREDITS BOUTON ACTION
{
sound.play(0.2f);//faire un truc ici
return true;
}
});
donsGame.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) // DONS BOUTON ACTION
{
sound.play(0.2f);//faire un truc ici
return true;
}
});
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
stage.dispose();
music.dispose();
sound.dispose();
}
}
You are positioning everything after hardcoded values. So right now your game is very resolution depended.
What you need to use is Viewports.
Here are some links to get you started:
Brent Aureli - Aspect Ratios & Viewports
libgdx github - viewports
libgdx github - scene2d
this is happening because different devices has different screen size. so it will appear differently . to avoid this you must use the viewPort .for more clarification you must read the libgdx api about the multi resolution and the viewPort . here i will suggest you some sample code to avoid this multi screen issue. please follow this pattern which acan solve your problem.
// in your main class
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera
public Viewport viewPort
private SpriteBatch batch;
private BitMapFont myScoreFont
public myGame() {
}
#Override
public void create() {
myScoreFont = new BitmapFont(Gdx.files.internal(font.txt), true);
batch = new SpriteBatch();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, Constants.APP_WIDTH, Constants.APP_HEIGHT);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
myScoreFont.draw(batch,"myText",0,0)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
for more details you must read the below link about the viewport
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/viewport/FillViewport.html
I have a blue square, and when the blue square is moved to the finish flag, the screen should change to signify that the level is complete. However, when I move the blue square to such position, I get an error message:
Exception in thread "LWJGL Application" org.lwjgl.opengl.OpenGLException: Cannot use offsets when Array Buffer Object is disabled
at org.lwjgl.opengl.GLChecks.ensureArrayVBOenabled(GLChecks.java:77)
at org.lwjgl.opengl.GL20.glVertexAttribPointer(GL20.java:892)
at com.badlogic.gdx.backends.lwjgl.LwjglGL20.glVertexAttribPointer(LwjglGL20.java:847)
at com.badlogic.gdx.graphics.glutils.ShaderProgram.setVertexAttribute(ShaderProgram.java:662)
at com.badlogic.gdx.graphics.glutils.VertexBufferObject.bind(VertexBufferObject.java:202)
at com.badlogic.gdx.graphics.Mesh.bind(Mesh.java:380)
at com.badlogic.gdx.graphics.Mesh.bind(Mesh.java:371)
at com.badlogic.gdx.graphics.Mesh.render(Mesh.java:479)
at com.badlogic.gdx.graphics.Mesh.render(Mesh.java:422)
at com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20.flush(ImmediateModeRenderer20.java:151)
at com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20.end(ImmediateModeRenderer20.java:160)
at com.badlogic.gdx.graphics.glutils.ShapeRenderer.end(ShapeRenderer.java:1104)
at com.badlogic.gdx.graphics.glutils.ShapeRenderer.check(ShapeRenderer.java:1087)
at com.badlogic.gdx.graphics.glutils.ShapeRenderer.polygon(ShapeRenderer.java:1014)
at com.badlogic.gdx.graphics.glutils.ShapeRenderer.polygon(ShapeRenderer.java:1043)
at com.ian.redsquare.Entities.Walls.render(Walls.java:22)
at com.ian.redsquare.Screens.RedSquareScreen.render(RedSquareScreen.java:65)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)
here is the screen class in which the blue square moves:
package com.ian.redsquare.Screens;
import ...
public class RedSquareScreen implements Screen{
RedSquareGame game;
Viewport gameViewport;
ShapeRenderer renderer;
RedSquare redSquare;
BlueSquare blueSquare;
FinishSquare finishSquare;
Walls walls;
public RedSquareScreen(RedSquareGame game){
this.game = game;
}
#Override
public void show() {
gameViewport = new ExtendViewport(C.WORLD_SIZE, C.WORLD_SIZE, C.WORLD_SIZE, C.WORLD_SIZE);
renderer = new ShapeRenderer();
renderer.setAutoShapeType(true);
finishSquare = new FinishSquare(blueSquare);
redSquare = new RedSquare();
blueSquare = new BlueSquare(redSquare);
walls = new Walls();
}
#Override
public void render(float delta) {
redSquare.update(delta);
blueSquare.update(delta);
if(finishSquare.position.dst(blueSquare.position) <= 0){
game.showLevelEndScreen();
}
gameViewport.apply(true);
Gdx.gl.glClearColor(C.BACKGROUND_COLOR.r, C.BACKGROUND_COLOR.g, C.BACKGROUND_COLOR.b, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setProjectionMatrix(gameViewport.getCamera().combined);
renderer.begin();
finishSquare.render(renderer);
redSquare.render(renderer);
blueSquare.render(renderer);
walls.render(renderer);
renderer.end();
}
#Override
public void resize(int width, int height) {
gameViewport.update(width, height, true);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
renderer.dispose();
}
#Override
public void dispose() {
}
}
here is screen class which is meant to appear once the blue square reaches the finish square:
package com.ian.redsquare.Screens;
import ...
public class LevelEndScreen extends InputAdapter implements Screen {
RedSquareGame game;
Viewport viewport;
ShapeRenderer renderer;
SpriteBatch batch;
public LevelEndScreen(RedSquareGame game){
this.game = game;
}
#Override
public void show() {
viewport = new ExtendViewport(C.LE_WORLD_SIZE, C.LE_WORLD_SIZE);
renderer = new ShapeRenderer();
renderer.setAutoShapeType(true);
batch = new SpriteBatch();
Gdx.input.setInputProcessor(this);
}
#Override
public void render(float delta) {
viewport.apply();
Gdx.gl.glClearColor(C.LE_BACKGROUND_COLOR.r, C.LE_BACKGROUND_COLOR.g, C.LE_BACKGROUND_COLOR.b, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.setProjectionMatrix(viewport.getCamera().combined);
renderer.begin(ShapeRenderer.ShapeType.Filled);
renderer.setColor(C.RESTART_COLOR);
renderer.rect(C.LE_WORLD_SIZE / 4, C.LE_WORLD_SIZE / 2, C.BUTTON_SIZE, C.BUTTON_SIZE);
renderer.setColor(C.NEXT_LEVEL_COLOR);
renderer.rect((C.LE_WORLD_SIZE * (3 / 4)) - C.BUTTON_SIZE, C.LE_WORLD_SIZE / 2, C.BUTTON_SIZE, C.BUTTON_SIZE);
renderer.end();
}
#Override
public void resize(int width, int height) {
viewport.update(width, height, true);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
batch.dispose();
renderer.dispose();
}
#Override
public void dispose() {
}
#Override
public boolean touchDown (int screenX, int screenY, int pointer, int button) {
Vector2 worldTouch = viewport.unproject(new Vector2(screenX, screenY));
if(worldTouch.dst2(new Vector2(C.LE_WORLD_SIZE / 4, C.LE_WORLD_SIZE / 2)) == 0){
game.showRedSquareScreen();
}
return true;
}
}
I've started a very small Libgdx project based in Scene2d. I downloaed last version of LGDX. I have tried to find some imformation but nothing clear.
The problem is that I only get a Black Screen of the Death. Nothing happens
I have followed the code, with logs and I'm sure I arrive to Draw method in my Actor with no results:
Thank you in advance.
public class ActorBall extends Actor implements Disposable {
private Texture ballTexture;
private TextureRegion ballTextureRegion;
public ActorBall() {
bolaTexture = new Texture("redball.png");
ballTextureRegion = new TextureRegion(ballTexture, 300,300);
setSize(300,300);
}
#Override
public void dispose(){
bolaTexture.dispose();
}
#Override
public void draw(Batch batch, float parentAlpha) {
Color col = getColor();
batch.setColor(col.r,col.g, col.b,col.a * parentAlpha);
Gdx.app.log("App","where are you");
batch.draw(ballTextureRegion,getX(),getY(),getOriginX(),
getOriginY(),getWidth(), getHeight(), getScaleX(), getScaleY(),getRotation());
}
#Override
public void act(float delta) {
super.act(delta);
}
}
My screen class extended from Screen:
public class scene extends scenebase {
private final OrthographicCamera camera;
private MyGdxGame game ;
private Stage stage; // los Stages son inputprocessors
private ActorBall ball;
public scene(MyGdxGame game) {
super(game);
this.game = game;
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
stage = new Stage(new ScreenViewport());
ball = new ActorBall();
ball.setPosition(0,0);
stage.addActor(ball);
}
#Override
public void render(float delta) {
// super.render(delta);
Gdx.gl.glClearColor(0,0,0.0f,1);
Gdx.gl.glClear (GL20.GL_COLOR_BUFFER_BIT);
camera.update();
// game.batch.setProjectionMatrix(camera.combined);
stage.draw();
stage.act();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update (width,height);
}
}
And last my main game:
public class MyGdxGame extends Game {
private AssetManager manager;
private scene screenscene;
#Override
public void create() {
manager = new AssetManager();
manager.load("redball.png", Texture.class);
manager.finishLoading();
// Enter the loading screen to load the assets.
screenscene = new scene(this);
setScreen(screenscene);
}
#Override
public void render () {
super.render(); // This is very important!!!!!!!!
Gdx.gl.glClearColor(0, 0, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
public AssetManager getManager() {
return this.manager;
}
}
#Override
public void render () {
super.render(); // This is very important!!!!!!!!
Gdx.gl.glClearColor(0, 0, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
What this does is first render everything and then clear the screen. You need to first clear it and then render.
I have been following this tutorial LIBGDX . I followed the similar steps as per the tutorial but the map is not loaded in the background as per the tutorial. I checked the code but I couldn't find the reason .
Here is my code,
public class PlayScreen implements Screen {
private MyJungleGame game;
Texture texture;
private OrthographicCamera gamecam;
private FitViewport gamePort;
private HudClass hud;
private TmxMapLoader maploader;
private TiledMap map;
private OrthogonalTiledMapRenderer renderer;
public PlayScreen(MyJungleGame game) {
this.game = game;
gamecam = new OrthographicCamera();
gamePort = new FitViewport(MyJungleGame.V_WIDTH, MyJungleGame.V_HEIGHT);
hud = new HudClass(game.batch);
maploader = new TmxMapLoader();
map = maploader.load("tiledmap.tmx");
renderer = new OrthogonalTiledMapRenderer(map);
gamecam.position.set(gamePort.getWorldWidth() / 2, gamePort.getWorldHeight() / 2, 0);
}
public void update(float dt) {
handleInput(dt);
gamecam.update();
renderer.setView(gamecam); // it wil draw wat the game cam can see
}
public void handleInput(float dt) { //(----4)
if (Gdx.input.isTouched()) {
gamecam.position.x += 100 * dt;
}
}
#Override
public void show() {
}
#Override
public void render(float delta) {
update(delta);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
game.batch.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
}
#Override
public void resize(int width, int height) {
gamePort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
This is my main game code . I have attached the screenshot of the output .
As you can see it is filled with black background but I need the tiled map to get loaded. I am completely new to this. Please help
I just found it. The problem is in the gameport. I didn't pass the value of camera to the gameport. I just changed the code from
gamePort = new FitViewport(MyJungleGame.V_WIDTH, MyJungleGame.V_HEIGHT);
to something like,
gamePort = new FitViewport(MyJungleGame.V_WIDTH, MyJungleGame.V_HEIGHT,gamecam);