【问题标题】:libgdx world to screen pos and factorslibgdx 世界筛选 pos 和 factor
【发布时间】:2017-04-14 09:23:09
【问题描述】:

我想在一个身体上画一个纹理,这是一个盒子。 如何将身体坐标转换为屏幕坐标? 我知道反过来是camera.unproject(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;

我真的不知道自己在做什么,我阅读了文档并阅读了一些教程,但是如果有人可以对这些变量和 world_to_screen 因素进行一些解释,那将真正帮助我。

我也设置了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] 舞台类

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

屏幕类

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 () {

    }
}

【问题讨论】:

    标签: java libgdx box2d


    【解决方案1】:

    我们主要使用像素到米的转换,因为 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-30
      • 1970-01-01
      • 2013-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多