Camera Jumps on first drag

JeanSwamp

Member
Hello,

I have a very simple drag system for my camera, with a setup as such:

Create:
GML:
position_x = 0;
position_y = 0;
new_room_x = 0;
new_room_y = 0;
Drag Start:
GML:
position_x = event_data[? "posX"];
position_y = event_data[? "posY"];
Dragging:
GML:
new_room_x = position_x - event_data[? "rawposX"];
new_room_y = position_y - event_data[? "rawposY"];
Step:
GML:
new_room_x = clamp(new_room_x, 0, room_width-cam_w);
camera_set_view_pos(view_camera[0], new_room_x, cam_y);
The camera while dragging after the first movement feels fine. The problem is the first drag gesture will make a massive jump, the further away you're from the 0. I have no idea what is causing this initial jump on drag and I can't seem to figure out a way to fix it. Anyone notice anything? Because I think everything is correct.

Also, ignore the Y values as I don't move them. This all happens to X values
 

NightFrost

Member
I haven't used gesture events, but it seems to me you're mixing values from "posX" and "rawposX" which have different context, former being room position and latter being raw window position. It seems the values are framed differently, and their origins [0,0] are also different (unless camera is in the corner).

Further, shouldn't a typical drag work by noting down drag start as current position, then each step calculate the difference between current drag position and previous step's, then move camera by the difference, then set current values as previous values.
 

JeanSwamp

Member
I haven't used gesture events, but it seems to me you're mixing values from "posX" and "rawposX" which have different context, former being room position and latter being raw window position. It seems the values are framed differently, and their origins [0,0] are also different (unless camera is in the corner).

Further, shouldn't a typical drag work by noting down drag start as current position, then each step calculate the difference between current drag position and previous step's, then move camera by the difference, then set current values as previous values.
Actually before opening this thread I looked up on forums and tutorials and this seems to be the correct method to do a gesture scroll. There's even a video tutorial on Youtube that does this and I could see some people in the comments had the same issue as I am experienced.

 

NightFrost

Member
Hm I guess the dragging itself would work that way too, since those are then all relative positions on screen surface as the finger moves around, though it still feels a little iffy to me. And it just seems that the initial positioning would cause a jump. The position_x is initialized to zero, drag start switches it to press position, and dragging updates new_room_x to that minus the new drag position, which causes a jump. You could show_debug_message relevant values to confirm that this is the case. In other words, since the difference between current camera position and drag start position is brought into equation, it certainly will make the camera jump.
 

JeanSwamp

Member
Hm I guess the dragging itself would work that way too, since those are then all relative positions on screen surface as the finger moves around, though it still feels a little iffy to me. And it just seems that the initial positioning would cause a jump. The position_x is initialized to zero, drag start switches it to press position, and dragging updates new_room_x to that minus the new drag position, which causes a jump. You could show_debug_message relevant values to confirm that this is the case. In other words, since the difference between current camera position and drag start position is brought into equation, it certainly will make the camera jump.
Yes this is what I noticed, because it only happens towards the right side scrolling. Any ideas how to bypass this as is only the first drag what causes the jump
 

NightFrost

Member
Well, to preserve that particular code setup, I'm not sure unless testing around, and as I also code purely for desktop I use state machines for stuff like that. But having said that, it follows the same general principles:

For starting a drag I would do something like
GML:
drag_current_x = mouse_x;
drag_current_y = mouse_y;
drag_previous_x =mouse_x;
drag_previous_y = mouse_y;
And while drag state persists, I calculate the drag distance deltas:
GML:
drag_current_x = mouse_x;
drag_current_y = mouse_y;
drag_x = drag_current_x - drag_previous_x;
drag_y = drag_current_y - drag_previous_y;
drag_previous_x = drag_current_x;
drag_previous_y = drag_current_y;
At which point drag_x and drag_y contain the drag deltas and I can apply them to whatever was being dragged. I suppose you can replace the mouse values with rawpos values in these fragments.

I also noticed that the gesture event data has rawdiffx and rawdiffy but I'm not sure if these serve the same purpose, as drag deltas.
 

JeanSwamp

Member
Well, to preserve that particular code setup, I'm not sure unless testing around, and as I also code purely for desktop I use state machines for stuff like that. But having said that, it follows the same general principles:

