12

ここに画像の説明を入力

私は 10 時間 (文字通り) 探していました。問題は、LibGdx を使用して Java ゲームをプログラミングする方法を学んでいることです。水平宇宙船ゲームをやっています。したがって、ここでの私の最悪の問題は、スクロールの方法がわからないことです (draw の方が説明がわかりやすいと思います)。巨大な背景 (スペース) を描画し、OrthographicCamera を SpaceShip のように正しく動かしたいので、スペースの背景でスクロール効果が作成されます。敵はおらず、画面には船しかありません。

私はこれを試しています:

 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 のおかげでわかります) が、ゲーム内では移動していないため、SpaceShip はウィンドウの端で消えるだけです。

spriteBatch.end() の前にもこれを試しました

spriteBatch.setProjectionMatrix(camera.combined);

しかし、それを行うと、ウィンドウには黒い画面しか表示されず、船も何も表示されません。私が言ったように、私は必死です、私は多くの例(マウスでスクロールする、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());     
}

誰かがハードコアモードで助けたい場合は、ここでコードをダウンロードできます

私のコード(動作していません)

私はついにそれを解決しました!

これは、レンダリング、サイズ変更などのために GameScreen 内で呼び出されるメソッドを持つクラス名 WorldRenderer で使用したコードです。

 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 の render 内で呼び出して移動するこのメソッドがあります。

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

非常にシンプルなゲーム バケツゲーム

4

3 に答える 3

6

これがあなたの唯一の間違いかどうかはわかりませんが、これは 1 つの間違いです。これがあなたがしていたことだと言うなら:

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

何も見えません。setProjectionMatrix が begin()/end() ブロック内で呼び出されたとき。現在のバッチが GPU にフラッシュされます。したがって、実際にはカメラ マトリックスで何も描画していません。代わりにこれを行う必要があります。

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

編集:

その行を呼び出さない場合、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 を削除します。ship.position * ppuで描画中に、カム位置をship.positionに設定していました。また、背景が大きすぎました (そのため、ピクセル化されて表示されます)。これで合理的なことがわかるはずです。(いつか、ストレッチに対処するために別の方法でカメラを初期化する必要がありますが、すべてがどのように機能するかを理解するまで忘れてください).

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();
}
于 2013-01-24T21:03:56.253 に答える
3

どのようにあなたの絵がはっきりしていませんか?このアプローチを正しく行っているかどうかはわかりません。背景と出荷の詳細を教えてください。背景画像の詳細を教えてください。スクロールするのは巨大な画像ですか、それともスクロールしながら繰り返したい繰り返し画像ですか。

- 編集 -

わかりました、私は何が起きているのか考えていると思います。私は通常、カメラを現在のコンテキストに適用します。

サイズ変更に以下を配置します

    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に移動すると、どのように見えるかを確認してください。次に、船をミックスに追加します

-その他の編集---

次に、posXとposYを次のように計算できます。

posX = defaultOffsetX + shipX

等々..

とにかく、これが私がまだ自分自身を学んでいるだけなので、これが最善の方法ではないかもしれないのに役立つことを願っています..しかしそれはうまくいくようです。

于 2013-01-24T20:43:29.723 に答える
0

私はあなたのコードを編集しました。以下をご覧ください。

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

}

このように、あなたの船は常に画面の真ん中にあり、背景が動きます。お役に立てれば。

于 2013-01-25T13:30:03.287 に答える