【问题标题】:LibGDX circle object keep rollingLibGDX 圆形对象保持滚动
【发布时间】:2014-11-20 02:31:45
【问题描述】:

基本上我有一个圆形物体作为玩家,它只能跳跃。我想要做的是让圆形物体保持滚动,同时对圆形物体施加恒定的重力或力,使其在地面上保持向右滚动。我尝试通过将 vector2 x 值设置为 0.5f 来制作恒定的重力:

World world = new World(new Vector2(0.5f, -9.8f), true); 

当我这样做时,随着时间的推移,球会快速移动。

有没有办法达到我想要的效果?

播放类代码:

public class Play implements Screen,ContactListener{

World world = new World(new Vector2(0f, -9.8f), true);  
Box2DDebugRenderer debugRenderer;  
OrthographicCamera camera;  
static final int PPM = 100;
static float height,width;
Body player;
RayHandler handler;
PointLight l1;
Body groundBody;
float tileSize;
boolean playerOnGround = false;
int footContact;
ShapeRenderer shapeRenderer;
PointLight light;
TiledMap tileMap;
OrthogonalTiledMapRenderer tmr;
BallJump game;
int level;

Color lightColor = new Color();

public Play(int level,BallJump game ) { 
    this.level = level;
    this.game = game;
}


@Override
public void show() {
    shapeRenderer = new ShapeRenderer();

    height = Gdx.graphics.getHeight();
    width = Gdx.graphics.getWidth();

    //set camera
     camera = new OrthographicCamera();  


     new FitViewport(width/PPM/2, height/PPM/2, camera);
    if((height + width) > 1500 && (height + width) < 2000) { 
        camera.zoom = 0.5f;
    } else if ((height + width) > 2000) { 
        camera.zoom = 0.75f;
    }
     camera.update();  




     //player Body  
     BodyDef bodyDef = new BodyDef();  
     bodyDef.type = BodyType.DynamicBody;  
     bodyDef.position.set((width/PPM)/2/2, (height / PPM)/2/2);  
     player = world.createBody(bodyDef);  
     CircleShape dynamicCircle = new CircleShape();  
     dynamicCircle.setRadius(5f/PPM);  
     FixtureDef fixtureDef = new FixtureDef();  
     fixtureDef.shape = dynamicCircle;  
     fixtureDef.density = 0.4f;  
     fixtureDef.friction = 1f;  
     fixtureDef.restitution = 0f;  











     player.createFixture(fixtureDef).setUserData("player");;  
     debugRenderer = new Box2DDebugRenderer();  

     //Lighting

     handler = new RayHandler(world);

     light = new PointLight(handler,500,Color.MAGENTA,4f,width/PPM/2/2/2,height/PPM/2/2);
     light.attachToBody(player);



     // tile map

     tileMap = new TmxMapLoader().load("test2.tmx");
     tmr = new OrthogonalTiledMapRenderer(tileMap,0.01f);

     TiledMapTileLayer layer = (TiledMapTileLayer) tileMap.getLayers().get("block");
     tileSize = layer.getTileHeight()*2;

     for(int row = 0; row < layer.getHeight(); row++) { 
         for(int col = 0; col < layer.getWidth(); col++) { 
             Cell cell =  layer.getCell(col, row);
             if(cell == null) { continue;}
             if(cell.getTile() == null) { continue;}

             BodyDef bdef = new BodyDef();
             bdef.type = BodyType.StaticBody;
             bdef.position.set((col + 0.5f) * tileSize /PPM/2, (row + 0.5f) * tileSize /PPM/2);

             PolygonShape cs = new PolygonShape();
             cs.setAsBox(tileSize/2/PPM/2, tileSize/2/PPM/2);




             FixtureDef fdef = new FixtureDef();
             fdef.friction = 0f;
             fdef.shape = cs;
             world.createBody(bdef).createFixture(fdef).setUserData("ground");;

             world.setContactListener(this);



         }
     }


}


public void update() { 

     playerOnGround = footContact > 0;





    if(Gdx.input.isKeyJustPressed(Keys.UP) || (Gdx.input.isTouched())) { 
        if(playerOnGround)
        player.applyForceToCenter(0, 0.75f, true);
    }
     else if (Gdx.input.isKeyPressed(Keys.SPACE)) { 
        player.setTransform((width/PPM)/2/2, (height / PPM)/2/2, 0);
    }




}




@Override  
public void pause() {  
}  

@Override  
public void resume() {  
}


@Override
public void beginContact(Contact contact) {

    Fixture a = contact.getFixtureA();
    Fixture b = contact.getFixtureB();


    if(b.getUserData().equals("player") && b.getUserData() != null) { 
        footContact++;
        player.setAngularDamping(5f);
    } 
    if(a.getUserData().equals("player") && a.getUserData() != null) { 
        footContact++;
        player.setAngularDamping(5f);
    } 





}


@Override
public void endContact(Contact contact) {
    Fixture a = contact.getFixtureA();
    Fixture b = contact.getFixtureB();

    if(b.getUserData().equals("player") && b.getUserData() != null) { 
        footContact--;
    } 
    if(a.getUserData().equals("player") && a.getUserData() != null) { 
        footContact--;
    } 


}


@Override
public void preSolve(Contact contact, Manifold oldManifold) {}


@Override
public void postSolve(Contact contact, ContactImpulse impulse) {}


@Override
public void render(float delta) {

    camera.position.set(player.getPosition().x, player.getPosition().y, 0); 
    update();
    camera.update();

    shapeRenderer.setProjectionMatrix(camera.combined);




     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);  

     world.step(1/60f, 6, 2); 
     handler.updateAndRender();
     handler.setCombinedMatrix(camera.combined);






     debugRenderer.render(world, camera.combined);  






}
}

【问题讨论】:

    标签: java libgdx game-physics gravity


    【解决方案1】:

    重力是force,它应用于每个world 中的每个body 中的每个step
    这意味着,这些受影响对象的velocity 每帧都会增加。
    这只是预期的结果,想想现实:
    如果你从高处跳跃,你会越来越快,直到你撞到地面(或空气阻力限制你的速度)。

    如果你想以恒定的速度移动(在Box2D),你应该这样做:

    Vector2 vel = this.player.body.getLinearVelocity();
    if (vel.x < MAX_VELOCITY) {
         circle.applyLinearImpulse(impulse.x, impulse.y, pos.x, pos.y, wake);
    

    其中impulse.xfloat,定义应用在x 方向的脉冲强度,impulse.y 与y 方向相同,pos.xpos.y 是您想要的位置应用impulse(如果不是中心,身体会得到一些torque-效果)和boolean wake 定义,如果body 应该唤醒。

    【讨论】:

      猜你喜欢
      • 2016-06-04
      • 2015-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多