Java libGDX中奇怪的多批次定位

Java libGDX中奇怪的多批次定位,java,libgdx,Java,Libgdx,请原谅这个基本问题,我只是想了解一下LibGDX的本质 我正在创建一个径向条来显示我的倒计时计时器 我已经找到了一些代码,我需要它做什么,问题是径向精灵的定位。我似乎无法使它在图像对象中居中(因为它似乎忽略了图像的局部坐标,并且默认为舞台坐标),所以0,0将其放置在屏幕左下角附近 我尝试使用localtoStage,反之亦然,来计算正确的位置,但这似乎也没有给我正确的值 请告知 package com.goplayplay.klpoker.CSS.Classes; im

请原谅这个基本问题,我只是想了解一下LibGDX的本质

我正在创建一个径向条来显示我的倒计时计时器

我已经找到了一些代码,我需要它做什么,问题是径向精灵的定位。我似乎无法使它在图像对象中居中(因为它似乎忽略了图像的局部坐标,并且默认为舞台坐标),所以0,0将其放置在屏幕左下角附近

我尝试使用localtoStage,反之亦然,来计算正确的位置,但这似乎也没有给我正确的值

请告知

    package com.goplayplay.klpoker.CSS.Classes;

        import com.badlogic.gdx.graphics.g2d.*;
        import com.badlogic.gdx.math.EarClippingTriangulator;
        import com.badlogic.gdx.math.Intersector;
        import com.badlogic.gdx.math.Vector2;
        import com.badlogic.gdx.scenes.scene2d.ui.Image;
        import com.badlogic.gdx.utils.ShortArray;

    public class ProgressCircle extends Image {

        TextureRegion texture;
        PolygonSpriteBatch polyBatch;
        Vector2 center;
        Vector2 centerTop;
        Vector2 leftTop;
        Vector2 leftBottom;
        Vector2 rightBottom;
        Vector2 rightTop;
        Vector2 progressPoint;
        float[] fv;
        IntersectAt intersectAt;

    public ProgressCircle(TextureRegion region, PolygonSpriteBatch polyBatch) {
        super(region);

        this.texture = region;
        this.polyBatch = polyBatch;

        center = new Vector2(this.getWidth() / 2, this.getHeight() / 2);
        centerTop = new Vector2(this.getWidth() / 2, this.getHeight());
        leftTop = new Vector2(0, this.getHeight());
        leftBottom = new Vector2(0, 0);
        rightBottom = new Vector2(this.getWidth(), 0);
        rightTop = new Vector2(this.getWidth(), this.getHeight());
        progressPoint = new Vector2(this.getWidth() / 2, this.getHeight() / 2);

        setPercentage(0);
    }

    private Vector2 IntersectPoint(Vector2 line) {
        Vector2 v = new Vector2();
        boolean isIntersect;

        //check top
        isIntersect = Intersector.intersectSegments(leftTop, rightTop, center, line, v);

        //check bottom
        if (isIntersect) {
            intersectAt = IntersectAt.TOP;
            return v;
        } else isIntersect = Intersector.intersectSegments(leftBottom, rightBottom, center, line, v);

        //check left
        if (isIntersect) {
            intersectAt = IntersectAt.BOTTOM;
            return v;
        } else isIntersect = Intersector.intersectSegments(leftTop, leftBottom, center, line, v);

        //check bottom
        if (isIntersect) {
            intersectAt = IntersectAt.LEFT;
            return v;
        } else isIntersect = Intersector.intersectSegments(rightTop, rightBottom, center, line, v);

        if (isIntersect) {
            intersectAt = IntersectAt.RIGHT;
            return v;
        } else {
            intersectAt = IntersectAt.NONE;
            return null;
        }
    }

    public void setPercentage(float percent) {
        //100 % = 360 degree
        //==> percent % => (percent * 360 / 100) degree

        float angle = convertToRadians(90); //percent = 0 => angle = -90
        angle -= convertToRadians(percent * 360 / 100);

        float len = this.getWidth() > this.getHeight() ? this.getWidth() : this.getHeight();
        float dy = (float) (Math.sin(angle) * len);
        float dx = (float) (Math.cos(angle) * len);
        Vector2 line = new Vector2(center.x + dx, center.y + dy);

        Vector2 v = IntersectPoint(line);

        if (intersectAt == IntersectAt.TOP) {
            if (v.x >= this.getWidth() / 2) 
            {
                fv = new float[]{
                        center.x,
                        center.y,
                        centerTop.x,
                        centerTop.y,
                        leftTop.x,
                        leftTop.y,
                        leftBottom.x,
                        leftBottom.y,
                        rightBottom.x,
                        rightBottom.y,
                        rightTop.x,
                        rightTop.y,
                        v.x,
                        v.y
                };
            } else {
                fv = new float[]{ 
                        center.x,
                        center.y,
                        centerTop.x,
                        centerTop.y,
                        v.x,
                        v.y
                };

            }
        } else if (intersectAt == IntersectAt.BOTTOM) {
            fv = new float[]{
                    center.x,
                    center.y,
                    centerTop.x,
                    centerTop.y,
                    leftTop.x,
                    leftTop.y,
                    leftBottom.x,
                    leftBottom.y,
                    v.x,
                    v.y
            };

        } else if (intersectAt == IntersectAt.LEFT) {
            fv = new float[]{
                    center.x,
                    center.y,
                    centerTop.x,
                    centerTop.y,
                    leftTop.x,
                    leftTop.y,
                    v.x,
                    v.y
            };

        } else if (intersectAt == IntersectAt.RIGHT) {
            fv = new float[]{
                    center.x,
                    center.y,
                    centerTop.x,
                    centerTop.y,
                    leftTop.x,
                    leftTop.y,
                    leftBottom.x,
                    leftBottom.y,
                    rightBottom.x,
                    rightBottom.y,
                    v.x,
                    v.y
            };

        } else // if (intersectAt == IntersectAt.NONE)
        {
            fv = null;
        }


    }

    //
    @Override
    public void draw(Batch batch, float parentAlpha) {
        //      super.draw(batch, parentAlpha);

        if (fv == null) return;

        batch.end();
        drawMe();
        batch.begin();



    }

    public void drawMe() {

        Vector2 acc = new Vector2();
        acc.set(getWidth() / 2, getHeight() / 2);
        localToStageCoordinates(acc);
        EarClippingTriangulator e = new EarClippingTriangulator();
        ShortArray sv = e.computeTriangles(fv);

        PolygonRegion polyReg = new PolygonRegion(texture, fv, sv.toArray());

        PolygonSprite poly = new PolygonSprite(polyReg);

        poly.setOrigin(this.getOriginX(), this.getOriginY());
        poly.setPosition(this.getX(), this.getY());
        //        poly.setPosition(acc.x, acc.y); //Attempting to calculate correct positioning - Doesnt work
        poly.setRotation(this.getRotation());
        poly.setColor(this.getColor());

        polyBatch.begin();
        poly.draw(polyBatch);
        polyBatch.end();


    }

    float convertToDegrees(float angleInRadians) {
        float angleInDegrees = angleInRadians * 57.2957795f;
        return angleInDegrees;
    }


        //-----------------------------------------------------------------

    float convertToRadians(float angleInDegrees) {
        float angleInRadians = angleInDegrees * 0.0174532925f;
        return angleInRadians;
    }

    public enum IntersectAt {
        NONE, TOP, BOTTOM, LEFT, RIGHT
    }


}

