libgdx box2d身体被放置在错误的y坐标

时间:2018-12-31 12:43:48

标签: java android android-studio libgdx box2d

我一直在使用box2d,但遇到一个问题,当我尝试将其放置在屏幕的右下角时,我的身体未设置为正确的y坐标。

我正在尝试将y坐标设置为0,以使主体直接与屏幕底部对齐。但是,身体的一半悬挂在屏幕上。即使我打印出人体的位置,它也表示y为0。

我将每米的像素设置为screenHeight / 80,对于我正在使用的当前设备,结果约为25 PPM。我不确定我的缩放是否会导致某些奇怪的事情发生。

代码:

public class GameScreen extends ScreenAdapter {
    Controller game;

    public World world;
    public Body ball;
    public Body block;
    public Box2DDebugRenderer box2DDebugRenderer;
    private Matrix4 cameraBox2D;

    public MyGestureListener myGestureListener;

    //x-axis length for top/bottom bar
    private float goalWidth;

    //pixels per meter
    public float PPM;

    //y-axis height for back bar
    private float goalHeight;
    private float goalPostThickness;

    //Screen height and width
    private float screenWidth;
    private float screenHeight;

    //How far down/up posts are from edge of screen
    private float goalPostTopOffset;
    private float goalPostBottomOffset;

    //Center x,y of cannon
    private float cannonOriginX; //Variables used for starting poisition of balls
    private float cannonOriginY;

    //Center x,y of ball
    float ballX;
    float ballY;

    //Velocity of ball
    public float velocity = 50;
    public int colorCode = 1;

    //Tracks users drag y coord
    public float panLocation = 0;

    //Velocity of block once the user releases
    public float flingVelocity;

    //Changes to true when the block is released
    public boolean isReleased = false;

    public GameScreen (Controller game){
        this.game = game;
    }

    @Override
    public void show(){

        myGestureListener = new MyGestureListener(game, this);
        cameraBox2D = new Matrix4(game.cam.combined);

        screenWidth = game.getScreenWidth();
        screenHeight = game.getScreenHeight();

        //PPM = screenHeight / 80f;

        PPM = screenHeight / 80f;

        goalPostTopOffset = screenHeight/7;
        goalPostBottomOffset = goalPostTopOffset * 3;
        goalHeight = screenHeight - (goalPostTopOffset + goalPostBottomOffset);
        goalWidth = screenWidth / 6;
        goalPostThickness = screenWidth / 75;

        cannonOriginX = goalWidth / 2; //Variables used for starting position of balls
        cannonOriginY = (goalPostThickness*5) / 2;

        ballX = 0 + cannonOriginX;
        ballY = (goalPostBottomOffset - (goalPostBottomOffset / 4)) + cannonOriginY;

        world = new World(new Vector2(0, 0f), true);
        box2DDebugRenderer = new Box2DDebugRenderer();

        //Creates animated ball
        ball = createBall();

        //Sets radius, density, etc.
        setBallProperties(ball);

        //Creates block that stops balls
        block = createBlock();

        //Sets properties
        setBlockProperties(block);
    }

