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