libgdx世界筛选pos和因素 [英] libgdx world to screen pos and factors

查看:86
本文介绍了libgdx世界筛选pos和因素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个盒子上画一个纹理. 如何将身体的坐标转换为屏幕坐标? 我知道另一种方法是使用camera.unproject(pos),是否与此类似?

I want to draw a texture on a body, which is a box. How do I convert the coordinates of the body to screen coordinates? I know that the other way around is with camera.unproject(pos), is it similar to this?

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

I see a lot of people using constants such as WORLD_TO_SCREEN = 32, but I currently don't have that in my game. Is that a problem, and how can I implement it now? Because it seems like people that are using these factors can convert world to screen positions easily. I currently have a camera and an 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);

视口的宽度和高度设置为此

Viewport width and height are set to this

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

我真的不知道我在做什么,我阅读了文档并阅读了一些教程,但是如果有人可以对这些变量和真正有助于我的因素world_to_screen给出一些解释.

I don't really know what I'm doing, I read documentation and read some tutorials, but if someone could give some explanation about these variables and the world_to_screen factor that would really help me out.

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

I also set APP_WIDTH=1280, APP_HEIGHT = 720 Do viewport width and height mean that for box2d my screen is 20 meters wide and 22 meters high? (asking it again because I added a lot the question and I would really like to know these things)

所以我试图在地面上绘制地面图片

So I'm trying to draw a ground picture on the ground body

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

但是我在任何地方都看不到

But I don't see it anywhere

舞台班

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

    }
}

public class Main extends Game {

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

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

    @Override
    public void dispose () {

    }
}

推荐答案

我们主要使用像素到米的转换,因为box2d最好以米(0-10)为单位,但是您可以通过使用较小的世界宽度和视口高度来避免这种转换.我最喜欢将48和80作为视口的宽度和高度.

We mostly use Pixel to meter conversion because box2d best works in meters (0-10) but you can avoid this conversion by using small worldwidth and height of your viewport. I mostly prefer 48 and 80 as viewport width and height.

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

You can use unproject(vector3) method of camera that translate a point given in screen coordinates to world space. I am using this method in touchdown because I get screen coordinate as parameter then I need to convert it into camera world space so that I can generate object at a particular position in world.

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

这篇关于libgdx世界筛选pos和因素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