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\$
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\$
  • \$\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\$ – user2582651 Jun 20 '16 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\$ – user2582651 Jun 20 '16 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\$ – user2582651 Jun 20 '16 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\$ – Joseph Wimer Jun 20 '16 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\$ – user2582651 Jun 20 '16 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.