Изменение системы координат в LibGDX (Java)
LibGDX имеет систему координат, где (0,0) находится в левом нижнем углу. (например, это изображение: http://i.stack.imgur.com/jVrJ0.png)
Это я ударил головой о стену, главным образом потому, что я портирую игру, которую я уже сделал с обычной системой координат (где 0,0 находится в верхнем левом углу).
Мой вопрос: Есть ли простой способ изменения этой системы координат?
Ответы
Ответ 1
Если вы используете камеру (которую вы должны), изменение системы координат довольно просто:
camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Если вы используете TextureRegions и/или TextureAtlas, все, что вам нужно сделать в дополнение к этому, это call region.flip(false, true).
Причины, по которым мы используем y-up по умолчанию (которые вы можете легко изменить, как показано выше), следующие:
- ваш код моделирования, скорее всего, будет использовать стандартную систему координат евклидова с y-up
- Если вы идете в 3D, у вас есть y-up
- Система координат по умолчанию является правой рукой в OpenGL с y-up. Конечно, вы можете легко изменить это с помощью некоторой магии.
Единственными двумя местами в libgdx, где мы используем y-down, являются:
- Координаты пикселей (верхнее левое начало, y-down)
- Коснитесь событийных координат, которые указаны в координатах окна (верхнее левое начало, y-down)
Опять же, вы можете легко изменить используемую систему координат на все, что хотите, используя либо Камеру, либо крошечный бит математической математики.
Ответ 2
Просто чтобы немного рассказать о том, что сказал выше, если вы используете TextureAtlas (с TextureRegions), вам нужно перевернуть их, как сказал badlogic, в дополнение к работе с камерой. Если вы используете TextureAtlas, вы можете использовать этот код сразу после загрузки атласа:
String textureFile = "data/textures.txt";
atlas = new TextureAtlas(Gdx.files.internal(textureFile), Gdx.files.internal("data"));
// Let flip all the regions. Required for y=0 is TOP
Array<AtlasRegion> tr = atlas.getRegions();
for (int i = 0; i < tr.size; i++) {
TextureRegion t = tr.get(i);
t.flip(false, true);
}
Ответ 3
Если вы хотите скрыть преобразование и не думать об этом после его установки один раз, вы можете создать класс, который наследует все необходимые вам функции, но сначала преобразует координаты перед передачей его функции родительского класса. К сожалению, это займет много времени.
В качестве альтернативы вы можете сделать метод, который выполняет простое преобразование y' = height - y
всего объекта Coordinate
(или независимо от того, что вы используете) и вызывать его один раз перед каждой операцией.
Ответ 4
Интересная графическая библиотека, я бы сказал. Я нашел эту оценку по ссылке ниже:
Другая проблема заключалась в том, что в разных частях Libgdx использовались разные системы координат. Иногда происхождение осей происходило в нижний левый угол с осью y, направленной вверх, а иногда и в верхний левый угол спрайта направлен вниз. При рисовании Сетки происходили даже в центре экрана. Это вызвало довольно много путаницы и дополнительной работы, чтобы все в правильное место на экране.
http://www.csc.kth.se/utbildning/kandidatexjobb/datateknik/2011/rapport/ahmed_rakiv_OCH_aule_jonas_K11072.pdf
Ответ 5
Я просто создал класс, который расширяет SpriteBatch
, который переопределяет некоторые методы, добавляя y = Gdx.graphics.getHeight() - y - height
. Простой, но эффективный.
Ответ 6
Не уверен, что это помогает кому-то или нет, но я смог правильно обработать текстуры и шрифты, используя предложенную перевернутую систему координат через OrthographicCamera. Вот что я сделал:
private SpriteBatch batch;
private BitmapFont font;
private OrthographicCamera cam;
private Texture tex;
@Override
public void create () {
batch = new SpriteBatch();
font = new BitmapFont(true);
font.setColor(Color.WHITE);
cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
cam.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
tex = new Texture("badlogic.jpg");
}
@Override
public void dispose() {
batch.dispose();
font.dispose();
tex.dispose();
}
@Override
public void render () {
cam.update();
batch.setProjectionMatrix(cam.combined);
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
font.draw(batch, "Test", 50, 50);
batch.draw(tex, 100, 100, tex.getWidth(), tex.getHeight(), 0, 0, tex.getWidth(), tex.getHeight(), false, true);
batch.end();
}
Важно отметить:
- Конструктор BitmapFont, boolean переворачивает шрифт
- Для batch.draw() вам нужно использовать все эти параметры, потому что вам нужно булевое flipY в конце, чтобы перевернуть текстуру (я могу расширить SpriteBatch или сделать утилитный метод, чтобы не пропускать так много параметров все время.)
- Обратите внимание на пакет batch.setProjectionMatrix(cam.combined); в render()
Теперь мы увидим, вернусь ли я сюда позже, сделаю теперь изменения, чтобы исправить любые другие проблемы или открытия, выполнив все это.:)