For starting a drag I would do something like
GML:
drag_current_x = mouse_x;
drag_current_y = mouse_y;
drag_previous_x =mouse_x;
drag_previous_y = mouse_y;
And while drag state persists, I calculate the drag distance deltas:
GML:
drag_current_x = mouse_x;
drag_current_y = mouse_y;
drag_x = drag_current_x - drag_previous_x;
drag_y = drag_current_y - drag_previous_y;
drag_previous_x = drag_current_x;
drag_previous_y = drag_current_y;
At which point drag_x and drag_y contain the drag deltas and I can apply them to whatever was being dragged. I suppose you can replace the mouse values with rawpos values in these fragments.

I also noticed that the gesture event data has rawdiffx and rawdiffy but I'm not sure if these serve the same purpose, as drag deltas.
You don't want to update drag_current_x every step for gestures, because that woulnd't make long drag scrolls work as it will always be a minor distance.
 

Nidoking

Member
You're initializing the position to 0,0 on Create. Surely it has an actual initial position that isn't 0,0. Initialize the variables to that.

Zero is only a sensible default if there isn't a more sensible default value. Get out of the habit of writing = 0 for every variable and think about what the correct values should be.
 

JeanSwamp

Member
You're initializing the position to 0,0 on Create. Surely it has an actual initial position that isn't 0,0. Initialize the variables to that.

Zero is only a sensible default if there isn't a more sensible default value. Get out of the habit of writing = 0 for every variable and think about what the correct values should be.
It doesn't matter, after the first drag start the positions won't be 0. The jump happens every first drag.
 

NightFrost

Member
You don't want to update drag_current_x every step for gestures, because that woulnd't make long drag scrolls work as it will always be a minor distance.
Interesting, sounds like mobile development has its own particularities to watch out for. But I'm curious, when the user swipes the screen wouldn't the drag event fire every step (as I'd expect it to knowing nothing more), or does GM space it out in some manner? Anyhow, if placed into the events then the code would work as required. (That is, behave as the code it replaces.)
 

Nidoking

Member
It doesn't matter, after the first drag start the positions won't be 0. The jump happens every first drag.
These two sentences you typed contradict each other. If it didn't matter, you wouldn't be seeing a problem. Since you are seeing a problem, it clearly does matter. It's your choice: Did you post here because you wanted to solve this problem, or do you just like complaining and want to keep it that way? All I can do is tell you how to solve your problem. The tiny, incredibly simple step of actually fixing the problem is your responsibility.
 

JeanSwamp

Member
These two sentences you typed contradict each other. If it didn't matter, you wouldn't be seeing a problem. Since you are seeing a problem, it clearly does matter. It's your choice: Did you post here because you wanted to solve this problem, or do you just like complaining and want to keep it that way? All I can do is tell you how to solve your problem. The tiny, incredibly simple step of actually fixing the problem is your responsibility.
No sir. They're initialized to 0, but after the first drag they're updated to an actual touch position. The next drag will start from the previous drag. Therefore initializing it to 0 it doesn't solve any problem.

Interesting, sounds like mobile development has its own particularities to watch out for. But I'm curious, when the user swipes the screen wouldn't the drag event fire every step (as I'd expect it to knowing nothing more), or does GM space it out in some manner? Anyhow, if placed into the events then the code would work as required. (That is, behave as the code it replaces.)
The dragging event fires every step as long as you don't release. The thing is, if you update the drag_current you will be dragging always at the same speed. However if you have your origin drag point from the edge of the screen, the further away you move from that point, the faster you drag/scroll. If that makes sense.
 
Last edited:

Nidoking

Member
They're initialized to 0, but after the first drag they're updated to an actual touch position.
after the first drag they're updated to an actual touch position.
after the first drag
after the first drag
The problem is with the first drag, is it not?

The jump happens every first drag.
The problem is the first drag gesture will make a massive jump,
So, let me summarize: AFTER the first drag, everything works normally. AFTER the first drag, the positions line up. I am telling you that you need to fix the problem BEFORE the first drag because the problem happens when you do the first drag. The problem does not happen after you do the first drag, so a solution that only happens after the first drag cannot possibly solve a problem that has already happened.

So, once again, I ask you: Do you actually want to solve the problem, or would you rather not solve the problem? Because no matter how many times you ask, there is no other solution but the one correct solution.
 

JeanSwamp

Member
I am not sure how to tell you the 0 does not matter, unless I magically destroy the camera obejct and initialize it again without me knowing.
 

Nidoking

Member
Okay, then why are you using posX for the position_x variable and rawposX for the new_room_x variable? Seems like you should use the same type of position for both.
 
Top