2
\$\begingroup\$

Hello I just started to use LibGDX, and it's awesome. I looked at the Box2DLights library, and started to learn how the lighting work here.

I got something up:

img
(source: gyazo.com)

As you can see, it works, but the shadow of the sprite goes over itself, and doesn't start in the right place.

Why is it doing this? is it possible to set offsets?

This is how I initialize them:

    this.texture = new Texture("sprites/water.png");
    this.camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    this.camera.setToOrtho(false);
    this.renderer = new SpriteBatch();

    this.map = new TileMap(20, 20);
    this.map.generateAllSame(new Texture("sprites/sprite.png"));     

    this.world = new World(new Vector2(), true);

    this.createBodies();

    RayHandler.setGammaCorrection(true);
    RayHandler.useDiffuseLight(true);
    this.ray = new RayHandler(this.world);
    this.ray.setAmbientLight(0.2f, 0.2f, 0.2f, 0.1f);
    this.ray.setCulling(true);
    this.ray.pointAtLight(50, 0);
    this.ray.setBlurNum(1);
    camera.update(true);
    this.spriteLight = new PointLight(ray, 128);
    this.spriteLight.setDistance(500f);
    this.spriteLight.setPosition(150, 150);

    this.spriteLight.setColor(new Color(0.5f, 0.8f, 0.7f, 1f)); 
    this.spriteLight.setSoftnessLength(0);
    this.spriteLight.setSoft(true);


public void createBodies() {
    CircleShape chain = new CircleShape();
    chain.setRadius(10);

    FixtureDef def = new FixtureDef();
    def.restitution = 0.8f;
    def.friction = 0.01f;
    def.shape = chain;
    def.density = 1f;


    BodyDef body = new BodyDef();
    body.type = BodyType.DynamicBody;

    for (int i = 0; i < 3; i++) {
        body.position.x = 40 + MathUtils.random(500);
        body.position.y = 40 + MathUtils.random(500);

        Body box = this.world.createBody(body);
        box.createFixture(def);
        this.bodies.add(box);
    }
    chain.dispose();
}

And my rendering:

public void render() {
    handleInput();
    camera.update();
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    renderer.setProjectionMatrix(camera.combined);

    renderer.disableBlending();
    renderer.begin();
    this.map.render(renderer);
    renderer.draw(texture, 50, 50);

    renderer.enableBlending();

    for (Body body : this.bodies) {
        Vector2 pos = body.getPosition();
        renderer.draw(texture, pos.x + amount, pos.y);
    }
    renderer.end();

    ray.setCombinedMatrix(camera.combined, camera.position.x, camera.position.y, 
            camera.viewportWidth * camera.zoom, camera.viewportHeight * camera.zoom);

    ray.update();
    ray.render();


}

What did I do wrong?

\$\endgroup\$
5
\$\begingroup\$

This is less a problem with Box2dLights, and more a problem with setting up Box2d collision fixtures to match your sprites.

The Box2dLight rays are colliding with the CircleShape fixture you attached to the box2d body.

CircleShape chain = new CircleShape();
chain.setRadius(10);

Instead, this should be a Polygon shape with the same dimensions as your box, like this:

PolygonShape shape = new PolygonShape();
shape.setAsBox(width/2, height/2);

It also looks like your sprite has some transparent space surrounding it. The center point of your circle fixture is not matching up with the bottom left of your sprite. I would either modify the picture file or add an offset to the fixture so it matches.

You should also convert your pixel coordinates to something smaller for Box2d. Right now your circle shape has a radius of 10 meters. Box2d is not built to simulate very large or very small objects. 10 meters is within the tolerance, but if you go over 50 meters box2d can have undefined behavior. Check out the http://www.box2d.org/manual.html section 1.7 Units for more information.

\$\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.