2017-04-14 41 views
0

我想绘制一个身体,这是一个盒子的纹理。 如何将身体的坐标转换为屏幕坐标? 我知道另一种方式是与camera.unproject(pos),这是类似的吗?libgdx世界到屏幕pos和因素

我看到很多使用常量的人,例如WORLD_TO_SCREEN = 32,但我目前在我的游戏中没有这样的常量。这是一个问题,我现在怎么实现?因为使用这些因素的人似乎可以轻松地将世界转换为屏幕位置。我现在有一个摄像头和一个ExtendViewport

camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 
viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera); 
camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f); 

视口的宽度和高度都设置为这个

public static final int VIEWPORT_WIDTH = 20; 
public static final int VIEWPORT_HEIGHT = 22; 

我真的不知道我在做什么,我阅读文档,看了一些教程,但是如果有人能够对这些变数和对我真正有帮助的因素给出一些解释。

我也设置APP_WIDTH=1280, APP_HEIGHT = 720 视窗的宽度和高度是否意味着对于box2d我的屏幕宽20米,高22米? (再次问它,因为我加入了很多的问题,我真的想知道这些事情)

[编辑]

所以我想在地上画体的接地图片

float x = stage.getGround().getX(); 
float y = stage.getGround().getY(); 
float w = stage.getGround().getWidth(); 
float h = stage.getGround().getHeight(); 

stage.act(delta); 
stage.draw(); 
stage.updateCamera(); 

Texture texture = new Texture(Gdx.files.internal("ground.png")); 
Sprite sprite = new Sprite(texture); 
sprite.setSize(w, h); 
sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2); 

,但我没有看到它的任何地方

[编辑2] Stage类

public class Mission1Stage extends Stage{ 
    public static final int VIEWPORT_WIDTH = 20; 
    public static final int VIEWPORT_HEIGHT = 22; 

    private World world; 
    private Ground ground; 
    private LeftWall leftWall; 
    private Rocket rocket; 

    private static final float TIME_STEP = 1/300f; 
    private float accumulator = 0f; 

    private OrthographicCamera camera; 
    private Box2DDebugRenderer renderer; 
    private Viewport viewport; 

    private SpriteBatch spriteBatch = new SpriteBatch(); 

    private Vector3 touchPoint; 
    private ShapeRenderer shapeRenderer; 

    private Button boostButton; 
    private Skin boostSkin; 

    private Button boostLeftButton; 
    private Skin boostLeftSkin; 

    private Button boostRightButton; 
    private Skin boostRightSkin; 

    private Button resetButton; 
    private Skin resetSkin; 

    private Game game; 

    private boolean isTouched = false; 

    public Mission1Stage(Game game) { 
     setUpWorld(); 
     renderer = new Box2DDebugRenderer(); 
     shapeRenderer = new ShapeRenderer(); 
     setupCamera(); 
     setUpButtons(); 
     addActor(new Background(ground)); 
    } 

    private void setUpWorld() { 
     world = WorldUtils.createWorld(); 
     setUpGround(); 
     setUpRocket(); 
    } 

    private void setUpGround() { 
     ground = new Ground(WorldUtils.createGround(world)); 
     addActor(ground); 
    } 

    private void setUpLeftWall() { 
     leftWall = new LeftWall(WorldUtils.createLeftWall(world)); 
    } 

    private void setUpRocket() { 
     rocket = new Rocket(WorldUtils.createRocket(world)); 
     addActor(rocket); 
    } 

    private void setupCamera() { 
     camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 
     viewport = new ExtendViewport(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, camera); 
     camera.position.set(VIEWPORT_WIDTH/2, VIEWPORT_HEIGHT/2, 0f); 
     camera.update(); 
    } 

    private void setUpButtons() { 
     boostSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); 
     boostButton = new Button(boostSkin); 
     boostButton.setSize(80,80); 
     boostButton.setPosition(Gdx.graphics.getWidth()-boostButton.getWidth()*2,0); 
     boostButton.setTransform(true); 
     boostButton.scaleBy(0.5f); 
     Gdx.input.setInputProcessor(this); 
     addActor(boostButton); 

     boostLeftSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); 
     boostLeftButton = new Button(boostLeftSkin); 
     boostLeftButton.setSize(100, 100); 
     boostLeftButton.setPosition(0, 0); 
     addActor(boostLeftButton); 

     boostRightSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); 
     boostRightButton = new Button(boostRightSkin); 
     boostRightButton.setSize(100, 100); 
     boostRightButton.setPosition(boostLeftButton.getWidth(), 0); 
     addActor(boostRightButton); 

     resetSkin = new Skin(Gdx.files.internal("skin/flat-earth-ui.json")); 
     resetButton = new Button(resetSkin); 
     resetButton.setSize(100, 100); 
     resetButton.setPosition(Gdx.graphics.getWidth()-100, Gdx.graphics.getHeight()-100); 
     addActor(resetButton); 
    } 

    @Override 
    public void act(float delta) { 
     super.act(delta); 
     handleInput(); 

     accumulator += delta; 

     while(accumulator >= delta) { 
      world.step(TIME_STEP, 6, 2); 
      accumulator -= TIME_STEP; 
     } 
    } 

    @Override 
    public void draw() { 
     super.draw(); 
     renderer.render(world, camera.combined); 

     float x = getGround().getBody().getPosition().x; 
     float y = getGround().getBody().getPosition().y; 
     float w = getGround().getWidth() * 2; 
     float h = getGround().getHeight() * 2; 

     spriteBatch.setProjectionMatrix(getCamera().combined); 

     Texture texture = new Texture(Gdx.files.internal("ground.png")); 
     Sprite sprite = new Sprite(texture); 
     sprite.setSize(w, h); 
     sprite.setPosition(x-sprite.getWidth()/2, y-sprite.getHeight()/2); 


     spriteBatch.begin(); 
     sprite.draw(spriteBatch); 
     spriteBatch.end(); 
    } 

    public void handleInput() { 
     if(boostButton.isPressed()) { 
      rocket.boost(); 
     } 
     if(boostLeftButton.isPressed()) { 
      rocket.turnLeft(); 
     } 
     if(boostRightButton.isPressed()) { 
      rocket.turnRight(); 
     } 
     if(resetButton.isPressed()) { 

     } 
    } 

    public boolean resetScreen() { 
     if(resetButton.isPressed()) return true; 
     return false; 
    } 

    public void updateCamera() { 

    } 

    public Ground getGround() { 
     return ground; 
    } 

    public void resize(int width, int height) { 
     viewport.update(width, height); 
     camera.position.x = VIEWPORT_WIDTH/2; 
     camera.position.y = VIEWPORT_HEIGHT /2; 
    } 


    private void translateScreenToWorldCoordinates(int x, int y) { 
     getCamera().unproject(touchPoint.set(x, y, 0));getCamera(); 
    } 
} 

Screen类

public class Mission1Screen implements Screen{ 
    private Game game; 
    private Mission1Stage stage; 
    private SpriteBatch spriteBatch = new SpriteBatch(); 

    private Skin boostSkin; 
    private Button boostButton; 

    public Mission1Screen(Game game) { 
     this.game = game; 
     stage = new Mission1Stage(game); 
    } 

    @Override 
    public void show() { 

    } 

    @Override 
    public void render(float delta) { 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

     if(stage.resetScreen()) { 
      game.setScreen(new Mission1Screen(game)); 
     } 

     stage.act(delta); 
     stage.draw(); 
     stage.updateCamera(); 
    } 

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

    @Override 
    public void pause() { 

    } 

    @Override 
    public void resume() { 

    } 

    @Override 
    public void hide() { 

    } 

    @Override 
    public void dispose() { 

    } 
} 

[编辑3]

public class Main extends Game { 

    @Override 
    public void create() { 
     this.setScreen(new Mission1Screen(this)); 
    } 

    @Override 
    public void render() { 
     super.render(); 
    } 

    @Override 
    public void dispose() { 

    } 
} 

回答

2

我们主要使用Pixel计量转换,因为在米Box2D的最佳作品(0-10),但你可以通过使用小型避免这种转换您的视口的世界宽度和高度。我大多更喜欢48和80作为视口的宽度和高度。

您可以使用unproject(vector3)摄像头方法,将屏幕坐标中给定的点转换为世界空间。我在touchdown中使用这种方法,因为我将屏幕坐标作为参数,然后我需要将其转换为相机世界空间,以便我可以在世界的特定位置生成对象。

public class MyGdxTest extends Game implements InputProcessor { 

