LibGdx Как прокручивать с помощью OrthographicCamera?

enter image description here

Я проваливаюсь в течение 10 часов (буквально), и я закончил, мне нужно спросить. Дело в том, что я учусь, как использовать LibGdx для программирования Java-игр. Я играю в Горизонтальный космический корабль. Итак, моя худшая проблема в том, что я не знаю, как сделать прокрутку (думаю, ничья объяснит лучше). Я хочу нарисовать фон hudge (Space) и сделать так, чтобы моя OrthographicCamera двигалась вправо, как с моим SpaceShip, так что это создаст эффект прокрутки с помощью Space Background. Никаких врагов и ничего кроме корабля на экране.

Я пытаюсь это

 public void moveCamera(float x,float y){
    cam.position.set(x, y, 0);
 }

Затем я использую этот метод в моем методе визуализации WorldRender:

public void render(float delta){ 
    ship.Move(delta);
    moveCamera(ship.getPosition().x,ship.getPosition().y);
    cam.update();
    System.out.println(""+cam.position);
    spriteBatch.begin();
        drawBackground();
        drawShip();
    spriteBatch.end();
}

Я на самом деле перемещаю положение камеры (я вижу это благодаря печати), но в игре она не двигается, поэтому SpaceShip просто исчезает у края окна.

Я также попробовал это до spriteBatch.end()

spriteBatch.setProjectionMatrix(camera.combined);

но когда я делаю это, Windows oly показывает черный экран, нет корабля, нет ничего. Как я уже сказал, я в отчаянии, я вижу много примеров (прокрутка мышью, паралэкскроллинг и т.д.), Но все они продвинуты или не имеют ничего общего с моим кодом. Любая помощь будет оценена

Вот как я рисую вещи. Фон и корабль - это текстуры внутри WorldRender. Я рисую фоновое изображение очень широко, поэтому я собираюсь прокрутить, как я уже сказал. Что код

private void loadTextures(){
    shipTexture=new Texture(Gdx.files.internal("nave.png"));
    background=new Texture(Gdx.files.internal("fondo.jpg"));
}

public void drawShip(){
    spriteBatch.draw(shipTexture,ship.getPosition().x*ppuX,ship.getPosition().y*ppuY, ship.WIDTH*ppuX,ship.HEIGHT*ppuY);
}

public void drawBackground(){
    spriteBatch.draw(background, -10*ppuX,0*ppuY, Gdx.graphics.getWidth()*10,Gdx.graphics.getHeight());     
}

Здесь вы можете скачать код, если кто-то хочет помочь в хардкорном режиме

Мой код (не работает)

Я, наконец, решил это !!!! WIIIIIIIIII !!! Что код, который я использовал в имени класса WorldRenderer, который имеет методы, которые вызываются в GameScreen для рендеринга, изменения размера и т.д.

 public WorldRenderer(World world) {
    // TODO Auto-generated constructor stub

    this.world=world;
    this.ship=world.getShip();
    this.cam = new OrthographicCamera(CAMERA_WIDTH,CAMERA_HEIGHT);

    this.cam.setToOrtho(false,CAMERA_WIDTH,CAMERA_HEIGHT);
    this.cam.position.set(ship.getPosition().x,CAMERA_HEIGHT/2,0);
    this.cam.update();//actualizamos la camara
    spriteBatch=new SpriteBatch();
    loadTextures();
}

private void loadTextures(){
    shipTexture=new Texture(Gdx.files.internal("nave.png"));
    background=new Texture(Gdx.files.internal("fondo.jpg"));
}

  public void drawShip(){
          spriteBatch.draw(shipTexture,ship.getPosition().x,ship.getPosition().y,10,10);
}

public void drawBackground(){
    spriteBatch.draw(background, 0,0, 500,50);
} 

 public void render(float delta){ 
    ship.Move(delta);
    moveCamera(ship.getPosition().x);
    spriteBatch.setProjectionMatrix(cam.combined); 
    spriteBatch.begin();
        drawBackground();
        drawShip();
    spriteBatch.end();
}

 public void moveCemara(float x){
    cam.position.set(x+20,cam.position.y, 0);
    cam.update();
}

Внутри корабля у меня есть этот метод, который я вызываю в рендер в WorldRenderer, чтобы переместить его

public void Move(float delta){
    if(Gdx.input.isKeyPressed(Keys.LEFT)) this.position.x -=velocity *delta;
    if(Gdx.input.isKeyPressed(Keys.RIGHT)) this.position.x +=velocity *delta;
    if(Gdx.input.isKeyPressed(Keys.UP)) this.position.y +=velocity *delta;
    if(Gdx.input.isKeyPressed(Keys.DOWN)) this.position.y -=velocity *delta;
}

Также я хочу поблагодарить людей, которые помогли мне. Я отмечаю первый ответ как хороший, но сочетание обоих было тем, что дало мне реальное решение.

Я оставляю здесь несколько тузов, за которыми я следовал, которые очень хороши для новичков

Вот и все, что нужно, с нуля ! LiGdxForNoobs

Простая платформообразующая игровая платформа Game

Очень простая игра bucketGame

Ответ 1

Не понятно, как ваш рисунок? Я не уверен, правильно ли вы это делаете. Можете ли вы предоставить подробную информацию о своем происхождении и корабле? Можете ли вы предоставить подробную информацию о своем фоновом изображении, это огромное изображение, которое вы прокручиваете или это повторяющееся изображение, которое вы хотите повторять при прокрутке?

- EDIT--

ОК, я думаю, у меня есть идея, что может быть. Обычно я применяю камеру к текущему контексту.

