libgdx - ShapeRenderer in Group.draw renders in wrong colour - java

MyGroup:
public class GShape extends Group{
private ShapeRenderer shape;
public GShape() {
super();
shape = new ShapeRenderer();
}
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
shape.begin(ShapeType.Line);
Gdx.gl10.glLineWidth(5);
shape.setColor(1, 1f, 1f, 1f);
shape.line(0, 0, 200, 100);
shape.end();
}
}
Main:
public class GameControl implements ApplicationListener {
private Stage stage;
private GShape gShape;
#Override
public void create() {
stage = new Stage(480,320,false);
Texture t = new Texture(Gdx.files.internal("data/the200.png"));
Image i = new Image(t);
stage.addActor(i);
gShape = new GShape();
stage.addActor(gShape);
}
#Override
public void dispose() {
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.draw();
// gShape.render();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
Colour of shape is not white? Why?
http://nw7.upanh.com/b3.s38.d3/352dd792eb77ce6df204a7af47ae1ac6_55348087.cos.jpg?rand=0.19125773780979216

You are probably getting inconsistent results because you're mixing SpriteBatch and ShapeRenderer contexts. Both of these expect state they "store" in OpenGL to be maintained between begin() and end() calls.
The Actor draw() method is called in a context where the SpriteBatch begin() has already been called, so you need to end it before beginning your ShapeRenderer. (And you need to restart the SpriteBatch before returning.
Like this:
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
batch.end(); // ** End the batch context
shape.begin(ShapeType.Line);
// .. draw lines ...
shape.end()
batch.begin(); // ** Restart SpriteBatch context that caller assumes is active
}

Related

Libgdx, button onclick event crashes

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.

LibGdx: Shaperenderer Rect not being drawn on Screen

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);

Can't center image scene2d

I'am trying to center my image, but I can't. I tryied everything with viewports and nothing. I won't want to use magic numbers to make the trick! it's possible that the default viewport is messing up?
here is my code:
public class LoadingScreen extends AbstractScreen{
private Stage stage;
private Texture texture;
private Image loading_image;
public LoadingScreen(XBallGame game ) {
super(game);
texture = TextureManager.SPLASH;
loading_image = new Image();
stage = new Stage();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0,0,0,1); //sets clear color to black
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //clear the batch
stage.act(delta);
stage.draw();
}
#Override
public void show() {
loading_image.addAction(Actions.sequence(Actions.alpha(0)
,Actions.fadeIn(0.5f),Actions.delay(2),Actions.run(new Runnable() {
#Override
public void run() {
System.out.println("DONE");
}
})));
stage.addActor(loading_image);
loading_image.setPosition(Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2);
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
}
}
UPDATE (Fixed the problem) :
Just added this line:
loading_image.setPosition((Gdx.graphics.getWidth()/2) - loading_image.getWidth()/2,
(Gdx.graphics.getHeight()/2) - loading_image.getHeight()/2);
and works fine!

LibGDX Actor draw override

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

libgdx with scene2d and actor is not displaying the sprite

I am testing out Libgdx and Scene2d. I expected this small program to display a logo, but it draws a black screen only. Any idea what am I missing?
public class MyGame implements ApplicationListener {
private Stage stage;
#Override
public void create() {
stage = new Stage(800, 800, false);
Gdx.input.setInputProcessor(stage);
MyActor actor = new MyActor();
stage.addActor(actor);
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public void resize(int width, int height) {
stage.setViewport(800, 800, false);
}
}
public class MyActor extends Actor {
Sprite sprite;
public MyActor() {
sprite = new Sprite();
sprite.setTexture(new Texture("data/libgdx.png"));
setWidth(sprite.getWidth());
setHeight(sprite.getHeight());
setBounds(0, 0, getWidth(), getHeight());
setTouchable(Touchable.enabled);
setX(0);
setY(0);
}
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
batch.draw(sprite, getX(), getY());
}
}
Construct the sprite with the texture and use Gdx.file.internal:
sprite = new Sprite(new Texture(Gdx.files.internal("data/libgdx.png")));
Anyway, if you just want to display and act on images, you might prefer to use Image class:
private Stage stage;
private Texture texture;
#Override
public void create() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
texture = new Texture(Gdx.files.internal("data/libgdx.png"));
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
com.badlogic.gdx.scenes.scene2d.ui.Image actor = new com.badlogic.gdx.scenes.scene2d.ui.Image(region);
stage.addActor(actor);
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
I was getting a black screen too until I explicitly set Actor's height (setHeight(height)) and width (setWidth(width)) to the Sprite's values.
tex = new Texture(Gdx.files.internal("happy.png"));
Image happy = new Image(tex);
/* happy.setBounds(happy.getX(), happy.getY(), happy.getWidth(), happy.getHeight()); not needed if using full image */
stage.addActor(happy);
Your problem is most likely this line, in the draw method
batch.draw(sprite, getX(), getY());
The code I have seen when drawing sprites is
sprite.draw(batch);

Categories