2015-10-17 62 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,因此需要考虑黑条。

但是,您只需要担心与舞台不相关的东西的未投影。