我目前正在使用LibGDX在我的游戏中实现一个简单的重力系统。但是,我发现将向量与向量和向量与标量相乘的方式有点不同。
在Unity中,我会像这样实施引力:
public Vector3 velocity;
public Vector3 acceleration;
private void FixedUpdate()
{
transform.position += velocity*Time.fixedDeltaTime;
Vector3 force = Physics.gravity*GetComponent<Rigidbody>().mass;
acceleration = force/GetComponent<Rigidbody>().mass;
velocity = velocity + acceleration*Time.fixedDeltaTime;
}
}
矢量乘法非常简单。
在LibGDX中,我正在尝试以下方法:
import com.badlogic.gdx.math.Vector2;
final protected Vector2 _gravity = new Vector2(0f, -9.82f);
final protected float _mass = 1f;
protected Vector2 _velocity;
protected Vector2 _acceleration;
public void Update(float deltaTime)
{
// Transform is a class containing a Vector2 called Position
Transform.Position.add(_velocity.scl(deltaTime));
Vector2 force = _gravity.scl(_mass);
_acceleration = force.scl(1f/_mass);
_velocity = _velocity.add(_acceleration.scl(deltaTime));
System.out.println(_velocity);
// _velocity gets smaller and smaller and finally hits 0.
}
这不起作用,因为Vector2的 scl()方法直接改变了向量本身,如在LibGDX的Vector2类中可以看到的那样:
public Vector2 scl (float scalar) {
x *= scalar;
y *= scalar;
return this;
}
我认为我希望它返回 new Vector2,而不是直接更改矢量本身。
我该怎么做?还是我完全错了?使用&#34; *&#34;在LibGDX中有一种更简单的方法可以将向量与标量相乘吗?操作
答案 0 :(得分:3)
Vector2 force = _gravity.cpy().scl(_mass);
cpy()
方法返回向量的副本,因此您最终将副本乘以_mass
而不是原始向量。
与使用new Vector2()
创建副本相比,此解决方案的一个细微优点是它适用于任何矢量维度而无需修改。
答案 1 :(得分:2)
方法(和其他人)不创建新向量的原因是为了避免创建垃圾。创建垃圾会导致垃圾收集器清理,这可能(并且会)导致垃圾收集。对于游戏来说,经常需要避免频繁的蠢事。
因此,如果它只需要一次,那么可以使用cpy()
方法或new
关键字。但是对于经常调用的方法(比如你的更新方法),你真的想避免这种情况。相反,您可以使用成员向量。
final Vector2 force = new Vector2();
public void update(float delta) {
...
force.set(_gravity).scl(mass);
...
}
请注意,对于position += velocity * time
等操作,您可以使用mulAdd
方法。
position.mulAdd(velocity, deltaTime);
答案 2 :(得分:0)
您可以尝试在缩放之前复制矢量,如下所示:
new Vector2(_gravity).scl(_mass);