0

I am using PlayN to build a game involving stone a user has to move in a physic world (with gravity etc.) I want the user to be able to manipulate directly the stones using the touch pad and give them a velocity by dragging and throwing them.

For now I have an implementation where every stone is on his own layer and I have a listener on the stone layer that would deactivate the physics for this stone body (when the user grabs it) and reactivate once the drag is finished.

The problem is the listener callback seems to be executed with a delay meaning that many frames are displayed before reactivation of the physics engine is taken into account leading to delay in the stone falling after the user stopped the grabbing.

Are there other approaches for such behaviors ? Am I missing something ?

Thanks !

  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);
        }

    });`
bambata
  • 313
  • 1
  • 5

2 Answers2

1

Found an interesting presentation about playN.

http://playn-2011.appspot.com/slides/index.html#34

In the example the author uses following code:

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.
    }              
});

This link contains the docs for the Touch.Adapter http://docs.playn.googlecode.com/git/javadoc/playn/core/Touch.Adapter.html#Touch.Adapter()

So try this:

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);
    }   
  });
bpichon
  • 46
  • 4
0

The best way I found to handle this type of problem is actually to use a MouseJoint in Box2d. Suspending the physic is not the correct approach as it breaks the simulation (among other things, the body will not be taken into account for collisions)

I will post some links I found explaining the different possible approaches...

bambata
  • 313
  • 1
  • 5