I have two clases, one for main methods and the other for splash. However, switching between these two doesn't work. I wanted to draw an image in the Splash class, but it turned black instantly. And when I moved the code from the splash to main class, the image appeared.
Main class:
public class Main extends Game {
public static int WIDTH, HEIGHT;
public void create () {
WIDTH = Gdx.graphics.getWidth();
HEIGHT = Gdx.graphics.getHeight();
setScreen(new Splash());
}
public void render () { }
public void dispose() { super.dispose(); }
public void pause() { super.pause(); }
public void resize(int width, int height) { super.resize(width, height); }
public void resume() { }
}
Splash class:
public class Splash implements Screen {
private Sprite splash;
private SpriteBatch sb;
public void show() {
sb = new SpriteBatch();
Texture splashTexture = new Texture(Gdx.files.internal("res/img/splash.png"));
splash = new Sprite(splashTexture);
splash.setSize(Main.WIDTH, Main.HEIGHT);
Gdx.gl.glClearColor(0, 0, 0, 1);
}
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sb.begin();
splash.draw(sb);
sb.end();
}
public void resize(int width, int height) { }
public void resume() { }
public void dispose() { }
public void hide() { }
public void pause() { }
}
Any idea, what could cause the problem of not rendering the image in Splash class?
UPDATE 1: I have discovered, that the render() method inside the Splash class doesn't even get called (but the show() method does)
You should call the render method from your game class. If you dont call it noone will do that for you. You shouldn't override the render method of the game class which you do and you do it empty so it wont call anything for you.
Lets take a look into the Game class. It does implement all methods from the ApplicationListener interface (well not the create()). So there is no need for you to override anything of it. Simply delete your:
public void render () { }
public void dispose() { super.dispose(); }
public void pause() { super.pause(); }
public void resize(int width, int height) { super.resize(width, height); }
public void resume() { }
and it should work fine. Even though these are useless methods. They do nothing than calling the super class so why you write those. If you have not written that it automatically calls the super methods.
But okay if you want to handle the stuff yourself like calling dispose on a screen or calling the init before you set a new screen you need to write your own "game" class which implements the ApplicationListener interface.
To give you an idea on how to do this ill post a small example which i use for some tests:
public class MyGameClass implements ApplicationListener {
private Screen curScreen; // the current screen
#Override
public void create(){
Gdx.graphics.getWidth();
Gdx.graphics.getHeight();
Intro temp = new Intro(this);//just an example of the first screen to load up
setScreen(temp);
}
public void setScreen(Screen s) {
if (curScreen != null) {
curScreen.hide();
curScreen.dispose();
}
curScreen = s;
curScreen.show();
curScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
s.init();
}
#Override
public void dispose() {
curScreen.dispose();
}
#Override
public void render() {
curScreen.render(Gdx.graphics.getDeltaTime()); //call the rendermethod with the delta time as parameter
}
#Override
public void resize(int width, int height) {
curScreen.resize(width, height);
}
#Override
public void pause() {
curScreen.pause();
}
#Override
public void resume() {
curScreen.resume();
}
}
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()
I have used the stage method. But it doesn't work. I am new in game developing. Help me out please.
You can use Label, If you're using scene2d in this way :
public class GdxText extends ApplicationAdapter {
Stage stage;
Label scoreLabel;
#Override
public void create() {
stage=new Stage();
Label.LabelStyle labelStyle=new Label.LabelStyle(new BitmapFont(), Color.RED);
scoreLabel=new Label(String.format("%03d",0),labelStyle);
Table table =new Table();
table.defaults().pad(2);
table.add(new Label("SCORE :",labelStyle));
table.add(scoreLabel);
table.setPosition(200,300);
stage.addActor(table);
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.draw();
stage.act();
}
public void increase(){
CharSequence value=scoreLabel.getText();
int v= Integer.valueOf(value.toString());
scoreLabel.setText(String.format("%03d", ++v));
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width,height,true);
}
#Override
public void dispose() {
stage.dispose();
}
}
I am using default font for this test, you can use own font. Whenever you want to increase value of score call increase() method, that increase your score by one.
Output :
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'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.
I have tried to use this tutorial:
http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=484#p2959
Firstly have declared private Toast render_toast = new Toast(7, 6);
After that putted render_toast.toaster(); to render.
I would like to use it in show, so I have put this to show():
render_toast.makeText("Game start", "font", Toast.COLOR_PREF.BLUE, Toast.STYLE.ROUND, Toast.TEXT_POS.middle_right, Toast.TEXT_POS.middle_down, Toast.MED);
It isn't working, gives no error message, only stop my application.
I have implemented Android-like toast for my project and decided to share it with you! Enjoy: Toast LibGDX (GitHub)
Create an interface for required methods in your game. Implement this method in your AndroidLauncher class, using libgdx handler. You can call these methods anywhere in your game for Android related UI.
You can follow this video for details,
https://www.youtube.com/watch?v=XxiT3pkIiDQ
This is how, I used it in my game.
//Defining interface for customized methods
public interface AndroidInterfaces {
public void toast(final String t);
}
//implementing the interface in android launcer
public class AndroidLauncher extends AndroidApplication implements AndroidInterfaces{
final AndroidLauncher context=this;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
//if (Gdx.input.isPeripheralAvailable(Peripheral.Compass))
cfg.useCompass = true;
//cfg.useAccelerometer=true;
initialize(new MyGame(this), cfg);
}
#Override
public void toast(final String t) {
handler.post(new Runnable()
{
#Override
public void run() {
//System.out.println("toatsing in launcher run");
Toast.makeText(context, t, Toast.LENGTH_SHORT).show();
}
});
}
}
public class MyGame extends Game{
//16012016
//16012016 for toast
AndroidInterfaces aoi;
public MyGame(AndroidInterfaces maoi)
{
aoi=maoi;
}
public MyGame()
{
}
public boolean backpressed=false; //Universal flag to check back button press status , across screens.
.....
.....
}
public class MainMenuScreen implements Screen{
MyGame game;
float x,y,w,h,pw,gap;
float x1,y1; //coordinates for animation
//16012016
boolean toast=false;
float toasttimer=0;
public MainMenuScreen(MyGame gg) {
game = gg;
}
#Override
public void render(float delta) {
//16012016
if(toast)
{
toasttimer=toasttimer+delta;
}
.....
...//omitted
//16012016:Toast
if(toast)
{
if(toasttimer> 2.5)
Gdx.app.exit();
else if (Gdx.input.isKeyJustPressed(Keys.BACK)) //For double back press exit effect.
Gdx.app.exit();
}
else if (Gdx.input.justTouched()) {
game.setScreen(game.STS); //Setting another screen
}
//16012016
else if (Gdx.input.isKeyJustPressed(Keys.BACK))
if(!game.backpressed)
{
if(!toast)
{
toast=true; //if bsck button is just pressed in current screen then toasting..
game.aoi.toast("EXITING.THANKS FOR PLAYING!"); //Not relevant to desktop project, calling implemented method in androind launcher
}
}
}
else if(game.backpressed)
{
game.backpressed=false;
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
//16012016
toasttimer=0;
toast=false;
Gdx.graphics.setContinuousRendering(true);
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}