10

I'm trying to make something like a slingshot using libGDX.

My code

if (Gdx.input.isTouched()) {

        ShapeRenderer sr = new ShapeRenderer();
        sr.setColor(Color.BLACK);
        sr.setProjectionMatrix(camera.combined);

        sr.begin(ShapeType.Line);
        sr.line(player.getLeft().x, player.getLeft().y,
                Global.game_touch_position.x, Global.game_touch_position.y);
        sr.line(player.getRight().x, player.getRight().y,
                Global.game_touch_position.x, Global.game_touch_position.y);
        sr.end();

    }

Doing this i will have the output enter image description here This looks awful, and if I debug on my android phone , the logcat is spammed by the message

02-17 18:55:27.371: D/dalvikvm(7440): GC_CONCURRENT freed 1884K, 40% free 8287K/13635K, paused 15ms+2ms, total 40ms

And lags, I have like 30 fps when i touch the screen , and 60 when i don't...

I also need to draw the line with a little bit of thickness, so when the line is bigger, i will have to make it thicker, to give a cool look.

Which is the best way to draw a simple line in libgdx ? If I won't find any answer probably i'm going to draw circles from a point of the line to the other..this would look ok , but won't look like a slingshot...

Any help?

Boldijar Paul
  • 5,405
  • 9
  • 46
  • 94
  • 3
    I guess you got spam because of creating instance of `ShapeRenderer` every frame rendering. Try create it once in constructor instead. – desertkun Feb 17 '14 at 17:20
  • But how should I draw the line with thinkness? – Boldijar Paul Feb 17 '14 at 17:25
  • Generally try to have a single question per post. SO is designed around that. Anyway, see http://stackoverflow.com/questions/16680908/libgdx-gl10-gllinewidth?rq=1 for the line thickness. – P.T. Feb 17 '14 at 19:40

3 Answers3

15

I just have something like this in a helper or utils class. I usually use it for debugging and visualizing whats going on.

private static ShapeRenderer debugRenderer = new ShapeRenderer();

    public static void DrawDebugLine(Vector2 start, Vector2 end, int lineWidth, Color color, Matrix4 projectionMatrix)
    {
        Gdx.gl.glLineWidth(lineWidth);
        debugRenderer.setProjectionMatrix(projectionMatrix);
        debugRenderer.begin(ShapeRenderer.ShapeType.Line);
        debugRenderer.setColor(color);
        debugRenderer.line(start, end);
        debugRenderer.end();
        Gdx.gl.glLineWidth(1);
    }

    public static void DrawDebugLine(Vector2 start, Vector2 end, Matrix4 projectionMatrix)
    {
        Gdx.gl.glLineWidth(2);
        debugRenderer.setProjectionMatrix(projectionMatrix);
        debugRenderer.begin(ShapeRenderer.ShapeType.Line);
        debugRenderer.setColor(Color.WHITE);
        debugRenderer.line(start, end);
        debugRenderer.end();
        Gdx.gl.glLineWidth(1);
    }

Now I can easily draw a line from anywhere I like on any projection matrix I want.

HelperClass.DrawDebugLine(new Vector2(0,0), new Vector2(100,100), camera.combined);

You want to draw outside the other SpriteBatch begin and end. And if you want to make a lot of lines each frame you are better off beginning and ending the ShapeRenderer in a separate static method or make it public and do it yourself depending on your needs.

Obviously you can create more methods for more shapes or more overloads.

Madmenyo
  • 8,389
  • 7
  • 52
  • 99
3

You could set line thickness by calling Gdx.gl10.glLineWidth(width_in_pixels).

desertkun
  • 1,027
  • 10
  • 19
1

ShapeRenderer has a method called rectLine() that draws a line with a specified thickness. It is exactly what you're looking for with your line thickness question. You will also want to change sr.begin(ShapeType.Line) to sr.begin(ShapeType.Filled)

if (Gdx.input.isTouched()) {

    ShapeRenderer sr = new ShapeRenderer();
    sr.setColor(Color.BLACK);
    sr.setProjectionMatrix(camera.combined);

    sr.begin(ShapeType.Filled);
    sr.rectLine(player.getLeft().x, player.getLeft().y,
            Global.game_touch_position.x, Global.game_touch_position.y, desired_thickness);
    sr.rectLine(player.getRight().x, player.getRight().y,
            Global.game_touch_position.x, Global.game_touch_position.y, desired_thickness);
    sr.end();

}
  • Haha , old question! Also that shaperenderer in the render method is very bad. – Boldijar Paul Oct 07 '14 at 14:53
  • Yes...a creating new objects in the render method is not the best thing for a game. And I was so excited that I actually knew exactly how to answer a question on SO that I couldn't resist. Even if the question is 10 months old... – Eric Christensen Oct 07 '14 at 17:21
  • I remember the feeling bro! :) – Boldijar Paul Oct 08 '14 at 03:59
  • Btw, i think your answer is wrong, shapetype.filled will draw any filled shapes like circles, rectangles, not lines, really, you can't fill a line. – Boldijar Paul Oct 08 '14 at 04:00
  • I'm using it in my game right now. I just compared line and filled. Filled is definitely what you want for ShapeRenderer.rectLine(). It works for ShapeRenderer.line() the same way that shaptype.line does but is probably much less efficient. – Eric Christensen Oct 09 '14 at 21:57