I posted recently and got some great suggestions and I’m hoping I could get some further input
I’m trying to drag a sprite and have it rotate to line up with the direction of the mouse cursor, I have my drag event handlers setup as shown in the code snippet below:
// Center the object on the cursor on drag start 'pick up'
this.input.on('dragstart', function (pointer, gameObject) {
gameObject.x = pointer.x
gameObject.y = pointer.y
});
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
var points = pointer.getInterpolatedPosition(30);
// Smoothly draw a point for each interpolated position, stops scattering effect
points.forEach(function (p) {
// Points should be drawn on the 'tip', so need to offset
rt.draw(point, p.x, p.y - 28);
rt.draw(point, p.x + 16, p.y - 28);
rt.draw(point, p.x - 16, p.y - 28);
});
// Rotate the object on drag
p1x = gameObject.x
p1y = gameObject.y
p2x = pointer.x
p2y = pointer.y
dx = p2x - p1x
dy = p2y - p1y
let targetRad = Math.atan2(dy, dx)
targetRad += (Math.PI/2) // Phaser uses rh clockwise rotation (0 = right) so offset
gameObject.rotation = targetRad
// Move the object on drag
gameObject.x = pointer.x
gameObject.y = pointer.y
});
This works however it seems quite erratic especially at lower speeds and I’d like to smooth it out if possible, .gif below should give some ideas.
As the distance between object/cursor increases I get a smoother rotation which makes sense and i’ve tried limiting rotation to only apply once that distance is some arbitrary value but this hinders things when you want to slowly drag the object as rotation isn’t applied
Would anyone have any ideas/suggestions or is there some function already part of Phaser that handles this?
Worst case I could lock the rotation to fixed directions like compass points depending on where the angle falls but I’d really like something more natural looking
RotateTo seems to help a little, but I think the issue is the cursor being too close to the center and the calculated angle coming out too large, if you have only a 1 pixel distance then you’re only going to get angles relating to the 8 possible points surrounding the center
I like the idea of pushing the point of rotation away from the cursor, will give that a shot and report back
I did try only moving once the magnitude between center/cursor is greater than an arbitrary value - helped with the rotation but movement became choppy as it’d only redraw once that distance was reached, even pushing the position updates into the interpolated points loop didnt seem to help
Might be worth another try though, is there an equivalent of RotateTo but for movement that could more smoothly move the object to a the cursor point?
Tried it and unfortunately I end up with no rotation at very low drag speeds (threshold never hit) or choppy rotation at ‘medium’ drag speeds where the cursor occasionally hits the threshold
If I get an hour this evening I’ll give the offset rotation point a test, not had chance today
Another idea I might try is reducing the applied rotation by some factor depending on the distance, to ‘dampen’ it a at short distances, I could just adjust the delta in rotateTo to something really small
You might try using pointer.angle or pointer.velocity instead. pointer.angle is noisy at low speeds, but it will act the same no matter where the cursor is placed relative to the sprite.
Can give it a shot but how do you access pointer.angle?
It doesn’t seem to be an available property in the callback pointer, looks like there is a prevPosition though so I guess you could calculate it yourself
Not sure if the documentation is off or I’m misunderstanding, it talks about using InputPlugin.activePointer to access the reference but this seems instead to be input.manager.activePointer