将速度矢量添加到位置矢量时,速度矢量趋于无穷大

时间:2016-12-21 17:08:45

标签: java vector libgdx

我正在使用LibGdx处理一些代码。我有实体代码,它使用更新和一个输入适配器,它可以在按键时添加速度矢量。在调试期间,我注意到当将速度矢量添加到位置矢量时,速度在片刻之后变为无穷大。代码可以在下面找到:

InputAdapter:

@Override
        public boolean keyDown(int keycode) {
            switch (keycode) {
                case Input.Keys.UP:
                    e.getVelocity().add(0,1);
                    break;
                case Input.Keys.DOWN:
                    e.getVelocity().add(0,-1);
                    break;
                case Input.Keys.LEFT:
                    e.getVelocity().add(-1,0);
                    break;
                case Input.Keys.RIGHT:
                    e.getVelocity().add(1,0);
                    break;
            }
            return true;
        }

        @Override
        public boolean keyUp(int keycode) {
            switch (keycode) {
                case Input.Keys.UP:
                    e.getVelocity().sub(0,1);
                    break;
                case Input.Keys.DOWN:
                    e.getVelocity().sub(0,-1);
                    break;
                case Input.Keys.LEFT:
                    e.getVelocity().sub(-1,0);
                    break;
                case Input.Keys.RIGHT:
                    e.getVelocity().sub(1,0);
                    break;
            }
            return true;
        }

游戏类:

SpriteBatch batch;
Map<UUID,Entity> entities = new HashMap<>();
@Override
public void create () {
    batch = new SpriteBatch();
    Entity e = new Entity(UUID.randomUUID(),new Texture("avatar.png"),Vector2.Zero,Vector2.Zero);
    entities.put(e.getId(),e);
    Gdx.input.setInputProcessor(new InputAdapter(){...});
}

