Camera panning not working

netscaped

Member
Hey all, I'm very, very new to gml, but what I tried to do here was to slowly move my camera to the desired coordinates (It's a very uh, pixelated game, so 1px per loop wouldn't be too slow), but it doesn't seem to do anything except freezing the game up. I've tinkered with it for a while now, but I just can't seem to understand what's wrong, I would hugely appreciate any help.

GML:
//the x y i want my camera to move to
goal_x = 180;
goal_y = 25;

//record x y before moving, so i can pan back later
before_view_x = camera_get_view_x(view_camera[0]);
before_view_y = camera_get_view_y(view_camera[0]);

//set the recorded coordinates as variables for current x y
view_now_x = before_view_x;
view_now_y = before_view_y;

//calculates how much the camera is off before loop
x_to_go = view_now_y - goal_x;
y_to_go = view_now_y - goal_y;

//loop for moving the camera
while x_to_go != 0 or y_to_go != 0
{
    //horizontal
    if x_to_go > 0
    {
    camera_set_view_pos(view_camera[0], view_now_x-1, view_now_y);
    }
    if x_to_go < 0
    {
    camera_set_view_pos(view_camera[0], view_now_x+1, view_now_y);
    }
    x_to_go = view_now_x - goal_x;
    view_now_x = camera_get_view_x(view_camera[0]);

    //vertical
    if y_to_go > 0
    {
    camera_set_view_pos(view_camera[0], view_now_x, view_now_y-1);
    }
    if y_to_go < 0
    {
    camera_set_view_pos(view_camera[0], view_now_x, view_now_y+1);
    }
    y_to_go = view_now_y - goal_y;
    view_now_y = camera_get_view_y(view_camera[0]);
}
 

FoxyOfJungle

Kazan Games
You can try to use the Approach function:

GML:
///approach(start, end, shift);
if (argument0 < argument1)
{
    return min (argument0 + argument2, argument1);
} else {
    return max (argument0 - argument2, argument1);
}
 

rytan451

Member
What I usually do:
GML:
/// @param target_x The target x position to move the view to
/// @param target_y The target y position to move the view to
/// @param spd  A value between 0 and 1. 0 means "not moving", 1 means "reaches the target immediately" (0.1 is a good value)
function moveCameraTo(target_x, target_y, spd) {
  var current_x = camera_get_view_x(view_camera[0]),
      current_y = camera_get_view_y(view_camera[0]);
  
  camera_set_view_pos(lerp(current_x, target_x, spd), lerp(current_y, target_y, spd));
}
This has the advantage of being very simple and quick to calculate, as well as also having a nice movement curve (it starts fast and slows as it reaches the target).
 

netscaped

Member
What I usually do:
GML:
/// @param target_x The target x position to move the view to
/// @param target_y The target y position to move the view to
/// @param spd  A value between 0 and 1. 0 means "not moving", 1 means "reaches the target immediately" (0.1 is a good value)
function moveCameraTo(target_x, target_y, spd) {
  var current_x = camera_get_view_x(view_camera[0]),
      current_y = camera_get_view_y(view_camera[0]);
 
  camera_set_view_pos(lerp(current_x, target_x, spd), lerp(current_y, target_y, spd));
}
This has the advantage of being very simple and quick to calculate, as well as also having a nice movement curve (it starts fast and slows as it reaches the target).
Thank you so, so much! This is a really wonderful solution, works perfectly.
 

Nidoking

Member
Since nobody has set you straight on why you had a problem in the first place, you've got a while loop in there. You don't understand while loops. The loop doesn't end until it meets the condition, and the step doesn't end until the event ends. So you were freezing the game while the camera moved, waiting until it hit exactly the spot you wanted it to hit. Unfortunately, due to floating point math, the numbers are not always going to be integers, so you were probably getting to 180.0001 and then bouncing back and forth forever, never hitting zero. Had this worked correctly, the effect would have been the camera jumping immediately to the goal in a single frame.
 

FoxyOfJungle

Kazan Games
I had thought that you wanted to make the camera move smoothly in one direction 🤔 If it is just to soften the camera, lerp should be used even...
 
Top