Independent Game and GUI Resolutions

One of the first things that should be done on any project is setting up the camera and GUI viewports. This will define the player’s view throughout the game and having a solid base to start from is always helpful.

First, I define some options and variables inside of my Game object.

//vars
gameRes = 0;
guiRes = 0;

//flags
isResChange = false;
isFullscreen = false;

//option list
resOptions = ds_list_create();
ds_list_add(resOptions, [640, 480]);
ds_list_add(resOptions, [1024, 768]);
ds_list_add(resOptions, [1280, 800]);
ds_list_add(resOptions, [1366, 768]);
ds_list_add(resOptions, [1920, 1080]);

I add two cursor variables so I can store which resolution the game and GUI are using, respectively.
Next, I add a couple flags so I know when resolution is changed (we don’t want to set the resolutions constantly every step, only on change) and one for the fullscreen state.
Finally, I add a DS List of the available resolution options. Using the cursor variables, we can get the appropriate resolution from this list.

Now, I add an If block to the Game object’s Step event.

if(isResChange){
    var guiResData = Game.resOptions[| Game.guiRes];
    var gameResData = Game.resOptions[| Game.gameRes];
    display_set_gui_size(guiResData[0], guiResData[1]);
    
    Camera.resW = gameResData[0];
    Camera.resH = gameResData[1];
    
    isResChange = false;
}

Basically, I’m checking if resolution has changed for either GUI or Game, and set both at that point.

For the Camera object, I follow Shaun Spaulding’s excellent tutorial¬†GameMaker Studio 2 – Smooth Camera Tutorial.

I modify his Camera code a little to allow zooming.

In the Camera object’s Create event:

camera = camera_create();

//set the intial resolution, zoom, and movement rate
resW = 640;
resH = 480;
zoom = 1;
rate = 10;

var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
var pm = matrix_build_projection_ortho(resW / zoom, resH / zoom, 1, 10000);

camera_set_view_mat(camera, vm);
camera_set_proj_mat(camera, pm);

view_camera[0] = camera;

follow = noone;
xTo = x;
yTo = y;
zoomTo = zoom;

And Step event:

x += (xTo - x) / rate;
y += (yTo - y) / rate;
zoom += (zoomTo - zoom) / rate;

var vm = matrix_build_lookat(x, y, -10, x, y, 0, 0, 1, 0);
var pm = matrix_build_projection_ortho(resW / zoom, resH / zoom, 1, 10000);

camera_set_view_mat(camera, vm);
camera_set_proj_mat(camera, pm);

if(follow != noone){
    xTo = follow.x;
    yTo = follow.y;
}

Dividing the matrix_build_projection_ortho width and height by the zoom variable will zoom the camera in and out.

By increasing or decreasing the zoomTo variable, we can smoothly zoom in our out.

The final result is basic and could use some polishing, but it looks something like this:

Leave a Reply

Your email address will not be published. Required fields are marked *