我正在使用PlayN构建一个涉及石头的游戏,用户必须在物理世界中移动(有重力等)我希望用户能够使用触摸板直接操作石头并给他们一个速度拖拽它们。
现在我有一个实现,其中每块石头都在他自己的层上,我在石头层上有一个监听器,可以停用这个石头体的物理(当用户抓住它时)并在拖动完成后重新激活。
问题是监听器回调似乎是延迟执行的,这意味着在重新激活物理引擎之前会显示许多帧,导致用户停止抓取后石头的延迟。
此类行为还有其他方法吗?我错过了什么吗?
谢谢!
layer.addListener(new Pointer.Adapter() {
@Override
public void onPointerStart(Event event) {
suspendPhysik = true;
getBody().setActive(!suspendPhysik);
}
@Override
public void onPointerEnd(Event event) {
suspendPhysik = false;
getBody().setActive(!suspendPhysik);
long deltatime = System.currentTimeMillis() - prevTimestamp;
Vec2 velocity = new Vec2((event.x()
* NewGame.physUnitPerScreenUnit - prevX)
/ deltatime,
(event.y() * NewGame.physUnitPerScreenUnit - prevX)
* NewGame.physUnitPerScreenUnit / deltatime);
getBody().setLinearVelocity(velocity);
}
@Override
public void onPointerDrag(Event event) {
x = event.x() * NewGame.physUnitPerScreenUnit;
y = event.y() * NewGame.physUnitPerScreenUnit;
setPos(event.x() * NewGame.physUnitPerScreenUnit, event.y()
* NewGame.physUnitPerScreenUnit);
}
});`
答案 0 :(得分:1)
发现了一个关于playN的有趣演讲。
http://playn-2011.appspot.com/slides/index.html#34
在示例中,作者使用以下代码:
touch().setListener(new Touch.Adapter() {
@Override
public void onTouchStart(Event[] touches) {
// Process touch events into a zoom start position.
}
@Override
public void onTouchMove(Event[] touches) {
// Update zoom based on touches.
}
});
此链接包含Touch.Adapter的文档 http://docs.playn.googlecode.com/git/javadoc/playn/core/Touch.Adapter.html#Touch.Adapter()
所以试试这个:
layer.addListener(new Touch.Adapter() {
@Override
public void onTouchStart(Touch.Event[] touches) {
suspendPhysik = true;
getBody().setActive(!suspendPhysik);
}
@Override
public void onTouchMove(Touch.Event[] touches) {
suspendPhysik = false;
getBody().setActive(!suspendPhysik);
long deltatime = System.currentTimeMillis() - prevTimestamp;
Vec2 velocity = new Vec2((touches[0].x() * NewGame.physUnitPerScreenUnit - prevX) / deltatime, (event.y() * NewGame.physUnitPerScreenUnit - prevX) * NewGame.physUnitPerScreenUnit / deltatime);
getBody().setLinearVelocity(velocity);
}
@Override
public void onTouchMove(Touch.Event[] touches)
{
x = touches[0].x() * NewGame.physUnitPerScreenUnit;
y = touches[0].y() * NewGame.physUnitPerScreenUnit;
setPos(x * NewGame.physUnitPerScreenUnit, y * NewGame.physUnitPerScreenUnit);
}
});
答案 1 :(得分:0)
我发现处理此类问题的最佳方法实际上是在Box2d中使用MouseJoint。 暂停物理不是正确的方法,因为它打破了模拟(除其他事项外,不会考虑碰撞的身体)
我会发布一些我发现解释不同可能方法的链接......