Search code examples
android-studiokotlinlibgdxbox2d

Attach sprite to Bullet - Box2D LibGDX kotlin


I'm following some tutorials to be able to implement the parabolic motion. In debug everything works correctly, the parabolic motion responds correctly and the result works. Now I would like to insert a Sprite, and here my problems begin. In fact, the sprite perfectly performs the rotations of the object that is carrying out the parabolic motion but it absolutely does not follow the X and Y coordinates. thank you in advance:

Bullet function:

private fun createBullet() {
    val circleShape = CircleShape()
    circleShape.radius = 0.5f
    circleShape.position = Vector2(convertUnitsToMeters(firingPosition.x), convertUnitsToMeters(firingPosition.y))
    val bd = BodyDef()
    bd.type = BodyDef.BodyType.DynamicBody
    bullet = world!!.createBody(bd)
    bullet!!.createFixture(circleShape, 1f)
    circleShape.dispose()
    val velX = abs(MAX_STRENGTH * -MathUtils.cos(angle) * (distance / 100f))
    val velY = abs(MAX_STRENGTH * -MathUtils.sin(angle) * (distance / 100f))
    bullet!!.setLinearVelocity(velX, velY)
}

How I'm trying to create sprite:

override fun render(delta: Float) {
    sprite.setPosition(bullet!!.position.x - sprite.width / 2,
            bullet!!.position.y - sprite.height / 2)
    sprite.rotation = Math.toDegrees(bullet!!.angle.toDouble()).toFloat()

    batch!!.use {
        it.draw(sprite, sprite.x, sprite.y, sprite.originX,
                sprite.originY,
                sprite.width, sprite.height, sprite.scaleX, sprite.scaleY, sprite.rotation)
    }
}

Solution

  • This is an incorrect way to use the Sprite class. There is an unfortunate design decision in libGDX that Sprite is a subclass of TextureRegion, which allows you you pass it to SpriteBatch.draw() as if it is a TextureRegion. When you do this, it ignores all of the settings on the Sprite.

    If you use the Sprite class, you must use Sprite.draw() instead of SpriteBatch.draw().

    In my opinion, you should not use the Sprite class at all. You should write your own game object class that has the exact parameters you need and maybe keeps a reference to a TextureRegion. Then when you draw it using SpriteBatch.draw, you pass all the relevant data for position, rotation, etc. Then you are not having to keep redundant copies of your box2d body data in sync.