大家好,所以我试图在libgdx中制作这个简单的游戏,一切都很好,直到我注意到我需要施加一个强大的力量才能使玩家移动一点点有没有办法让它需要更少的力量? 这是我渲染播放器的PlayScreen。 `
private Logang game;
//basic playscreen variables
private OrthographicCamera gamecam;
private Viewport gamePort;
//Box2d variables
private World world;
private Box2DDebugRenderer b2dr;
boolean drawn = true;
private Player p;
private int pX = 100, pY = 300;
public GameScreen(Logang game) {
this.game = game;
//create cam used to follow mario through cam world
gamecam = new OrthographicCamera();
gamecam.update();
Box2D.init();
//create our Box2D world, setting no gravity in X, -10 gravity in Y, and allow bodies to sleep
world = new World(new Vector2(0, Logang.GRAVITY), true);
//allows for debug lines of our box2d world.
b2dr = new Box2DDebugRenderer();
//create a FitViewport to maintain virtual aspect ratio despite screen size
gamePort = new ScalingViewport(Scaling.fill, Logang.GWIDTH, Logang.GHEIGHT, gamecam);
p = new Player(new Sprite(new Texture("hud_p3.png")), world, pX, pY, 1);
//initially set our gamcam to be centered correctly at the start of of map
gamecam.position.set(gamePort.getWorldWidth() / 2 , gamePort.getWorldHeight() / 2, 0);
line();
}
@Override
public void show() {
}
public void update(float dt) {
//handle user input first
p.update(dt);
//update our gamecam with correct coordinates after changes
}
@Override
public void render(float delta) {
//separate our update logic from render
update(delta);
//Clear the game screen with Black
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1f / 60f, 6, 2);
gamecam.position.set(p.getSprite().getX(),Logang.GHEIGHT / 2, 0); // x and y could be changed by Keyboard input for example
gamecam.update();
game.getBatch().setProjectionMatrix(gamecam.combined);
//renderer our Box2DDebugLines
b2dr.render(world, gamecam.combined);
System.out.println("Player x: " + p.getSprite().getX() + " Camera X: " + gamecam.position.x + " Body X: " + p.getBody().getPosition().x);
//System.out.println("Player y: " + p.getSprite().getY() + " Camera Y: " + gamecam.position.y + " Body Y: " + p.getBody().getPosition().y);
game.getBatch().begin();
if (p.getBody() != null)
p.render(game.getBatch());
EntityManager.renderTerra(game.getBatch(), delta);
game.getBatch().end();
}
public void line() {
Texture tmp = new Texture("hud_p3.png");
tmp.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
for (int i = 0; i < 50; i++) {
EntityManager.add(new Ground(new Sprite(tmp), world, (int)(i * Logang.TILE), 1, 2));
}
// EntityManager.changeSize(((Logang.TILE) * 5),Logang.TILE);
}
@Override
public void resize(int width, int height) {
//updated our game viewport
gamePort.update(width, height);
}
public World getWorld() {
return world;
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void hide() {
}
@Override
public void dispose() {
world.dispose();
b2dr.dispose();
}`
这是我的实体类,由播放器扩展
private World world;
private Sprite sprite;
private Body body;
private int tipo;
public Entity(Sprite sprite, World world, int x, int y, int tipo){
this.sprite = sprite;
this.world = world;
getSprite().setPosition(x, y);
getSprite().setSize(Logang.TILE , Logang.TILE);
define(tipo);
this.tipo = tipo;
}
public void update(float dt){
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
getBody().applyLinearImpulse(new Vector2(-Logang.PPM,0f), getBody().getWorldCenter(), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
getBody().applyLinearImpulse(new Vector2(Logang.PPM,0f), getBody().getWorldCenter(), true);
}
if(Gdx.input.isKeyPressed(Input.Keys.SPACE)){
getBody().applyLinearImpulse(0f,-Logang.GRAVITY * Logang.PPM, getBody().getPosition().x, getBody().getPosition().y, true);
}
}
}
public void define(int tipo){
BodyDef bdef = new BodyDef();
bdef.position.set((getSprite().getX() + getSprite().getWidth() / 2), (getSprite().getY() + getSprite().getHeight() / 2));
switch(tipo){
case 1: {
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
case 2:{
bdef.type = BodyDef.BodyType.StaticBody;
break;
}
case 3:{
bdef.type = BodyDef.BodyType.DynamicBody;
break;
}
}
body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(getSprite().getWidth() / 2, getSprite().getHeight() / 2);
fdef.shape = shape;
body.createFixture(fdef);
body.setUserData(this);
shape.dispose();
}
public void render(SpriteBatch batch){
if(tipo != 2) {
float posX = getBody().getPosition().x;
float posY = getBody().getPosition().y;
getSprite().setPosition(posX - getSprite().getWidth() / 2, posY - getSprite().getHeight() / 2);
}
getSprite().draw(batch);
}
public Sprite getSprite() {
return sprite;
}
public void setSprite(Sprite sprite) {
this.sprite = sprite;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
}
感谢大家的回答
答案 0 :(得分:1)
Box2D是一个物理引擎,所以试图模仿游戏中的真实物理。因此,如果您的物体很大且很重,则需要大量的力才能移动它。
为了使你的物体可以用较小的力量移动,你可以使它们变小或改变它们的密度,使它们更轻,这样可以用较小的力量移动它们。
要更改您在fixtureDefinition中设置的密度
FixtureDef fdef = new FixtureDef();
fdef.density=0.1f; // (weight: range 0.01 to 1 is good)
fdef.friction = 0.7f; // (how slippery it is: 0=like ice 1 = like rubber)
fdef.restitution = 0.3f; //(how bouncy is it 0= not bouncy 1 = 100% bouncy)
我注意到的另一件事是你在这一行中使用了似乎是PixelPerMeter比率的力量:
getBody().applyLinearImpulse(new Vector2(-Logang.PPM,0f), getBody().getWorldCenter(), true);
你不应该将这个值用于你的力量,因为这是用于将box2d世界转换为渲染坐标,你可以使用以下代码将力量应用到中心。
getBody().applyLinearImpulse(new Vector2((10f*getBody().getMass()),0f), getBody().getWorldCenter(), true);
作为旁注,冲动用于创建单个力的应用,而body.applyForceToCenter(强制,唤醒);用于随时间推移施加恒定力。尝试使用apply force方法,看看是否有帮助。