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

enter image description here

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

Я triying этот

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

затем я использую этот метод в моем WorldRender метод render ():

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();
}

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

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

spriteBatch.setProjectionMatrix(camera.combined);

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

вот как я рисую вещи. Фон и корабль-это текстуры внутри 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, который имеет методы, которые calle в 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;
}

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

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

это хорошее все-от-царапин-туто LiGdxForNoobs

простая игра с platformGame

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

3 ответов


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

-- EDIT--

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

поместите следующее в ваш размер

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

поместите следующее В начало вашего render ()

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. Затем добавьте свой корабль в mix

- БОЛЬШЕ ПРАВОК ---

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

параметра posx = defaultOffsetX+shipX

и так далее..

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


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

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 использует свою собственную камеру по умолчанию (которая не заметит вашу камеру.обновления (модификации), так что это не то, что вы хотите).

теперь вы должны уделять больше внимания координатам, которые вы используете. Я не совсем уверен,что вам действительно нужна конверсия 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();
}

Эй, я отредактировал ваш код, посмотрите на следующее

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();
}

}

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