@Override
public void render () {
    entities.values().forEach(Entity::update);
    Gdx.gl.glClearColor(1, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    entities.values().forEach(e->e.draw(batch));
    batch.end();
}

@Override
public void dispose () {
    batch.dispose();
    entities.values().forEach(Entity::dispose);
    entities.clear();
}

实体类:

 private UUID id;
private Texture texture;
private Vector2 position;
private Vector2 velocity;

public Entity(UUID id, Texture texture, Vector2 position, Vector2 velocity) {
    this.id = id;
    this.texture = texture;
    this.position = position;
    this.velocity = velocity;
}

public UUID getId() {
    return id;
}

public Texture getTexture() {
    return texture;
}

public Vector2 getPosition() {
    return position;
}

public void setPosition(Vector2 position) {
    this.position = position;
}

public Vector2 getVelocity() {
    return velocity;
}

public void setVelocity(Vector2 velocity) {
    this.velocity = velocity;
}

public void draw(SpriteBatch batch) {
    batch.draw(texture,getPosition().x,getPosition().y);
}

public void dispose() {
    texture.dispose();
}

public void update() {
    System.out.println(getVelocity());
    getPosition().add(getVelocity());
}

输出(按下一次向下键):

(0.0,0.0)
(0.0,-1.0)
(0.0,-2.0)
(0.0,-4.0)
(0.0,-8.0)
(0.0,-15.0)
(0.0,-30.0)
(0.0,-60.0)
(0.0,-120.0)
(0.0,-240.0)
(0.0,-480.0)
(0.0,-960.0)
(0.0,-1920.0)
(0.0,-3840.0)
(0.0,-7680.0)
(0.0,-15360.0)
(0.0,-30720.0)
(0.0,-61440.0)
(0.0,-122880.0)
(0.0,-245760.0)
(0.0,-491520.0)
(0.0,-983040.0)
(0.0,-1966080.0)
(0.0,-3932160.0)
(0.0,-7864320.0)
(0.0,-1.572864E7)
(0.0,-3.145728E7)
(0.0,-6.291456E7)
(0.0,-1.2582912E8)
(0.0,-2.5165824E8)
(0.0,-5.0331648E8)
(0.0,-1.00663296E9)
(0.0,-2.01326592E9)
(0.0,-4.02653184E9)
(0.0,-8.0530637E9)
(0.0,-1.61061274E10)
(0.0,-3.22122547E10)
(0.0,-6.4424509E10)
(0.0,-1.28849019E11)
(0.0,-2.57698038E11)
(0.0,-5.15396076E11)
(0.0,-1.03079215E12)
(0.0,-2.0615843E12)
(0.0,-4.1231686E12)
(0.0,-8.2463372E12)
(0.0,-1.64926744E13)
(0.0,-3.29853488E13)
(0.0,-6.5970698E13)
(0.0,-1.31941395E14)
(0.0,-2.63882791E14)
(0.0,-5.27765581E14)
(0.0,-1.05553116E15)
(0.0,-2.11106233E15)
(0.0,-4.22212465E15)
(0.0,-8.4442493E15)
(0.0,-1.68884986E16)
(0.0,-3.37769972E16)
(0.0,-6.7553994E16)
(0.0,-1.35107989E17)
(0.0,-2.70215978E17)
(0.0,-5.40431955E17)
(0.0,-1.08086391E18)
(0.0,-2.16172782E18)
(0.0,-4.32345564E18)
(0.0,-8.6469113E18)
(0.0,-1.7293823E19)
(0.0,-3.4587645E19)
(0.0,-6.917529E19)
(0.0,-1.3835058E20)
(0.0,-2.7670116E20)
(0.0,-5.5340232E20)
(0.0,-1.10680464E21)
(0.0,-2.2136093E21)
(0.0,-4.4272186E21)
(0.0,-8.854437E21)
(0.0,-1.7708874E22)
(0.0,-3.5417749E22)
(0.0,-7.0835497E22)
(0.0,-1.4167099E23)
(0.0,-2.8334199E23)
(0.0,-5.6668398E23)
(0.0,-1.13336796E24)
(0.0,-2.2667359E24)
(0.0,-4.5334718E24)
(0.0,-9.0669436E24)
(0.0,-1.8133887E25)
(0.0,-3.6267775E25)
(0.0,-7.253555E25)
(0.0,-1.450711E26)
(0.0,-2.901422E26)
(0.0,-5.802844E26)
(0.0,-1.1605688E27)
(0.0,-2.3211376E27)
(0.0,-4.642275E27)
(0.0,-9.28455E27)
(0.0,-1.85691E28)
(0.0,-3.71382E28)
(0.0,-7.42764E28)
(0.0,-1.485528E29)
(0.0,-2.971056E29)
(0.0,-5.942112E29)
(0.0,-1.1884224E30)
(0.0,-2.3768449E30)
(0.0,-4.7536898E30)
(0.0,-9.5073795E30)
(0.0,-1.9014759E31)
(0.0,-3.8029518E31)
(0.0,-7.6059036E31)
(0.0,-1.5211807E32)
(0.0,-3.0423614E32)
(0.0,-6.084723E32)
(0.0,-1.2169446E33)
(0.0,-2.4338892E33)
(0.0,-4.8677783E33)
(0.0,-9.7355566E33)
(0.0,-1.9471113E34)
(0.0,-3.8942226E34)
(0.0,-7.7884453E34)
(0.0,-1.5576891E35)
(0.0,-3.1153781E35)
(0.0,-6.2307562E35)
(0.0,-1.24615125E36)
(0.0,-2.4923025E36)
(0.0,-4.984605E36)
(0.0,-9.96921E36)
(0.0,-1.993842E37)
(0.0,-3.987684E37)
(0.0,-7.975368E37)
(0.0,-1.5950736E38)
(0.0,-3.1901472E38)
(0.0,-Infinity)
(0.0,-Infinity)
(0.0,-Infinity)
(0.0,-Infinity)
(0.0,-Infinity)
(0.0,-Infinity)
(0.0,-Infinity)

我不确定为什么速度矢量正在增加,因为它被修改的唯一时间是在keydown事件期间。如果有人能够解释为什么会发生这种情况,那将会非常有用!

1 个答案:

答案 0 :(得分:1)

在Java中,没有不可变对象这样的东西。您已将静态对象实例Vector2.Zero的两个副本传递给每个新实体。因此,无论何时按某个键,您都要向Vector2.Zero添加一个值,每当您更新实体时,您都会多次向自己添加Vector2.Zero的新值,因为每个实体都会引用相同的实例对象

创建Entity类的一种安全方法是让它实例化自己的final Vector2实例:

public class Entity {

    private UUID id;
    private Texture texture;
    private final Vector2 position = new Vector2();
    private final Vector2 velocity = new Vector2();

    public Entity(UUID id, Texture texture) {
        this.id = id;
        this.texture = texture;
    }

    //...
}

此外,当它们都使用相同的图像时,为实体的每个实例实例化一个新的Texture对象并不是一个好主意。您正在以冗余方式将完全相同的图像数据的许多副本加载到GPU。加载纹理一次并将相同的实例传递给所有实体,并且不要忘记在dispose()方法中处理它。不要在实体的处置方法中处理它,因为它会被多次处理(实体不会自己&#34;纹理,因为它没有&#39;实例化它。)