3
\$\begingroup\$

Question : In the following snippet, I wish to draw different shapes such as rectangles, circles, triangles etc. I will be creating different class files for each of such objects, as I did for Rectangle class here.

I've been trying to invoke the draw method of Rectangle object from Stage object, but I am unable to do so. If I make a plain call to the draw method of the Rectangle object, I can draw the object.

Can some one suggest me how is this possible ? Also, I had many other queries which I'd tried to put in comments. Please have a look at them and kindly help me in figuring out the concept beneath it.

Disclaimer : I am new to game programming, started with Libgdx.

Following is the Scan class :

package com.mygdx.scan.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.scenes.scene2d.Stage;

public class Scan extends ApplicationAdapter {
private Stage stage;
public static ShapeRenderer shapeRenderer;

@Override
public void create () {
    stage = new Stage();
    shapeRenderer = new ShapeRenderer();
    Rectangle rect1 = new Rectangle(50, 50, 100, 100);
    stage.addActor(rect1);

}

@Override
public void render () {
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    shapeRenderer.setProjectionMatrix(stage.getCamera().combined);
    shapeRenderer.begin(ShapeType.Filled);
    shapeRenderer.setColor(Color.BLACK);
    //new Rectangle(50, 50, 100, 100).draw();
    shapeRenderer.end();
    // This should call Rectangles draw method. I want a Shapetype.Filled Rectangle. 
    // But I'm unable to invoke this method if I add the actor in stage object and invoke it's draw method. 
    stage.draw(); 
}

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

Following is the Rectangle Actor class :

package com.mygdx.scan.game;

import com.badlogic.gdx.scenes.scene2d.Actor;

public class Rectangle extends Actor {

float xcord, ycord, width, height;
public Rectangle(float x , float y , float width, float height) {
    this.xcord = x;
    this.ycord = y;
    this.width = width;
    this.height = height;
}

// This needs to be called in the Scan class. I just want the draw       method to be invoked. 
// Also I wish to draw many such rectangles. What is the best practice to get hold of ShapeRenderer object from Scan class ?
// Should I use one instance of  ShapeRenderer object in Scan class or should I create ShapeRenderer object for each of the Rectangle object ??
// I also plan to repeat the activity for another object such as circles. So I would like to know the best practice here.
public void draw() {
    Scan.shapeRenderer.rect(this.xcord, this.ycord, this.width, this.height);
}

}

\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

You should use your ShapeRenderer as an input into your draw function.

// The shapeRenderer as input
public void draw (ShapeRenderer renderer) {
     renderer.set(ShapeType.Filled);
     renderer.drawRect(this.xcord, this.ycord, this.width, this.height);
}

Taking the ShapeRenderer as input also allows you to iterate over a list of rectangles to draw your rectangles. I personally prefer 'for : in' loops, but anything but a while loop will work (while loops will crash your game).

for( Rectangle rect : rectangles) {
    rect.draw(shapeRenderer);
}
// always end when you finish renderering! 
shapeRenderer.end();

Lastly, I recommend that you put this before you begin your ShapeRenderer.

 shapeRenderer.setAutoShapeType(true);

This will make the ShapeRenderer swap to a workable ShapeType for you (automatically) if it can't draw with the current ShapeType.

Edit: Reread your question, and I didn't answer it perfectly. Stages have their own batches, which means if you want to render your rectangles (or anything) using them, they need to have sprites (or some image/texture), as batches can't draw the basic shapes. (Rectangle, circle, ellipses).

\$\endgroup\$
6
  • \$\begingroup\$ Thanks for the input. Yes, I am interested to know how stage handles drawing of basic shapes(Rectangles, circle) etc where shaperenderer is also involved. I couldn't find the solution, and I am still waiting. \$\endgroup\$ Commented Jun 20, 2016 at 4:51
  • \$\begingroup\$ Adding a post again, since I couldn't edit my previous comment. I wish to use stage because I want to handle click events on these rectangles and scene2d makes my job easier relatively. Else I'd be handling click events for each of the shape objects. \$\endgroup\$ Commented Jun 20, 2016 at 5:06
  • \$\begingroup\$ I read the libgdx docs : github.com/libgdx/libgdx/wiki/Scene2d and changed my code ( Section for Drawing) . However, the rectangle is still not drawn. \$\endgroup\$ Commented Jun 20, 2016 at 11:13
  • \$\begingroup\$ Did you update your code in the question? It doesn't appear to have changed. If you want to use Stage to render the shapes, you should make Sprites for the rectangles/triangles/circles and use the Stage's batch to draw those. (Batches cannot draw basic shapes, only sprites or textures). \$\endgroup\$ Commented Jun 20, 2016 at 15:33
  • \$\begingroup\$ No I didn't . But rest assured, i've followed what was mentioned in the wiki page. I still couldn't get it working. \$\endgroup\$ Commented Jun 20, 2016 at 15:41
0
\$\begingroup\$

Try moving shapeRenderer.end() to after stage.draw(). You must not draw anything using the shape renderer after it has been ended.

Alternatively also try doing stage.act() before stage.draw() in addition to the above. Not sure what that would fix but it's a possibility.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .