2015-10-17 98 views
1

下面的代碼給了我很奇怪的y座標。Libgdx - camera.unproject沒有固定我的座標

10-18 00:13:36.834 30543-30567/com.xxxx.yyyy.android I/x﹕ 137.4782 
10-18 00:13:36.834 30543-30567/com.xxxx.yyyy.android I/y﹕ -1984.2426 
10-18 00:13:36.835 30543-30567/com.xxxx.yyyy.android I/ux﹕ 91.65213 
10-18 00:13:36.835 30543-30567/com.xxxx.yyyy.android I/uy﹕ -1984.2426 

我想我設置了一切錯誤,而不是在運行時出現錯誤? camera.unproject調用應該照顧從屏幕座標到遊戲座標的所有重映射,不是嗎?或者我必須在未投影之前進行縮放和反轉?

package com.xxxx.yyyy; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.Camera; 
import com.badlogic.gdx.graphics.Texture; 
import com.badlogic.gdx.graphics.g2d.Batch; 
import com.badlogic.gdx.math.Vector3; 
import com.badlogic.gdx.scenes.scene2d.Actor; 
import com.badlogic.gdx.scenes.scene2d.InputEvent; 
import com.badlogic.gdx.scenes.scene2d.InputListener; 


public class LetterActor extends Actor 
{ 
    private Texture texture; 
    private Vector3 touchPosition = new Vector3(); 
    private Camera camera; 
    private boolean unproject = true; 

    public LetterActor(Texture letterTexture, Camera theCamera) 
    { 
     texture = letterTexture; 
     camera = theCamera; 

     touchPosition.set(240, 800, 0); 
     camera.unproject(touchPosition); 
     setPosition(touchPosition.x, touchPosition.y); 

     setSize(texture.getWidth(), texture.getHeight()); 

     addListener(new InputListener() 
     { 
      @Override 
      public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) 
      { 
       touchPosition.set(x, y, 0); 
       if (unproject) 
       { 
        camera.unproject(touchPosition); 
       } 
       setPosition(touchPosition.x, touchPosition.y); 

       logPositions(x, y, touchPosition.x, touchPosition.y); 

       return true; 
      } 

      @Override 
      public void touchUp(InputEvent event, float x, float y, int pointer, int button) 
      { 
       touchPosition.set(x, y, 0); 
       if (unproject) 
       { 
        camera.unproject(touchPosition); 
       } 
       setPosition(touchPosition.x, touchPosition.y); 

       logPositions(x, y, touchPosition.x, touchPosition.y); 
      } 

      @Override 
      public void touchDragged(InputEvent event, float x, float y, int pointer) 
      { 
       touchPosition.set(x, y, 0); 
       if (unproject) 
       { 
        camera.unproject(touchPosition); 
       } 
       setPosition(touchPosition.x, touchPosition.y); 

       logPositions(x, y, touchPosition.x, touchPosition.y); 
      } 
     }); 
    } 

    private void screenTo() 
    { 

    } 

    private void logPositions(float x, float y,float ux, float uy) 
    { 
     Gdx.app.log("x", Float.toString(x)); 
     Gdx.app.log("y", Float.toString(y)); 
     Gdx.app.log("ux", Float.toString(ux)); 
     Gdx.app.log("uy", Float.toString(y)); 
    } 

    @Override 
    public void draw(Batch batch, float alpha) 
    { 
     batch.draw(texture, getX(), getY(), getWidth(), getHeight()); 
    } 

    @Override 
    public void act(float delta) {} 
} 



package com.xxxx.yyyy; 

import com.badlogic.gdx.ApplicationAdapter; 
import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.GL20; 
import com.badlogic.gdx.graphics.OrthographicCamera; 
import com.badlogic.gdx.utils.viewport.ExtendViewport; 
import com.badlogic.gdx.graphics.Texture; 
import com.badlogic.gdx.scenes.scene2d.Stage; 
import com.badlogic.gdx.scenes.scene2d.Touchable; 
import com.badlogic.gdx.utils.viewport.FitViewport; 

public class WordPuzzle extends ApplicationAdapter 
{ 
    private final static float VIRTUAL_WIDTH = 480; 
    private final static float VIRTUAL_HEIGHT = 800; 

    private OrthographicCamera camera; 
    private FitViewport viewport; 
    private Stage stage; 

    @Override 
    public void create() 
    { 
     camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); 
     camera.setToOrtho(false, VIRTUAL_WIDTH, VIRTUAL_HEIGHT); 

     viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT, camera); 
     stage = new Stage(); 
     stage.setViewport(viewport); 
     Gdx.input.setInputProcessor(stage); 

     Texture[] textures = LetterLoader.loadLetters(); 
     for (int i = 0; i < textures.length; i++) 
     { 
      LetterActor letterActor = new LetterActor(textures[i], camera); 
      letterActor.setTouchable(Touchable.enabled); 
      stage.addActor(letterActor); 
     } 
    } 

    @Override 
    public void render() 
    { 
     Gdx.gl.glClearColor(1, 1, 1, 1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 

     stage.act(Gdx.graphics.getDeltaTime()); 
     stage.draw(); 
    } 


    @Override public void resize(int width, int height) 
    { 
     stage.getViewport().update(width, height, true); 
    } 

    @Override public void dispose() 
    { 
     stage.dispose(); 
    } 
} 



package com.xxxx.yyyy; 

import com.badlogic.gdx.Gdx; 
import com.badlogic.gdx.graphics.Texture; 

public class LetterLoader { 

    public static Texture[] loadLetters() 
    { 
     Texture[] letters = new Texture[26]; 

     for (int i = 0; i < 26; i++) 
     { 
      char letter = (char) (i + 65); 
      letters[i] = new Texture(Gdx.files.internal("bigletters/" + letter + ".png")); 
     } 

     return letters; 
    } 
} 

回答

0

首先,您從輸入偵聽器獲得的觸摸位置(x,y)已經是正確的座標。


關於你的輸出,你實際打印Ÿ兩次,但把它UY第二次:

Gdx.app.log("uy", Float.toString(y)); 

如果touchPosition.set(240, 800, 0);是在屏幕座標,那麼你需要unproject他們,但是

camera.unproject(touchPosition); 

假定th在您的相機填充整個屏幕,因此它在內部呼叫:

unproject(screenCoords, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); 

由於您使用虛擬大小,這是錯誤的。最簡單的解決辦法是從您正在使用視使用unproject方法:

viewport.unproject(touchPosition); 

這將自動調用用正確的參數相機unproject方法。

0

由於您正在使用Stage和InputListener,因此您在touchDown中獲得的座標以及相關的方法已經在世界座標系中,所以對它們進行未投影是沒有意義的。你可以直接使用x和y。

另外(雖然這與InputListener無關),但camera.unproject假設一個填充屏幕的視口,這與您正在使用的FitViewport不同。如果您使用的是視口類,則需要使用viewport.unproject而不是camera.unproject,因此需要考慮黑條。

但是,您只需要擔心與舞臺不相關的東西的未投影。