您忘记在多边形批次上设置摄影机的投影矩阵。您可以从传入的批次中获取副本:

public void draw(Batch batch, float parentAlpha) {
    //      super.draw(batch, parentAlpha);

    if (fv == null) return;

    batch.end();
    drawMe(batch.getProjectionMatrix());
    batch.begin();
}

public void drawMe(Matrix4 projection) {
    polyBatch.setProjectionMatrix(projection);
    //...
}
或者更简单地说,您可以使用PolygonBatch作为阶段的批次,这样您就不必交换批次:

stage = new Stage(myViewport, new PolygonBatch());

//...

public void draw(Batch batch, float parentAlpha) {
    //      super.draw(batch, parentAlpha);

    if (fv == null) return;
    //don't need to call begin and end on the batch
    drawMe((PolygonBatch)batch); 
}

public void drawMe(PolygonBatch polyBatch) {
    //...
    //don't need to call begin or end on the batch
}

顺便说一句,您的
drawMe
方法实例化了很多对象,有些是大型对象。如果你有超过几个演员做这件事,你应该避免这样做,否则你会因为GC而口吃。尝试在构造函数中仅实例化一次对象并重用它们。

您忘记在多边形批处理上设置摄影机的投影矩阵。您可以从传入的批次中获取副本:

public void draw(Batch batch, float parentAlpha) {
    //      super.draw(batch, parentAlpha);

    if (fv == null) return;

    batch.end();
    drawMe(batch.getProjectionMatrix());
    batch.begin();
}

public void drawMe(Matrix4 projection) {
    polyBatch.setProjectionMatrix(projection);
    //...
}
或者更简单地说,您可以使用PolygonBatch作为阶段的批次,这样您就不必交换批次:

stage = new Stage(myViewport, new PolygonBatch());

//...

public void draw(Batch batch, float parentAlpha) {
    //      super.draw(batch, parentAlpha);

    if (fv == null) return;
    //don't need to call begin and end on the batch
    drawMe((PolygonBatch)batch); 
}

public void drawMe(PolygonBatch polyBatch) {
    //...
    //don't need to call begin or end on the batch
}
顺便说一句,您的
drawMe
方法实例化了很多对象,有些是大型对象。如果你有超过几个演员做这件事,你应该避免这样做,否则你会因为GC而口吃。尝试在构造函数中只实例化一次对象并重用它们