    @Override
    public void render(float delta){
        //Logic
        world.step(1/60f, 6, 2);

        //Draw
        game.cam.update();
        Gdx.gl.glClearColor(32/255f, 32/255f, 32/255f, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        box2DDebugRenderer.render(world, game.cam.combined.scl(PPM));
        game.shape.setProjectionMatrix(game.cam.combined);

        Gdx.input.setInputProcessor(new GestureDetector(myGestureListener));

        System.out.println(block.getPosition().y);
        System.out.println(block.getPosition().x);

        drawNonAnimated();
        drawAnimated();


//show()
        cameraBox2D = game.cam.combined.cpy(); //Copy the main camera
        cameraBox2D.scl(PPM); //Scale the camera projection to the ratio you're using for Box2D

//render()
        box2DDebugRenderer.render(world, cameraBox2D);
    }

    @Override
    public void hide(){

    }

    //draws stationary objects such as goal posts
    public void drawNonAnimated(){

        //Cannon platform
        game.shape.setColor(1, 1, 1, 1);
        game.shape.begin(ShapeRenderer.ShapeType.Filled);
        game.shape.rect(0, (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM, goalWidth/PPM, (goalPostThickness*2)/PPM);
        game.shape.end();

        //Cannon
        game.shape.setColor(1, 1, 1, 1);
        game.shape.begin(ShapeRenderer.ShapeType.Filled);
        game.shape.rect(0, (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM, cannonOriginX/PPM,
                cannonOriginY/PPM, goalWidth/PPM, (goalPostThickness*5)/PPM, 1, 1, 45);
        game.shape.end();
    }

    public void drawAnimated(){
        //FOR BALL
        velocity--;
        ball.setLinearVelocity(new Vector2(35,velocity));

        Vector2 pos = ball.getPosition();

        if (pos.x >= screenWidth/PPM){
            ball.setTransform(new Vector2(ballX/PPM, ballY/PPM), 0);

            //Changing color of ball each loop
            if (colorCode == 3){
                colorCode = 1;
            }
            else{
                colorCode++;
            }
            //max 75   min 50
            velocity = randInt(50, 75);
        }

        attachCircleShape(pos);

        blockerMovement();

    }

    public void blockerMovement(){
        //FOR BLOCKER RECTANGLE ANIMATION
        Vector2 pos = block.getPosition();
        float boundaryLocation = (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM;
        //attachBlockerShape(pos);

        panLocation = myGestureListener.getPanLocation();
        if (isReleased == true){
            //Get the velocity as the block is released
            //to determine the speed it will continue to go after release
            block.setLinearVelocity(0, flingVelocity);
            flingVelocity -= 3;
        }

        else if (myGestureListener.getCheckRelease()|| panLocation/PPM >= boundaryLocation && !isReleased) {
            flingVelocity = myGestureListener.speed;
            isReleased = true;
            System.out.println("SPEED: " + flingVelocity);
        }
        else if (myGestureListener.isPaning) {

            block.setTransform(new Vector2((screenWidth - goalPostThickness) / PPM, panLocation / PPM), 0);
        }

    }

    //Creates animated ball
    public Body createBall(){
        Body bBody;
        BodyDef def = new BodyDef();
        def.type = BodyDef.BodyType.DynamicBody;
        def.position.set(ballX/PPM,ballY/PPM);
        def.fixedRotation = true;
        bBody = world.createBody(def);

        return bBody;
    }

    //Sets radius, density, etc.
    public void setBallProperties(Body body){
        float gbt = screenWidth / 75;  //Goal post thickness
        float ballRadius = (gbt * 1.5f) / PPM;

        // Create a circle shape and set its radius to 6
        CircleShape circle = new CircleShape();

        circle.setRadius(ballRadius);
        // Create a fixture definition to apply our shape to
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = circle;
        fixtureDef.density = 3.5f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f; // Make it bounce a little bit

        // Create our fixture and attach it to the body
        Fixture fixture = ball.createFixture(fixtureDef);

        circle.dispose();
    }



    public Body createBlock(){
        Body bBody;
        BodyDef def = new BodyDef();
        def.type = BodyDef.BodyType.DynamicBody;
        def.position.set((screenWidth - goalPostThickness)/PPM,0);
        def.fixedRotation = true;
        bBody = world.createBody(def);

        return bBody;
    }


     //Sets radius, density, etc.
    public void setBlockProperties(Body body){
        float gbt = screenWidth / 75;  //Goal post thickness

        // Create a circle shape and set its radius to 6
          PolygonShape square = new PolygonShape();
         square.setAsBox(goalPostThickness/PPM, (goalWidth/2)/PPM);

        // Create a fixture definition to apply our shape to
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = square;
        fixtureDef.density = 3.5f;
        fixtureDef.friction = 0.4f;
        fixtureDef.restitution = 0.6f; // Make it bounce a little bit

        // Create our fixture and attach it to the body
        Fixture fixture = block.createFixture(fixtureDef);

        square.dispose();
    }

    public static int randInt(int min, int max) {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;
        return randomNum;
    }

    public void attachBlockerShape(Vector2 pos){
        game.shape.setColor(1, 1, 1, 1);
        game.shape.begin(ShapeRenderer.ShapeType.Filled);
        game.shape.rect(pos.x, pos.y, goalPostThickness/PPM, (goalWidth/2)/PPM);
        game.shape.end();
    }

    //Attaching a regular libgdx shape to the position of box2d shape
    public void attachCircleShape(Vector2 pos){
        //Color of ball changes each loop
        if (colorCode == 1){
            //Blue
            game.circle.setColor(66/255f, 134/255f, 244/255f, 0);
        }
        else if (colorCode == 2){
            //Pink
            game.circle.setColor(244/255f, 66/255f, 116/255f, 0);
        }
        else if (colorCode == 3){

            game.circle.setColor(244/255f, 116/255f, 66/255f, 0);
        }
        game.circle.begin(ShapeRenderer.ShapeType.Filled);
        game.circle.circle(pos.x*PPM, pos.y*PPM, goalPostThickness * 1.5f);
        game.circle.end();
        game.cam.update();

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


}

1 个答案:

答案 0 :(得分:0)

如果使用Box2d 0,0创建一个Body,则在Body的中心,而libgdx在左下角将其设置为0,0。

enter image description here

因此,如果您使用Box2d创建实体,并且希望0,0位于左下角,则必须将实体在x上移动一半的宽度,在y上移动一半的高度:

public Body createBody(float x, float y, float width, float height){
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;

    //Move the body so if x and y are 0 the bottom left corner of the body is on position 0,0
    bodyDef.position.x = x + width / 2;
    bodyDef.position.y = y + height / 2;

    PolygonShape polygonShape = new PolygonShape();
    polygonShape.setAsBox(width / 2, height / 2);

    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = polygonShape;

    Body body = world.createBody(bodyDef);
    body.createFixture(fixtureDef);

    polygonShape.dispose();
    return body;
}