LibGDX реализует OpenGL.Терминология, которую мы используем в OpenGL, может помочь нам узнать, как LibGDX работает за кулисами.Другая технология, которая реализует OpenGL - это WebGL, WebGL использует JavaScript.LibGDX использует Java.Как только мы узнаем, как работает OpenGL, рисовать объекты и вращающиеся объекты должно быть весело.Конечно, в зависимости от того, что мы рисуем.OpenGL хорошо документирован.Сам OpenGL всегда работает одинаково.Первый вопрос, должно быть, что мы рисуем?И каковы цели проекта.Итак, вы хотите нарисовать куб и вращать его.Здорово.Как только мы можем нарисовать один куб и повернуть его, мы можем добавить больше объектов в сцену.Здорово.Стратегически вы можете разделить ваш проект на части.
- Нарисуйте свой объект.
- Поверните его.
- Добавьте больше объектов.
- Поверните их.
- Мы закончили.
Если вы также хотите повернуть вид, вы можете использовать тот же процесс, что и выше, с некоторыми изменениями.Например:
- Нарисуйте вид.
- Нарисуйте объекты внутри вида.
- Поверните объекты.
- Поверните вид.
- С другой стороны, вы можете просто использовать камеру и перемещать ее по сцене.
- Готово.
Что еще хуже, LibGDX может расширять множество различных классов,Программист должен реализовать все абстрактные методы.Ваш код может выглядеть по-разному, или некоторые функции ведут себя по-разному, в зависимости от того, какой класс вы расширяете или реализуете в своем проекте.Документация об этих классах является стохастической.Каждый абстрактный класс поставляется со своими абстрактными методами.Программист должен освободить любые другие ресурсы, выделенные LibGDX, используя метод dispose ().С помощью всего лишь нескольких изменений ваш код должен работать должным образом.
Например:
//
package com.mygdx.game;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
//import etc...
public class Space extends ApplicationAdapter implements ApplicationListener, InputProcessor {
SpriteBatch batch;
BitmapFont font;
float backgroundColor[];
Cube cubes[];
ModelBatch modelBatch;
int selectedCube;
PerspectiveCamera camera;
Environment environment;
int xCubes = 27;
int touchedButton;
int lastX, lastY;
float Theta, Phi, dX, dY;
Vector3 screenAOR;
float screenAng;
float point[];
int side[];
int front[];
float w;
float h;
Model viewM;
ModelInstance viewMin;
Vector3 position;
ColorAttribute attrib;
Vector3 cubePositions[];
boolean drag;
@Override
public void create () {
drag = false;
Theta = 0;
Phi = 0;
batch = new SpriteBatch();
font = new BitmapFont();
font.setColor(Color.FOREST);
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
modelBatch = new ModelBatch();
screenAOR = new Vector3();
camera = new PerspectiveCamera(67f, 3f, 2f);
camera.position.set(10f, -10f, 70f);
camera.lookAt(Vector3.Zero);
camera.up.set(Vector3.Y);
camera.near = 1f;
camera.far = 500f;
camera.update();
backgroundColor = new float[]{.9f, .9f, .7f};
environment = new Environment();
environment.set(new ColorAttribute( ColorAttribute.AmbientLight, .6f, .6f, .6f, 1f));
environment.add(new DirectionalLight().set(.8f, .8f, .8f, 50f, 50f, 50f));
environment.add(new DirectionalLight().set(.5f, .5f, .5f, -50f, -50f, 50f));
spaceModel();
Gdx.input.setInputProcessor(this);
//Gdx.graphics.requestRendering();
}
@Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
//Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//Gdx.gl.glClearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL20.GL_CULL_FACE);
batch.begin();
modelBatch.begin(camera);
modelBatch.render(viewMin, environment);
for(int i = 0; i < cubes.length; i++){
modelBatch.render(cubes[i].modelInstance, environment);
}
font.draw(batch, "Space pro...", 10, 100);
batch.end();
modelBatch.end();
}
@Override
public void dispose () {
batch.dispose();
modelBatch.dispose();
font.dispose();
viewM.dispose();
}
/*///////////////////////////////////
//Implements all abstract methods.
//
*/////////////////////////////////
@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
//lastX -= screenX;
//lastY -= screenY;
//float aspRatio = w/h;
//float angle = 40.0f;
moveModel(screenX, screenY);
// distance of mouse movement
//screenAng = (float) Math.sqrt( ((lastX * lastX) + (lastY * lastY)) );
//screenAng = (float) Math.tan((angle * 0.5)* (Math.PI/180));
// direction vector of the AOR
//screenAOR.set((lastY/screenAng), (lastX/screenAng), 0f );
//screenAOR.set(projection(angle,aspRatio,h,w));
//public Vector3 set(float x, float y, float z)
screenAOR.set(dX, dY, 0f);
if ( touchedButton == 0 ){
//public Matrix4 rotate(Vector3 axis, float degrees)
//cubes[ selectedCube ].modelInstance.transform.rotate( screenAOR, screenAng );
//public Matrix4 rotate(float axisX, float axisY, float axisZ, float degrees)
cubes[ selectedCube ].modelInstance.transform.rotate(dX, dY, 0f, Theta);
cubes[ selectedCube ].modelInstance.transform.rotate(dX, dY, 0f, Phi);
}
else{
//public void rotateAround(Vector3 point, Vector3 axis, float angle)
//camera.rotateAround( Vector3.Zero, screenAOR, (-screenAng/5.5f) );
//public void rotate(float angle, float axisX, float axisY, float axisZ)
//camera.rotate(Theta, dX, dY, 0f);
//camera.rotate(Phi, dX, dY, 0f);
//camera.rotateAround(position, screenAOR, Theta);
camera.rotateAround(Vector3.Zero, screenAOR, Theta);
camera.update();
//camera.rotateAround(position, screenAOR, Phi);
camera.rotateAround(Vector3.Zero, screenAOR, Phi);
camera.update();
viewMin.transform.rotate(dX, dY, 0f, Theta);
viewMin.transform.rotate(dX, dY, 0f, Phi);
}
//Gdx.graphics.requestRendering();
//Gdx.app.log("touchDragged:", screenAng+" : "+screenAOR+" : "+touchedButton);
return true;
}
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
drag = true;
if(button == Buttons.LEFT){
touchedButton = 0;
}
else{
touchedButton = button;
}
Gdx.app.log("touchDown:", button+" : "+screenX+" : "+screenY+" : "+pointer);
return true;
}
@Override
public boolean keyDown(int i) {
float move = 1.0f;
float pX = w/10;
float pY = h/10;
if(i == Keys.LEFT){
pX -= move;
//public void rotate(float angle, float axisX, float axisY, float axisZ)
//camera.rotate(-45, pX, 0f, 0f);
camera.rotate(-45, 0f, pY, 0f);
//camera.update();
//public void translate(float x, float y, float z)
//camera.translate(move, 0f, 0f);
}
if(i == Keys.RIGHT){
pX += move;
//camera.rotate(45, pX, 0f, 0f);
camera.rotate(45, 0f, pY, 0f);
//camera.update();
//camera.translate(-move, 0f, 0f);
}
if(i == Keys.DOWN){
pY -= move;
//camera.rotate(-45, 0f, pY, 0f);
//camera.rotate(-45, pX, 0f, 0f);
camera.rotate(45, pX, 0f, 0f);
//camera.update();
//camera.translate(0f, 0f, move);
//camera.update();
//camera.translate(0f, move, 0f);
}
if(i == Keys.UP){
pY += move;
//camera.rotate(45, 0f, pY, 0f);
//camera.rotate(45, pX, 0f, 0f);
camera.rotate(-45, pX, 0f, 0f);
//camera.update();
//camera.translate(0f, 0f, -move);
//camera.update();
//camera.translate(0f, -move, 0f);
}
camera.update();
Gdx.app.log("KeyDown: ", pX+" : "+pY+" : "+i);
return true;
}
@Override
public boolean keyUp(int i) {
Gdx.app.log("KeyUp: ",i+" : ");
return false;
}
@Override
public boolean keyTyped(char c) {
//Gdx.app.log("KeyTyped: ",c+" : ");
return false;
}
@Override
public boolean touchUp(int i, int i1, int i2, int i3) {
drag = false;
Gdx.app.log("touchUp: ",i+" : "+i1+" : "+i2+" : "+i3);
return true;
}
@Override
public boolean mouseMoved(int i, int i1) {
if(!drag)
{
dX *= 0.96;
dY *= 0.96;
Theta += dX;
Phi += dY;
return false;
}
Gdx.app.log("mouseMoved: ", i+" : "+i1);
return false;
}
@Override
public boolean scrolled(int i) {
return false;
}
public void moveModel(int x2, int y2){
dX = (float) ((x2 - lastX)*2*(Math.PI/w));
dY = (float) ((y2 - lastY)*2*(Math.PI/h));
Theta += dX;
Phi += dY;
lastX = x2;
lastY = y2;
}
public void spaceModel(){
xCubes = 27;
selectedCube = 14;
ModelBuilder modelB = new ModelBuilder();
attrib = new ColorAttribute(1,Color.VIOLET);
Material m = new Material();
m.set(attrib);
//public Model createXYZCoordinates(float axisLength, Material material, long attributes)
viewM = modelB.createXYZCoordinates(w, m , 1);
cubePositions = new Vector3[xCubes];
for(int i = 0; i < xCubes; i++){
cubePositions[i] = new Vector3((i/9), ((i%9)/3), (i%3)).scl(20f).add(-20f, -20f, -20f);
}
cubes = new Cube[xCubes];
for(int i = 0; i < xCubes; i++){
cubes[i] = new Cube(cubePositions[i], (i == selectedCube));
}
viewMin = new ModelInstance(viewM);
position = cubePositions[0];
viewMin.transform.setTranslation(position);
Gdx.app.log("viewModel: ", w+" : "+h+" : "+w/h);
}
float[] projection(float angle, float a, float z1, float z2){
float ang = (float) Math.tan((angle * 0.5)* (Math.PI/180));
float[] proj = {
(float)0.5/ang, 0, 0, 0,
0, (float)0.5*a/ang, 0, 0,
0, 0, -(z2+z1)/(z2-z1), -1,
0, 0, (-2*z2*z1)/(z2-z1), 0
};
return proj;
}
}
/*////////////////////
//Draw cubes.
//
*/////////////////
class Cube{
Vector3 position;
Model model;
ModelInstance modelInstance;
Cube(Vector3 cubePosition, boolean selected) {
position = cubePosition;
compose(selected);
}
//etc...
}
//
При вращении камеры и вращении объектов направление может изменяться или иногда изменяться.В зависимости от того, под каким углом находятся объект и камера в данный момент времени.Это как смотреть на обзорное зеркало в противоположном направлении.Поэтому положение и ориентация пользователя на сцене также важны.
//
//
Когдавы смотрите на объект, вращающийся «<---» по кругу, логически он будет менять направление «--->».Когда он достигает дальнего конца «<--->».т.е. справа налево и слева направо.Конечно, пользователь все еще будет использовать ту же кнопку.При нажатии других кнопок следует та же логика.Различные последовательности поворотов также могут приводить к разным изображениям.Другой вариант, который требует много времени: перевести (повернуть (масштаб (геометрия))).В конце концов, все изображение будет единым целым, состоящим из разных частей.Этот процесс мог бы помочь вам отладить ваш код и выяснить, что вызвало ошибки.С небольшим количеством математики хуже не может быть.Наука, стоящая за объектом, который вы вращаете, также важна.Когда вы смотрите на вращающийся объект, красота находится на глазах у наблюдателей.Например, вы смотрите на лицевую или оборотную сторону?Наконец, вы должны использовать математику, чтобы заставить вашу модель вести себя так, как вы хотите.
Наслаждайтесь.