Поместите следующее в свой размер

    public void resize(int width, int height) {
    cam = new OrthographicCamera(width, height);
    cam.translate(width / 2, height / 2, 0);
}

Поместите следующее в начало рендеринга()

cam.position.set(posX,posY,0);
cam.update();
cam.apply(Gdx.gl10);
Gdx.gl.glClearColor(0,0,0,1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // #14

Это приведет к тому, что у вас будет четкий экран с источником, установленным в левом нижнем углу окна. Затем вы должны сначала нарисовать свой фон

spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
spriteBatch.draw(background,0,0,sizeX,sizeY);
spriteBatch.end()

посмотрите, как это выглядит, когда вы перемещаете позицию камеры posX и posY. Затем добавьте свое судно в микс

- БОЛЬШЕ РЕДАКТИРОВАНИЯ ---

вы можете рассчитать posX и posY как

posX = defaultOffsetX + shipX

и т.д.

В любом случае надеюсь, что это поможет Я все еще только изучаю себя, поэтому это может быть не лучший метод... но он, похоже, работает.

Ответ 2

Я не могу сказать, является ли это вашей единственной ошибкой, но это ОДНА ошибка. Если это то, что вы говорите, вы делаете:

spriteBatch.begin();
drawBackground();
drawShip();
spriteBatch.setProjectionMatrix(camera.combined); 
spriteBatch.end();

Вы ничего не увидите. Когда setProjectionMatrix вызывается внутри блока begin()/end(). текущая партия очищается до gpu. Таким образом, вы фактически ничего не рисуете с матрицей камеры. Вы должны сделать это вместо этого:

    spriteBatch.setProjectionMatrix(camera.combined); 
    spriteBatch.begin();
    drawBackground();
    drawShip();
    spriteBatch.end();

EDIT:

Если вы не вызываете эту строку, spriteBatch использует свою собственную камеру по умолчанию (которая не замечает ваши изменения camera.update(), поэтому не то, что вы хотите).

Теперь вы должны уделять больше внимания координатам, которые вы используете. Я не совсем уверен, что вам действительно нужна конверсия ppu. Прежде всего, определите все в мнимых мировых координатах, обратите внимание, что вы увидите некоторое растяжение в вашем мире.

public void drawShip(){
    spriteBatch.draw(shipTexture,ship.getPosition().x,ship.getPosition().y, 10, 10);
}//your ship is 10 units wide and tall!

public void drawBackground(){
    spriteBatch.draw(background, -10,0, 500, 100);     
} //your background is 500 units wide, and 100 units tall

//camera setup
camera = new OrthographicCamera(50, 50);
//your camera will print to screen 50 units of your world

Если вы видите растянутый мир, попробуйте понять, как он работает (если вы ничего не видите, что-то не так).

ИЗМЕНИТЬ 2

Я взглянул на ваш код. Сначала удалите ppu, поскольку он скрывает ваш код. Вы устанавливали свою позицию кулака на корабль. Поезд, вытягивая на корабль. Положение * ppu. Кроме того, ваш фон был слишком большим (почему вы видите его пикселированным). Вы должны увидеть что-то разумное с этим. (когда-нибудь вам придется инициализировать свою камеру по-другому, чтобы справиться с растяжкой, но забудьте об этом, пока не поймете, как все работает).

this.cam = new OrthographicCamera(CAMERA_WIDTH,CAMERA_HEIGHT);

public void drawShip(){ 
    spriteBatch.draw(shipTexture, ship.getPosition().x ,ship.getPosition().y, 10, 10);
}

public void drawBackground(){
    spriteBatch.draw(background, -CAMERA_WIDTH/2, -CAMERA_HEIGHT/2, 100, 100); //let bg begin where camera starts. (0,0)
}


public void render(float delta){ 
    ship.Move(delta);
    moverCamara(ship.getPosition().x, ship.getPosition().y);
    spriteBatch.setProjectionMatrix(cam.combined);
    spriteBatch.begin();
        drawBackground();
        drawShip();
    spriteBatch.end();
}

Ответ 3

Я отредактировал твой код. Посмотрите на следующее:

public class WorldRenderer {

private World world;
private Ship ship;

private Texture shipTexture,background;
private SpriteBatch spriteBatch;

private OrthographicCamera cam;

float screenSizeX = 100;
float screenSizeY = 100;

float shipSizeX = 10;
float shipSizeY = 10;

public void setSize (int w, int h) {
    cam = new OrthographicCamera(screenSizeX,screenSizeY);
}


public WorldRenderer(World world) { 
    this.world=world;
    this.ship=world.getShip();
    spriteBatch=new SpriteBatch();
    loadTextures();
}



private void loadTextures(){
    shipTexture=new Texture(Gdx.files.internal("nave.png"));
    background=new Texture(Gdx.files.internal("fondo2.jpg"));
}

public void drawShip(){ 
    spriteBatch.draw(shipTexture, ship.getPosition().x,ship.getPosition().y, shipSizeX,shipSizeY);
}

public void drawBackground(){

    spriteBatch.draw(background, 0,0);
}


public void render(float delta){ 

    ship.Move(delta);

    moverCamara(ship.getPosition().x,ship.getPosition().y);

    spriteBatch.setProjectionMatrix(cam.combined);      
    spriteBatch.begin();
        drawBackground();
        drawShip();
    spriteBatch.end();
}




public void moverCamara(float x,float y){
    cam.position.set(x, y, 0);
    cam.update();
}

}

Таким образом, ваш корабль всегда находится в центре экрана, а фон движется. Надеюсь это поможет.