    private SpriteBatch batch; 
    private ExtendViewport extendViewport; 
    private OrthographicCamera cam; 

    private float w=20; 
    private float h=22; 

    private World world; 
    private Box2DDebugRenderer debugRenderer; 

    private Array<Body> array; 
    private Vector3 vector3; 

    @Override 
    public void create() { 

     cam=new OrthographicCamera(); 
     extendViewport=new ExtendViewport(w,h,cam); 

     batch =new SpriteBatch(); 
     Gdx.input.setInputProcessor(this); 

     world=new World(new Vector2(0,-9.8f),true); 
     array=new Array<Body>(); 
     debugRenderer=new Box2DDebugRenderer(); 
     vector3=new Vector3(); 

     BodyDef bodyDef=new BodyDef(); 
     bodyDef.type= BodyDef.BodyType.StaticBody; 
     bodyDef.position.set(0,0); 
     Body body=world.createBody(bodyDef); 

     ChainShape chainShape=new ChainShape(); 
     chainShape.createChain(new float[]{1,1,55,1}); 

     FixtureDef fixtureDef=new FixtureDef(); 
     fixtureDef.shape=chainShape; 
     fixtureDef.restitution=.5f; 
     body.createFixture(fixtureDef); 
     chainShape.dispose(); 
    } 

    @Override 
    public void render() { 
     super.render(); 

     Gdx.gl.glClearColor(0,1,1,1); 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

     world.step(1/60f,6,2); 
     batch.setProjectionMatrix(cam.combined); 
     batch.begin(); 

     world.getBodies(array); 
     for (Body body:array){ 
      if(body.getUserData()!=null) { 
       Sprite sprite = (Sprite) body.getUserData(); 
       sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2); 
       sprite.setRotation(body.getAngle()*MathUtils.radDeg); 
       sprite.draw(batch); 
      } 
     } 
     batch.end(); 
     debugRenderer.render(world,cam.combined); 
    } 

    @Override 
    public void resize(int width, int height) { 
     super.resize(width,height); 
     extendViewport.update(width,height); 
     cam.position.x = w /2; 
     cam.position.y = h/2; 
     cam.update(); 
    } 

    private void createPhysicsObject(float x,float y){ 

     float sizeX=2,sizeY=2; 
     BodyDef bodyDef=new BodyDef(); 
     bodyDef.position.set(x,y); 
     bodyDef.type= BodyDef.BodyType.DynamicBody; 

     Body body=world.createBody(bodyDef); 

     PolygonShape polygonShape=new PolygonShape(); 
     polygonShape.setAsBox(sizeX,sizeY); 
     FixtureDef fixtureDef=new FixtureDef(); 
     fixtureDef.shape=polygonShape; 
     fixtureDef.restitution=.2f; 
     fixtureDef.density=2; 

     body.createFixture(fixtureDef); 
     body.setFixedRotation(false); 
     polygonShape.dispose(); 


     Sprite sprite=new Sprite(new Texture("badlogic.jpg")); 
     sprite.setSize(2*sizeX,2*sizeY); 
     sprite.setPosition(x-sprite.getWidth()/2,y-sprite.getHeight()/2); 
     sprite.setOrigin(sizeX,sizeY); 

     body.setUserData(sprite); 
    } 

    @Override 
    public void dispose() { 
     batch.dispose(); 
     debugRenderer.dispose(); 
     world.dispose(); 
    } 

    @Override 
    public boolean keyDown(int keycode) { 
     return false; 
    } 

    @Override 
    public boolean keyUp(int keycode) { 
     return false; 
    } 

    @Override 
    public boolean keyTyped(char character) { 
     return false; 
    } 

    @Override 
    public boolean touchDown(int screenX, int screenY, int pointer, int button) { 

     vector3.set(screenX,screenY,0); 
     Vector3 position=cam.unproject(vector3); 
     createPhysicsObject(vector3.x,vector3.y); 

     return false; 
    } 

    @Override 
    public boolean touchUp(int screenX, int screenY, int pointer, int button) { 
     return false; 
    } 

    @Override 
    public boolean touchDragged(int screenX, int screenY, int pointer) { 
     return false; 
    } 

    @Override 
    public boolean mouseMoved(int screenX, int screenY) { 
     return false; 
    } 

    @Override 
    public boolean scrolled(int amount) { 
     return false; 
    } 
}