libgdx中的SpriteBatch根据纹理的原点绘制失败

4
我正在绘制一组精灵,当缩放比例较小时使用较小的纹理(4x4),当放大时则使用较大的纹理(16x16)。当缩放级别达到临界值时进行交换。然而,为了使过渡平稳,精灵(位于[x,y])需要以它们的中心作为原点进行绘制。目前,它们是基于左下角进行绘制的。因此,当纹理交换发生时,精灵会稍微跳动,因为原点不匹配。
我创建了一些变量来调试并确保它们是正确的。
    TextureRegion sprite = null;

    boolean useHighResTexture = (_gameRef.cameraZoom < CAMERA_ZOOM_SWITCH_LO_RES);
    if (useHighResTexture) {
        //Zoomed in, Hi res, Use animation
        sprite = animation.getKeyFrame(animationStateTime, true);

    } else {
        //Zoomed out, lo-res, Use static image
        sprite = Assets.instance.getSmall();
    }


    float spriteWidth = sprite.getRegionWidth();
    float spriteHeight = sprite.getRegionHeight();
    float spriteOriginX = spriteWidth/2;
    float spriteOriginY = spriteHeight/2;

    //Draw(TEXTURE, x, y, originx, originy, 
    //      width, height, scaleX, scaleY, rotation, 
    //      srcX, srcY, 
    //      srcWidth, srcHeight, boolflipX, boolflipY

    //this.setCenter(spriteOriginX, spriteOriginY);

    batch.draw(sprite.getTexture(), this.x, this.y, spriteOriginX, spriteOriginY, 
            spriteWidth, spriteHeight, 1.0f, 1.0f, this.directionFaced, 
            sprite.getRegionX(), sprite.getRegionY(),
            sprite.getRegionWidth(), sprite.getRegionHeight(), false, false);

您可以看到,我正在使用AssetsManager,在缩小版本(4x4)上使用静态图像,在放大版本(16x16)上使用动画效果。
变量spriteWidth、spriteHeight在缩小或放大时都为正确值(分别为4和16)。
变量spriteOriginX和spriteOriginY也是正确的,分别为8和2,取决于是缩小还是放大。
根据设定的原点(从左下角偏移),我原本认为它会基于该原点绘制精灵。
请问batch.draw()中的调用是否正确?
非常感谢, J
1个回答

8
不,这是不正确的。 draw() 总是使用左下角作为位置。原点仅用于缩放和旋转。
因此,对于您来说,这意味着您必须从您的位置中减去原点:
batch.draw(sprite.getTexture(), this.x - spriteOriginX, this.y - spriteOriginY,
    spriteOriginX, spriteOriginY, spriteWidth, spriteHeight, 1.0f, 1.0f,
    this.directionFaced, sprite.getRegionX(), sprite.getRegionY(),
    sprite.getRegionWidth(), sprite.getRegionHeight(), false, false
);

通过这样做,你只需将左下角(即位置)向左下方推动一半的宽度和一半的高度,以便你的位置真正定义了精灵的中心点。
再次强调:原点仅用于旋转和缩放。如果您在draw()方法中设置旋转,则会围绕原点旋转(在您的情况下为中心点)。

非常感谢,完美运作。顺便问一下,您是否知道一种不仅简单地切换纹理,而且能够实现平滑过渡的好/标准方法? - Jammo
我认为这个改变并不是真的必要。在你的情况下,也许是因为“动画”,只有当你放大时才会播放,否则它将不可见。但即使在这里,我也不确定它是否必要,我不认为有很大的性能提升。我建议尝试使用“TextureFilter”。它们描述了如何计算像素的颜色,如果1个纹理像素(纹理的像素)不是屏幕上的一个像素。有两种情况:缩小:1个纹理像素小于1个像素(如果您缩小),放大:1个纹理像素大于1个像素(您放大)。但那是另一回事了。 - Robert P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接