Smooth panning and zooming made easy

Didjargo

Member
GM Version: Game Maker Studio v 1.4.1763
Target Platform: PC

Summary
:
Here I will show you a very simple way to enable panning and zooming of your view with the mouse. Good for top-down tactical games and whatnot. EDIT: Code comments have been added to explain the process.

Tutorial:
Create a new object and call it whatever you like (I called it "camera_obj"). Place the camera_obj in your room and don't forget to have views enabled otherwise this won't work.

in the create event of the camera_obj, write this code
//These following two values establish the default view scale as a reference point
window_max_w = view_wview;
window_max_h = view_hview;

//the rate of which the camera zooms in and out. Adjust this to your liking, lower numbers are faster
zoom_speed = 50;


In the step event of the camera_obj, write this code

//panning

//when the mouse button is pressed, it captures the values of the mouse's X and Y position.
//Because the view is going to be moved, we want the position of the mouse in relation to
// the window, not the view.
if mouse_check_button_pressed(mb_left)
{
mouse_xstart = window_views_mouse_get_x();
mouse_ystart = window_views_mouse_get_y();
}

//so long as the mouse button is held down, the X and Y coordinate of the view will change to
// be the difference between the mouse's current position and the position it was when we started.
if mouse_check_button(mb_left)
{
view_xview += mouse_xstart - window_views_mouse_get_x();
view_yview += mouse_ystart - window_views_mouse_get_y();
}


//zooming
if mouse_wheel_up()
{
//establish values of the view's current scale for reference
prev_view_x = view_wview;
prev_view_y = view_hview;
//increase the view scale based on our zoom_speed variable. Dividing the value based on
//the original X and Y scales of the view ensure that the aspect ratio remains consistent.
view_hview -= window_max_h/zoom_speed;
view_wview -= window_max_w/zoom_speed;
//we now want the view to zoom in towards the center of the view as opposed to the top
//left corner as it would natural want to do.
view_xview += abs(view_wview-prev_view_x)/2;
view_yview += abs(view_hview-prev_view_y)/2;
}

//and just repeat the same code for zooming out only reverse the math.
if mouse_wheel_down()
{
prev_view_x = view_wview;
prev_view_y = view_hview;
view_hview += window_max_h/zoom_speed;
view_wview += window_max_w/zoom_speed;
view_xview -= abs(view_wview-prev_view_x)/2;
view_yview -= abs(view_hview-prev_view_y)/2;
}


And Bob's your uncle.
 
Last edited:
P

PatatjeFriet

Guest
I used it and it worked perfectly, thank you!
I do have one question. Is it possible to make a maximum scroll? Because now you can keep scrolling.
 
I thought I would convert it to be used with GMS2, I hope this helps someone else in the future because it helped me a lot! Thank you very much.

Create a new object and call it whatever you like (I called it "camera_obj"). Place the camera_obj in your room.

IN THE CREATE EVENT

//These following two values establish the default view scale as a reference point

view_enabled=true
view_visible[0]=true

//The camera's width and height.
view_wview=640 -Your view width
view_hview=320 -Your view height

//The camera's position.
view_xview=0
view_yview=0

camera=camera_create_view(view_xview,view_yview,view_wview,view_yview)

view_set_camera(0,camera)

window_max_w = view_wview;
window_max_h = view_hview;

//Lower values means more speed
zoom_speed = 10;

window_set_size(view_wview,view_hview) -set the window size to the camera's size
surface_resize(application_surface,view_wview,view_hview) -set the surface size to the camera's size
display_set_gui_size(view_wview,view_hview) -set the gui size to the camera's size

var display_width = display_get_width()
var display_height = display_get_height()

var window_width = view_wview
var window_height = view_hview

camera_set_view_pos(camera,view_xview,view_yview)
camera_set_view_size(camera,view_wview,view_hview)


IN THE STEP EVENT

//panning
//when the mouse button is pressed, it captures the values of the mouse's X and Y position.
//Because the view is going to be moved, we want the position of the mouse in relation to
// the window, not the view.
if keyboard_check_pressed(vk_control)
{
mouse_xstart = window_views_mouse_get_x();
mouse_ystart = window_views_mouse_get_y();
}

//so long as the mouse button is held down, the X and Y coordinate of the view will change to
// be the difference between the mouse's current position and the position it was when we started.
if keyboard_check(vk_control)
{
view_xview += mouse_xstart - window_views_mouse_get_x();
view_yview += mouse_ystart - window_views_mouse_get_y();
}



//zooming
if mouse_wheel_up()
{
//establish values of the view's current scale for reference
prev_view_x = view_wview;
prev_view_y = view_hview;
//increase the view scale based on our zoom_speed variable. Dividing the value based on
//the original X and Y scales of the view ensure that the aspect ratio remains consistent.
view_hview -= window_max_h/zoom_speed;
view_wview -= window_max_w/zoom_speed;
//we now want the view to zoom in towards the center of the view as opposed to the top
//left corner as it would natural want to do.
view_xview += abs(view_wview-prev_view_x)/2;
view_yview += abs(view_hview-prev_view_y)/2;
}

//and just repeat the same code for zooming out only reverse the math.
if mouse_wheel_down()
{
prev_view_x = view_wview;
prev_view_y = view_hview;
view_hview += window_max_h/zoom_speed;
view_wview += window_max_w/zoom_speed;
view_xview -= abs(view_wview-prev_view_x)/2;
view_yview -= abs(view_hview-prev_view_y)/2;
}

camera_set_view_pos(camera,view_xview,view_yview)
camera_set_view_size(camera,view_wview,view_hview)
 
I thought I would convert it to be used with GMS2, I hope this helps someone else in the future because it helped me a lot! Thank you very much.
I know this is an old thread but would it be possible to add bounds to the above code, stopping you from panning or zooming out of a "box"?
I too would appreciate bounds for the GMS2 code. I'm assuming it'll be in the step event, checking to see if a variable (not sure which) is more or less than the allowed amount?
 
Top