Search code examples
androidopengl-eslibgdx

Limit touch area to Texture area in libgdx


I load textures and convert them to sprites. The image below shows how typical sprite looks like. The shapes varies from sprites to sprite. I wont to move these sprites when user touches just the surface area. Currently I am using rectangle bounds to detect if user touched it or not. This approach is not clean becuase the texture is not a rectangle. As a consequence users can drag it without precisely touching it. The question is how to create a touch area just to represent the texture area (that is non-transparent pixel area or exclude gray color area in the image below).

enter image description here


Solution

  • I would approach this with color picking. By first determining which pixel on the sprite is touched and then check if the touched pixel is transparent. With code taken from this question and altered a bit (not tested):

    Color pickedColor = null;
    Rectangle spriteBounds = sprite.getBoundingRectangle();
    if (spriteBounds.contains(Gdx.input.getX(), Gdx.input.getY())) {
        Texture texture = sprite.getTexture();
    
        int spriteLocalX = (int) (Gdx.input.getX() - sprite.getX());
        // we need to "invert" Y, because the screen coordinate origin is top-left
        int spriteLocalY = (int) ((Gdx.graphics.getHeight() - Gdx.input.getY()) - sprite.getY());
    
        int textureLocalX = sprite.getRegionX() + spriteLocalX;
        int textureLocalY = sprite.getRegionY() + spriteLocalY;
    
        if (!texture.getTextureData().isPrepared()) {
            texture.getTextureData().prepare();
        }
        Pixmap pixmap = texture.getTextureData().consumePixmap();
        pickedColor = new Color(pixmap.getPixel(textureLocalX, textureLocalY));
    }
    
    //Check for transparency
    if (pickedColor != null && pickedColor.a != 0) {
        //The picked pixel is not transparent, the nontransparent texture shape was touched
    }
    

    Have in mind this hasn't been tested and can probably be optimized.