I am using the JS port of Chipmunk2D in my game engine, and so far it is working great.
My only issue so far is trying to do top down player movement via a control body. I am getting some jumpy, micro-teleportation effects as the player moves around.
Code and more details can be found on my github issue post: https://github.com/josephg/Chipmunk-js/issues/26
I was using the frame-time as my time-step for the space.step() function, and when I changed it to a constant the issue became much less prevalent but still happens. I have narrowed it down to actual body position changes (not fps or some other issue). If you have any ideas as to what the issue is or need more info please let me know!
Thanks!
-Chad
Jumpy Player Movement
-
- Posts: 29
- Joined: Wed May 09, 2012 12:06 am
- Contact:
Re: Jumpy Player Movement
You may also want to add interpolation between the last position/rotation and the current position/rotation when rendering in case you get multiple frames between physics steps.
-
- Posts: 3
- Joined: Fri Jan 24, 2014 1:01 pm
- Contact:
Re: Jumpy Player Movement
Yeah I thought this was gone, but it is definately still happening even with my physics running separately.
I'm not sure how I can know how much to interpolate when setting the new position? As you can see there is no interpolation now:
How can I know the step to use for an interpolation to the next value? I tried this:
Where `step` is my constant step value (which is 1/60 btw). But there is a still a noticeable teleportation effect, it didn't seem to help very much
I'm not sure how I can know how much to interpolate when setting the new position? As you can see there is no interpolation now:
Code: Select all
//go through each changed shape
space.activeShapes.each(function(shape) {
var spr = shape.sprite; //I set this when the shape is created so I have the ref here
spr.position.x = shape.body.p.x;
spr.position.y = shape.body.p.y;
spr.rotation = shape.body.a;
});
Code: Select all
var step = this.stepTime,
stepInv = 1 - step;
//execute the physics step
this.space.step(step);
//go through each changed shape
space.activeShapes.each(function(shape) {
var spr = shape.sprite; //I set this when the shape is created so I have the ref here
spr.position.x = (spr.position.x * step) + (shape.body.p.x * stepInv);
spr.position.y = (spr.position.y * step) + (shape.body.p.y * stepInv);
spr.rotation = (spr.rotation * step) + (shape.body.a * stepInv);
});
-
- Posts: 29
- Joined: Wed May 09, 2012 12:06 am
- Contact:
Re: Jumpy Player Movement
You should be interpolating between physics steps since that's where your discrete movement is currently happening. Even with a high number of steps, it's always going to "jump" between steps because the calculations are only obtaining an instantaneous result.
Basically you'll want to remember the last position & rotation for each physics body before any of them are updated. You calculate the interpolation value based on the elapsed time between physics steps. Since your step is 1/60, you simply divide the elapsed time by (1/60) to get the result. Then simply use that result to calculate the linear-interpolation of the position and rotation. If the result is > 1 then you need to run a new physics step. The idea here is that the interpolation will match the time that the frames are rendered and you should not expect those to happen at a regular interval (although ideally they do).
Your choice of timer is also important. If you're on Windows, GetTickCount typically has a resolution worse than 15ms which means that you won't get very accurate times; you'll want to use something like QueryPerformanceCounter instead.
Basically you'll want to remember the last position & rotation for each physics body before any of them are updated. You calculate the interpolation value based on the elapsed time between physics steps. Since your step is 1/60, you simply divide the elapsed time by (1/60) to get the result. Then simply use that result to calculate the linear-interpolation of the position and rotation. If the result is > 1 then you need to run a new physics step. The idea here is that the interpolation will match the time that the frames are rendered and you should not expect those to happen at a regular interval (although ideally they do).
Your choice of timer is also important. If you're on Windows, GetTickCount typically has a resolution worse than 15ms which means that you won't get very accurate times; you'll want to use something like QueryPerformanceCounter instead.
-
- Posts: 3
- Joined: Fri Jan 24, 2014 1:01 pm
- Contact:
Re: Jumpy Player Movement
Thanks Lego!
This has solved my issue now that I am interpolating correctly. As far as timer accuracy, note that this is in JavaScript so my choices are limited.
Thanks again for the help!
-Chad
This has solved my issue now that I am interpolating correctly. As far as timer accuracy, note that this is in JavaScript so my choices are limited.
Thanks again for the help!
-Chad
Who is online
Users browsing this forum: No registered users and 7 guests