Java 使用Box2D应用Y线性脉冲时X速度减慢
我使用libgdx和box2d作为我的物理引擎。现在我有一个非常简单的盒子,在一个平面上进行控制: 一切似乎都很顺利。我用箭头键控制这个盒子。如果我按下向右箭头,盒子将向右加速。当我按下向上箭头时,盒子会跳起来但出乎意料的是,当盒子跳跃时,它的x速度减慢。有人能告诉我为什么会这样以及如何解决吗? 仅使用一些Box2d设置的播放器对象:Java 使用Box2D应用Y线性脉冲时X速度减慢,java,libgdx,box2d,Java,Libgdx,Box2d,我使用libgdx和box2d作为我的物理引擎。现在我有一个非常简单的盒子,在一个平面上进行控制: 一切似乎都很顺利。我用箭头键控制这个盒子。如果我按下向右箭头,盒子将向右加速。当我按下向上箭头时,盒子会跳起来但出乎意料的是,当盒子跳跃时,它的x速度减慢。有人能告诉我为什么会这样以及如何解决吗? 仅使用一些Box2d设置的播放器对象: public class Player extends Entity { private static BodyDef createBodyDef() {
public class Player extends Entity {
private static BodyDef createBodyDef() {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.fixedRotation = true;
bodyDef.position.set(100, 200);
return bodyDef;
}
public Player(World world) {
super(world, createBodyDef(), Textures.rectangle(Units.m2P(0.7f), Units.m2P(2f), Color.RED));
FixtureDef fixtureDef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(50, 50, new Vector2(50, 50), 0f);
fixtureDef.shape = shape;
fixtureDef.friction = 0.1f;
getBody().createFixture(fixtureDef);
MassData massData = new MassData();
massData.mass = 90f;
getBody().setMassData(massData);
}
}
public class GameScreen extends BaseScreen implements InputProcessor {
private final World world = new World(new Vector2(0, -200), false);
private final GameView view = new GameView();
private final List<Entity> entities = new ArrayList<Entity>();
private final Player player = new Player(world);
private final List<Integer> pressedKeys = new ArrayList<Integer>();
public GameScreen() {
entities.add(player);
view.setFollowEntity(player);
MapBodyBuilder.buildShapes(view.getTiledMap(), 1, world);
}
@Override public void show() {
super.show();
Gdx.input.setInputProcessor(this);
}
@Override public void render(float delta) {
super.render(delta);
float forceX = 0f;
float forceY = 0f;
float force = 15000;
if (pressedKeys.contains(Input.Keys.LEFT)) {
forceX -= force;
}
if (pressedKeys.contains(Input.Keys.RIGHT)) {
forceX += force;
}
if (pressedKeys.contains(Input.Keys.DOWN)) {
forceY -= force;
}
player.getBody().applyForceToCenter(forceX, forceY, false);
world.step(delta, 5, 5);
view.render(entities);
}
@Override public void resize(int width, int height) {
super.resize(width, height);
}
@Override public void hide() {
super.hide();
Gdx.input.setInputProcessor(null);
}
@Override public void dispose() {
super.dispose();
world.dispose();
for (Entity entity : entities) {
entity.dispose();
}
}
@Override public boolean keyDown(int keycode) {
if (keycode == Input.Keys.UP) {
Body body = player.getBody();
body.applyLinearImpulse(new Vector2(0, 30000), body.getWorldCenter(), true);
}
pressedKeys.add(keycode);
return false;
}
@Override public boolean keyUp(int keycode) {
pressedKeys.remove((Integer) keycode);
return false;
}
@Override public boolean keyTyped(char character) {
return false;
}
@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) {
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;
}
public Player getPlayer() {
return player;
}
}
游戏屏幕:
public class Player extends Entity {
private static BodyDef createBodyDef() {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.fixedRotation = true;
bodyDef.position.set(100, 200);
return bodyDef;
}
public Player(World world) {
super(world, createBodyDef(), Textures.rectangle(Units.m2P(0.7f), Units.m2P(2f), Color.RED));
FixtureDef fixtureDef = new FixtureDef();
PolygonShape shape = new PolygonShape();
shape.setAsBox(50, 50, new Vector2(50, 50), 0f);
fixtureDef.shape = shape;
fixtureDef.friction = 0.1f;
getBody().createFixture(fixtureDef);
MassData massData = new MassData();
massData.mass = 90f;
getBody().setMassData(massData);
}
}
public class GameScreen extends BaseScreen implements InputProcessor {
private final World world = new World(new Vector2(0, -200), false);
private final GameView view = new GameView();
private final List<Entity> entities = new ArrayList<Entity>();
private final Player player = new Player(world);
private final List<Integer> pressedKeys = new ArrayList<Integer>();
public GameScreen() {
entities.add(player);
view.setFollowEntity(player);
MapBodyBuilder.buildShapes(view.getTiledMap(), 1, world);
}
@Override public void show() {
super.show();
Gdx.input.setInputProcessor(this);
}
@Override public void render(float delta) {
super.render(delta);
float forceX = 0f;
float forceY = 0f;
float force = 15000;
if (pressedKeys.contains(Input.Keys.LEFT)) {
forceX -= force;
}
if (pressedKeys.contains(Input.Keys.RIGHT)) {
forceX += force;
}
if (pressedKeys.contains(Input.Keys.DOWN)) {
forceY -= force;
}
player.getBody().applyForceToCenter(forceX, forceY, false);
world.step(delta, 5, 5);
view.render(entities);
}
@Override public void resize(int width, int height) {
super.resize(width, height);
}
@Override public void hide() {
super.hide();
Gdx.input.setInputProcessor(null);
}
@Override public void dispose() {
super.dispose();
world.dispose();
for (Entity entity : entities) {
entity.dispose();
}
}
@Override public boolean keyDown(int keycode) {
if (keycode == Input.Keys.UP) {
Body body = player.getBody();
body.applyLinearImpulse(new Vector2(0, 30000), body.getWorldCenter(), true);
}
pressedKeys.add(keycode);
return false;
}
@Override public boolean keyUp(int keycode) {
pressedKeys.remove((Integer) keycode);
return false;
}
@Override public boolean keyTyped(char character) {
return false;
}
@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) {
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;
}
public Player getPlayer() {
return player;
}
}
公共类GameScreen扩展BaseScreen实现InputProcessor{
私有最终世界=新世界(新向量2(0,-200),假);
私有最终GameView视图=新GameView();
私有最终列表实体=新的ArrayList();
私人决赛选手=新选手(世界);
private final List pressedKeys=new ArrayList();
公共游戏屏幕(){
实体。添加(玩家);
view.setfollownity(播放器);
MapBodyBuilder.buildShapes(view.getTiledMap(),1,world);
}
@覆盖公共void show(){
super.show();
Gdx.input.setInputProcessor(此);
}
@替代公共无效渲染(浮动增量){
超级渲染(delta);
浮动力x=0f;
浮动力y=0f;
浮力=15000;
if(按Keys.contains(Input.Keys.LEFT)){
力-=力;
}
if(按Keys.contains(Input.Keys.RIGHT)){
力X+=力;
}
如果(按按键。包含(输入。按键。向下)){
力-=力;
}
player.getBody().applyForceToCenter(forceX,forceY,false);
世界台阶(三角洲,5,5);
视图。渲染(实体);
}
@替代公共空心调整大小(整型宽度、整型高度){
超级。调整大小(宽度、高度);
}
@覆盖公共void hide(){
super.hide();
Gdx.input.setInputProcessor(null);
}
@重写公共void dispose(){
super.dispose();
世界。处置();
for(实体:实体){
entity.dispose();
}
}
@覆盖公共布尔键关闭(int-keycode){
if(keycode==Input.Keys.UP){
Body Body=player.getBody();
applylinearpulse(新向量2(0,30000),body.getWorldCenter(),true);
}
按按键。添加(按键代码);
返回false;
}
@重写公共布尔键控(int-keycode){
按按键。删除((整数)键码);
返回false;
}
@重写公共布尔键类型(字符字符){
返回false;
}
@覆盖公共布尔接地(int screenX、int screenY、int指针、int按钮){
返回false;
}
@覆盖公共布尔补色(int screenX、int screenY、int指针、int按钮){
返回false;
}
@重写公共布尔值(int-screenX、int-screenY、int-pointer){
返回false;
}
@覆盖公共布尔mouseMoved(int-screenX,int-screenY){
返回false;
}
@覆盖已滚动的公共布尔值(整数金额){
返回false;
}
公共播放器getPlayer(){
返回球员;
}
}
查看移动机构的工作原理:
if (keycode == Input.Keys.UP)
{
Body body = player.getBody();
body.applyLinearImpulse(new Vector2(0, 30000), body.getWorldCenter(), true);
}
做点像
if (keycode == Input.Keys.UP)
{
jumpForce = 30000; //jumpForce is variable of GameScreen class
}
然后在渲染方法中
...
if (pressedKeys.contains(Input.Keys.DOWN))
{
forceY -= force;
}
forceY += jumpForce; //here you add the jump force
player.getBody().applyForceToCenter(forceX, forceY, false);
jumpForce = 0; //but only once - in next iteration od render it will be avoided till UP key will be pressed again
当然,你可以考虑你自己的机制,但这是正确的方向