i'm new to libgdx and i can't figure out what i do wrong.
In my game I just want to switch between 2 screens (first is menuScreen, second is gameScreen). I have created these two screens and one game class, it all looks okay. But when i call my method setScreen(new GameScreen()) nothing happens. Also i should say, that i used screen and game classes in my previous project and all was ok, when i compare my current code to previous one i do not see any differences, so it is very curiously.
Here is my MenuScreen class:
MenuScreen implements Screen {
private SpriteBatch batch ;
private Texture texture;
private float timePassed;
public MenuScreen() {
timePassed = 0;
batch = new SpriteBatch();
texture = new Texture("texture.png");
#Override
public void render (float delta) {
timePassed += Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (timePassed > 5) {GameClass.getInstance().setScreen(new GameScreen());} //it looks strange, but it's to check if all works properly
batch.begin();
batch.draw(texture, 0, 0);
batch.end();
}
#Override
public void dispose() {
batch.dispose();
texture.dispose();
}
#Override
public void hide() {
}
#Override
public void resume() {
}
#Override
public void pause() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}}
Here is my GameScreen class:
GameScreen implements Screen {
private SpriteBatch batch2 ;
private Texture texture2;
public MenuScreen() {
batch2 = new SpriteBatch();
texture2 = new Texture("texture2.png");
}
#Override
public void render (float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch2.begin();
batch2.draw(texture2, 0, 0);
batch2.end();
}
#Override
public void dispose() {
batch2.dispose();
texture2.dispose();
}
#Override
public void hide() {
}
#Override
public void resume() {
}
#Override
public void pause() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}}
And Game class:
public class ClassGame extends Game {
public static ClassGame getInstance(){
ClassGame instance = new ClassGame();
return instance;
}
#Override
public Screen getScreen() {
return super.getScreen();
}
#Override
public void setScreen(Screen screen) {
super.setScreen(screen);
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
}
#Override
public void render() {
super.render();
}
#Override
public void resume() {
super.resume();
}
#Override
public void pause() {
super.pause();
}
#Override
public void dispose() {
super.dispose();
}
public ClassGame() {
super();
}
#Override
public void create() {
MenuScreen menuScreen = new MenuScreen();
setScreen(menuScreen);
}}
This is how I did for the same problem, i had three classes for two screen to switch between them. Here I am switching between second and third using a image actor as button.I also used two constructors in each class, one of them constructors with no arguments, below is my code hope you will get it.
My main class code:
public class First extends Game{
private Game game;
public Main(){ game=this; }
public void create() {
game.setScreen(new Second(game)); }}
Below is my first screen class code
public class Second implements Screen{
private Game second;
public Second(Game second){this.second=second;}
public Second(){}
// your code
Stage myStage=new Stage(new ScreenViewport());
Group myGroup=new Group();
Image secondButton=new Image(new Texture(Gdx.files.internal("image.png")));
public void show(){
myGroup.addActor(secondButton);
secondButton.addListener(new InputListener(){
second.setScreen(new Third(second)); });}
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
myStage.act(Gdx.graphics.getDeltaTime());
myStage.draw(); }
public void resize(int width, int height) {}
public void pause(){}
public void resume(){}
public void hide(){}
public void dispose(){}}}
And my next screen class code
public class Third implements Screen{
private Game third;
public Third(Game third){
this.third=third;}
public Third(){}
// your code
Stage myStage=new Stage(new ScreenViewport());
Group myGroup=new Group();
Image thirdButton=new Image(new Texture(Gdx.files.internal("image.png")));
public void show() {
myGroup.addActor(thirdButton);
thirdButton.addListener(new InputListener(){
third.setScreen(new Third(third));});}
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
myStage.act(Gdx.graphics.getDeltaTime());
myStage.draw();}
public void resize(int width, int height) { }
public void pause(){}
public void resume(){}
public void hide(){}
public void dispose(){}}}
I got it, guys. In my previous project i declared instance field outside of getInstance(). Like this :
public static GameClass instance = new GameClass();
public static GameClass getInstance(){
return instance;
}
But i still need your help. I don't know how this small thing wasn't letting me switch screens.
Related
I'm new to the world of app development, but I already have some specific knowledge. But my issue is the following involving libgdx and Android Studio:
When trying to load a texture through the Assets Manager method, the following error occurs:
`
E/AndroidRuntime: FATAL EXCEPTION: GLThread 593
Process: br.com.tpgames.dbz, PID: 19495
com.badlogic.gdx.utils.GdxRuntimeException: Asset not loaded: bater_1/goku2.png
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:172)
at com.badlogic.gdx.assets.AssetManager.get(AssetManager.java:143)
at br.com.tpgames.dbz.SplashScreen.<init>(SplashScreen.java:53)
`
My codes:
main class:
`
public class MainClass extends Game {
public AssetManager manager;
public void create () {
setScreen(new SplashScreen (this, manager));
}
}
`
Splash screen
`
public class SplashScreen implements Screen {
private Game game;
private AssetManager manager;
private float time = 0;
private SpriteBatch batch;
private Texture tex;
long startime;
public Texture goku;
public SplashScreen(Game game, AssetManager manager){
this.game = game;
this.manager = manager;
batch = new SpriteBatch();
tex = new Texture("logo.png");
startime = TimeUtils.millis();
manager = new AssetManager();
for (int i=1;i<=5;i++){
manager.load("bater_1/"+i+".png",Texture.class);
}
boolean load = manager.isLoaded("bater_1/goku1.png");
Gdx.app.log("Log", String.valueOf(load));
goku = manager.get("bater_1/goku2.png",Texture.class);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
time+=delta;
if (manager.update() && time >=2){ //Se o tempo for maior que 2 segundos, vai abrir a tela principal
game.setScreen(new Tela_Principal(game,manager));
}
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(tex, (float) (screenx*0.26), (float) (screeny*0.1), (float) (screenx*0.5), (float) (screeny*0.8));
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
`
Constants
`
public class Constantes {
public static int screenx = Gdx.graphics.getWidth();
public static int screeny = Gdx.graphics.getHeight();
}
`
Main screen
`
public class Tela_Principal implements Screen {
private Game game;
private AssetManager manager;
private SpriteBatch batch;
private SplashScreen splashScreen;
// private Texture goku;
public Tela_Principal(Game game, AssetManager manager){
this.game = game;
this.manager = manager;
splashScreen = new SplashScreen(game,manager);
for (int i=1;i<=5;i++){
manager.load("bater_1/goku"+i+".png",Texture.class);
}
batch = new SpriteBatch();
// goku = manager.get("bater_1/goku1.png",Texture.class);
}
#Override
public void show() {
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0,1,0,0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(splashScreen.goku, (float) (screenx *0.1), (float) (screeny*0.1));
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
`
I thank you for your help!!
manager.load() will queue your asset, not immediately load it.
Only when manager.update() returns true will the assets be available.
Looks like your problem is in SplashScreen
for (int i=1;i<=5;i++){
manager.load("bater_1/"+i+".png",Texture.class);
}
//not allowed
goku = manager.get("bater_1/goku2.png",Texture.class);
AssetManager is well explained here https://libgdx.com/wiki/managing-your-assets
I'm trying to create an android game using libgdx with a Titlescreen, you just press start and your game startes. However I'm having difficulty trying to get these buttons to work. The title-screen works, but as soon as I press 'start game' the game crashes with the error:
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.dinab.onepiecev2.TitleScreen$1.clicked(TitleScreen.java:47) at
com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:88)
at
com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:59)
at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:351) at
com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:360)
at
com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:221)
at
com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:128)
I don't understand what I'm doing wrong and whether the problem is in my TitleScreen.java or in my GameScreen.java
These are my codes:
Main class
public class Onepiecev2 extends Game {
static public Skin gameSkin;
public void create () {
gameSkin = new Skin(Gdx.files.internal("skin/glassy-ui.json"));
this.setScreen(new TitleScreen(this));
}
public void render () {
super.render();
}
public void dispose () {
}
}
TitleScreen
public class TitleScreen implements Screen {
Stage stage;
Game game;
SpriteBatch batch;
Texture img;
TextureRegion mainBackground;
public TitleScreen(Game aGame){
batch = new SpriteBatch();
img = new Texture("start_screen.jpg");
mainBackground = new TextureRegion(img, 0, 0, 1920, 1080);
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
Skin mySkin = new Skin(Gdx.files.internal("skin/glassy-ui.json"));
Button start_btn = new TextButton("START GAME", mySkin);
start_btn.setSize(Constantes.screenWidth/4, Constantes.screenHeight/12);
start_btn.setPosition(Constantes.col_width*3,Constantes.row_height/3);
start_btn.addListener( new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen( new GameScreen(game) );
}
} );
stage.addActor(start_btn);
}
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(mainBackground, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
stage.act();
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();
batch.dispose();
img.dispose();
}
}
GameScreen
public class GameScreen implements Screen {
Stage stage;
Game game;
SpriteBatch batch;
Texture img;
TextureRegion mainBackground;
public GameScreen(Game aGame){
batch = new SpriteBatch();
img = new Texture("start_screen.jpg");
mainBackground = new TextureRegion(img, 0, 0, 1920, 1080);
stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);
Skin mySkin = new Skin(Gdx.files.internal("skin/glassy-ui.json"));
Button start_btn = new TextButton("GO BACK", mySkin);
start_btn.setSize(Constantes.screenWidth/4, Constantes.screenHeight/12);
start_btn.setPosition(Constantes.col_width*3,Constantes.row_height/3);
start_btn.addListener( new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
game.setScreen( new TitleScreen(game));
}
} );
stage.addActor(start_btn);
}
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(mainBackground, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
batch.end();
stage.act();
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();
batch.dispose();
img.dispose();
}
}
From the crash log, it looks like the problem is in your TitleScreen where you are adding a click listener. I am referring to the following line.
game.setScreen(new GameScreen(game));
Looks like the game object is not initialized before and hence you are getting a NullPointerException.
Trying to create a simple loading Screen. The below code prints the correct progress, so I know that part works. But the rectangle is not being drawn. Not sure what is wrong.
Full LoadingScreen:
public class LoadingScreen implements Screen {
private static final float PROGRESS_BAR_WIDTH = MyGdxGame.WIDTH / 2f;
private static final float PROGRESS_BAR_HEIGHT = 50f;
GdxAssetManager assetManager;
Stage stage;
//Table mainTable;
private ShapeRenderer shapeRenderer;
private MyGdxGame game;
public LoadingScreen(MyGdxGame game){
this.game = game;
assetManager = game.getAssetManager();
shapeRenderer = new ShapeRenderer();
stage = new Stage(new StretchViewport(MyGdxGame.WIDTH, MyGdxGame.HEIGHT));
}
#Override
public void show() {
assetManager.loadGeneral();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderProgressBar();
if (assetManager.getManager().update()) {
game.setScreen(new LoginScreen(game));
}
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
private void renderProgressBar() {
float progress = assetManager.getManager().getProgress();
System.out.println(PROGRESS_BAR_WIDTH * progress);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.RED);
shapeRenderer.rect(
(MyGdxGame.WIDTH - PROGRESS_BAR_WIDTH) / 2f,
(MyGdxGame.HEIGHT - PROGRESS_BAR_HEIGHT) / 2f,
PROGRESS_BAR_WIDTH * progress,
PROGRESS_BAR_HEIGHT
);
shapeRenderer.end();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
stage.dispose();
shapeRenderer.dispose();
}
}
I guess methods of interest are render and renderProgressBar. Like I said, all I get is a white background until the loading is finished, but the print inside renderProgressBar prints the correct values.
Set projectionMatrix of ShapeRenderer using stage camera.
shapeRenderer.setProjectionMatrix(stage.getCamera().combined);
According to documentation the ExtendViewportshould extend the view and keep the aspect ratio, but whenever I try Implemented this viewPort Ive got two bars in the side of the phone screen. (this is sample background image,with some text and button on it to check how stretch will be).
Code:
public class Overlap2d extends Game {
public static float ASPECT_RATIO ;
public static final int GAME_SCREEN_WIDTH = 40;
public static final int GAME_SCREEN_HEIGHT = 80;
#Override
public void create () {
ASPECT_RATIO=(float)Gdx.graphics.getWidth()/(float)Gdx.graphics.getHeight() ;
ScreenManager.getScreenManager().init(this);
ScreenManager.getScreenManager().showScreen( ScreenName.MAIN_MENU );
}}
public abstract class AbstractScreen extends Stage implements Screen {
public AbstractScreen() {
super(new ExtendViewport(GAME_SCREEN_WIDTH,GAME_SCREEN_HEIGHT,new OrthographicCamera()));
}
public abstract void buildStage();
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 1, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
super.act(delta);
super.draw();
}
#Override
public void resize(int width, int height) {
getViewport().update(width,height);
}
#Override
public void show() {
Gdx.input.setInputProcessor(this);
}
#Override
public void resume() {}
#Override
public void pause() {}
#Override
public void hide() {}}
public class MenuScreen extends AbstractScreen{
private Texture txtrBg;
public MenuScreen() {
super();
txtrBg = new Texture( Gdx.files.internal("test.png") );
}
#Override
public void buildStage() {
getCamera().position.set(GAME_SCREEN_WIDTH / 2, GAME_SCREEN_HEIGHT / 2, 0);
Image bg = new Image(txtrBg);
bg.setSize(GAME_SCREEN_WIDTH,GAME_SCREEN_HEIGHT);
bg.setPosition(0,0);
addActor(bg);
}
#Override
public void dispose() {
super.dispose();
txtrBg.dispose();
}}
public static final int GAME_SCREEN_WIDTH = 40;
public static final int GAME_SCREEN_HEIGHT = 80;
you're using width and height ratio 1:2 but only very view device fits in this ratio so why don't you try 48 and 80 as viewport width and height.
Question is almost same so explanation can fit here also
https://stackoverflow.com/a/43398153/3445320
I am trying to override my Player class that extends Actor draw method but I am receiving an error saying
The method draw(SpriteBatch, float) of type Player must override or
implement a supertype method
Why can I not override the default draw method from the class Actor? Here is my code from the Player class.
public class Player extends Actor {
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
Gdx.app.log(getName(), "Drawing player");
}
public Player() {
setName("mainPlayer");
playerBounds = new Rectangle(100, 100, 32, 32);
}
}
Here is my code from the class with the Stage that is being drawn.
public class Mainscreen implements Screen {
// Class TAG
private static final String TAG = "Main Screen";
// Screen Variable(s)
private Awakening g;
private SpriteBatch sprBatch;
private OrthographicCamera gameCamera;
private Player mainPlayer;
// Screen Stage(s)
private sMain sMain;
#Override
public void dispose() {
sprBatch.dispose();
sMain.dispose();
}
#Override
public void hide() {
g.inputController.removeProcessor(sMain);
dispose();
}
public Mainscreen(Awakening game){
g = game;
sMain = new sMain(g, g.configMgr.getWidth(), g.configMgr.getHeight(), true);
gameCamera = new OrthographicCamera();
gameCamera.setToOrtho(false, sMain.getWidth(), sMain.getHeight());
mainPlayer = new Player(g, gameCamera);
g.setPlayer(mainPlayer);
sprBatch = new SpriteBatch();
g.mapMgr.setMap(g, gameCamera, "TestMap", mainPlayer);
sMain.addActor(mainPlayer);
}
#Override
public void pause() {g.togglePause(true);g.debugOut(TAG, "pause()");}
#Override
public void render(float delta) {
if(!g.isPaused()){
sMain.act(delta);
Gdx.gl.glClearColor(.125f, .125f, .125f, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gameCamera.update();
g.mapMgr.updateNPCS();
sprBatch.setProjectionMatrix(gameCamera.combined);
sprBatch.begin();
g.mapMgr.draw(gameCamera, new int[] {0,1});
sMain.draw(); // Draw player/NPCs
//g.getPlayer().draw(sprBatch, 0f);
g.mapMgr.drawCollisionRectangles(gameCamera);
sprBatch.end();
}
}
#Override
public void resize(int width, int height) {g.debugOut(TAG,"resize("+width+","+height+")");}
#Override
public void resume() {g.togglePause(false);g.debugOut(TAG, "resume()");}
#Override
public void show() {
g.debugOut(TAG, "show()");
g.inputController.addProcessor(sMain);
g.updateInput();
}
}
I am not sure what's going on but was pretty sure I could override draw before.
You must override it like this:
#Override
public void draw(Batch batch, float parentAlpha) {
Gdx.app.log(getName(), "Drawing player");
}
Change the SpriteBatch to Batch. Reference Actor#draw