How can I add black bars to the sides for my game?

Roleybob

Member
GM will automatically display black bars if you keep the aspect ratio the same instead of stretching the image (when displaying the game on a resolution which doesn't scale to your original aspect ratio properly).

So, for example if your game is 480x270, there will be no black bars when the game is displayed in 16:9 ratio but there will for other aspect ratios, as long as you don't allow GM to stretch the image. However, you'll still get distortion in some 16:9 aspect ratio displays, for example if you tried displaying 480x270 in a 800x450 window, as 800x450 does not divide evenly into 480x270 so there will be rows & columns of pixels which aren't drawn

You might be interested in this (this is just the first part of 3 videos):

 
Last edited:
GM will automatically display black bars if you keep the aspect ratio the same instead of stretching the image (when displaying the game on a resolution which doesn't scale to your original aspect ratio properly).

So, for example if your game is 480x270, there will be no black bars when the game is displayed in 16:9 ratio but there will for other aspect ratios, as long as you don't allow GM to stretch the image. However, you'll still get distortion in some 16:9 aspect ratio displays, for example if you tried displaying 480x270 in a 800x450 window, as 800x450 does not divide evenly into 480x270 so there will be rows & columns of pixels which aren't drawn

You might be interested in this (this is just the first part of 3 videos):

FIXED
 
Last edited:

Roleybob

Member
GM will add black bars automatically.

If you code your game to display at a resolution of 480x270, your game will display with no distortion for any multiples of those numbers, i.e. 480x270, 960x540, 1440x810, 1920x1080, etc.

It will display with no black lines when displayed on monitors with the same resolution. If you play a game with aspect ration 16:9 on a monitor with an aspect ration of 4:3, GM will automatically add the black lines (as long as you don't allow GM to resize the port, stretch the image, etc.

If you have another monitor with a different aspect ration then try it - code a game in 16:9, then play it on a monitor in 4:3, or any other aspect ratio other than 16:9 - GM will automatically add the black lines.

Alternatively, code a game to display in 4:3, then play it on your 16:9 monitor
 
GM will add black bars automatically.

If you code your game to display at a resolution of 480x270, your game will display with no distortion for any multiples of those numbers, i.e. 480x270, 960x540, 1440x810, 1920x1080, etc.

It will display with no black lines when displayed on monitors with the same resolution. If you play a game with aspect ration 16:9 on a monitor with an aspect ration of 4:3, GM will automatically add the black lines (as long as you don't allow GM to resize the port, stretch the image, etc.

If you have another monitor with a different aspect ration then try it - code a game in 16:9, then play it on a monitor in 4:3, or any other aspect ratio other than 16:9 - GM will automatically add the black lines.

Alternatively, code a game to display in 4:3, then play it on your 16:9 monitor
FIXED
 
Last edited:

Roleybob

Member
I have to go out now but I suspect you are using a viewport which is allowing GM to stretch what is displayed to the window size or something like that. It is very difficult to tell without seeing your room settings or the code you use to control view.

You should be able to get the answers you need from the PixelatedPope videos but it may take some time to understand, which is perfectly fine - it can take a while to get your head around the logic of pretty much all aspects of coding.

Otherwise, post more details - what version of GM you are using, the view settings you are using, etc
 
I have to go out now but I suspect you are using a viewport which is allowing GM to stretch what is displayed to the window size or something like that. It is very difficult to tell without seeing your room settings or the code you use to control view.

You should be able to get the answers you need from the PixelatedPope videos but it may take some time to understand, which is perfectly fine - it can take a while to get your head around the logic of pretty much all aspects of coding.

Otherwise, post more details - what version of GM you are using, the view settings you are using, etc
I am using GameMaker 2, I am not using the Room Editor, I created a camera object to which establishes the view in the room. If you want me to give you the code, just tell me, I can post more here.
 
What is the code?
Alright, I created an object called "camera", where I wrote code so it can follow the player, enable the views and get a width and height of the window. Also, on the Windows Graphic Options I marked: Allow Full Screen Switching and Keep Aspect Ratio.

CREATE EVENT
#macro cam view_camera[0]
#macro view_w camera_get_view_width(view_camera[0])
#macro view_h camera_get_view_height(view_camera[0])
aspect_ratio = display_get_width()/display_get_height();

view_height= 270;
view_width=round(view_height*aspect_ratio);

if(view_width & 1) view_width++;
if(view_height & 1) view_height++;

max_window_scale = min(floor(display_get_width()/view_width),floor(display_get_height()/view_height));
if(view_height * max_window_scale == display_get_height())
max_window_scale--;

window_scale = max_window_scale;

window_set_size(view_width*window_scale, view_height*window_scale);

alarm[0] = 1;

surface_resize(application_surface, view_width*window_scale, view_height*window_scale);

///Camera Variables to move freely

moveCamX = 0; //These variables are used if you want to move the camera without following the player
moveCamY = 0;

END STEP
/// @description

camera_set_view_size(cam, view_width, view_height);

//Press a key to move the camera freely
moveCam = keyboard_check(ord("P"));

if (moveCam) {
moveCamX = (keyboard_check(ord("D")) - keyboard_check(ord("A")))*6;
moveCamY = (keyboard_check(ord("S")) - keyboard_check(ord("W")))*6;
x += moveCamX;
y += moveCamY;
camera_set_view_pos(cam, x, y);
} else {
//The Camera follows the Player
if(instance_exists(obj_player)){
var _x = clamp(obj_player.x - view_width/2, 0, room_width - view_width);
var _y = clamp(obj_player.y - view_height/2, 0, room_height - view_height);
camera_set_view_pos(cam, _x, _y)
}
}

ALARM 0
/// @description
window_center();

ROOM START
/// @description
view_enabled = true;
view_visible[0] = true;

The Object Camera is set as persistent and placed in an Initial Room.

What I want to achieve is the use of Black Bars on the sides like Undertale or Everhood. I have read that Pixel Perfect Scaling is not perfect and there will always be some sort of distortion depending on the screen you are playing. So, Black Bars might be the only solution, but I dont know how to add them. I also want my game to scale depending on what screen is being displayed. I have even seen games that use like a Black Box around when it is being run at Full Screen Mode so the pixels dont get distorted.
 

Roleybob

Member
You are setting the width of the view based on the aspect ratio of the monitor

GML:
aspect_ratio = display_get_width()/display_get_height();

view_height= 270;
view_width=round(view_height*aspect_ratio);
So GM is stretching the view to the dimensions of the display port.

To display as 480 x 270, set the view_width to 480, then on a monitor which isn't 16:9 you should get black bars
 
You are setting the width of the view based on the aspect ratio of the monitor

GML:
aspect_ratio = display_get_width()/display_get_height();

view_height= 270;
view_width=round(view_height*aspect_ratio);
So GM is stretching the view to the dimensions of the display port.

To display as 480 x 270, set the view_width to 480, then on a monitor which isn't 16:9 you should get black bars
I set the view_width to 480 and activated the Full Screen Mode on my laptop (1366x768) and I still do not get Black Bars. Perhaps, is there something I am forgetting?
 

Roleybob

Member
1366x768 pretty much is 16:9.

You probably have a single black line so you can't really see it.

Try setting the view to a different aspect ration like 4:3 (which would be 480 x 360) and then play it in fullscreen
 
1366x768 pretty much is 16:9.

You probably have a single black line so you can't really see it.

Try setting the view to a different aspect ration like 4:3 (which would be 480 x 360) and then play it in fullscreen
Alright, I got the Black Bars now but... when I go into Full Screen Mode, my pixels get distorted. What can it be? Does it need to be coded?
 

Roleybob

Member
Distorted how?

If you are going to keep with a specific aspect ratio then you can get rid of a lot of the code you had in your camera object
 
Distorted how?

If you are going to keep with a specific aspect ratio then you can get rid of a lot of the code you had in your camera object
When I run the game and the window opens, everything looks fine, the window displayed duplicates the view size x2 but when I activate full screen mode, that's when I see pixels distorted like:

Some pixels look like rectangles, some other look thinner or bigger than the other ones.

Sorry, can you explain me what code should I get rid of?
 

Roleybob

Member
As 1366 is not divisible by 480 and 768 isn't divisible by 360 GM is still stretching the display port to fit one of those dimensions. You need to only allow GM to scale up to the nearest multiple of 480x360 which doesn't exceed either 1366 width or 768 height.

Something like this should be the bare bones of what you need, if you want the player to be able to play in wondowed mode and resize the window then you'll need to add that back in


GML:
var display_width = display_get_width();
var display_height = display_get_height();
var window_scale;

view_width = 480;
view_height = 360;

window_scale = min(floor(display_width / view_width), floor(display_height / view_height));
if (view_height * window_scale == display_height)
    window_scale--;

window_set_size(view_width * window_scale, view_height * window_scale);
 
Last edited:
As 1366 is not divisible by 480 and 768 isn't divisible by 360 GM is still stretching the display port to fit one of those dimensions. You need to only allow GM to scale up to the nearest multiple of 480x360 which doesn't exceed either 1366 width or 768 height.

Something like this should be the bare bones of what you need, if you want the player to be able to play in wondowed mode and resize the window then you'll need to add that back in


GML:
var display_width = display_get_width();
var display_height = display_get_height();
var window_scale;

view_width = 480;
view_height = 360;

window_scale = min(floor(display_width / view_width), floor(display_height / view_height));

window_set_size(view_width * window_scale, view_height * window_scale);
Alright, I understand that those resolutions aren't compatible and that GM is still streching it.

How can I allow GM to scale up to the nearest one? Is it through code or are there some options?

Please, I need help with this. I swear, that I do find stuff like making a Dialogue System easier than working with Resolutions, I'm stuck.
 

Roleybob

Member
This is what I am currently using in a game I am occasionally working on


Display control object create event

GML:
/*
SET UP THE WINDOW SIZE AND MAGNIFICATION OPTIONS
------------------------------------------------
*/

//determine monitor dimensions//
var display_width = display_get_width();
var display_height = display_get_height();

//desired basic window resolution (480:270 = 16:9 aspect ratio)//
target_width = 480;
target_height = target_width * (9/16);

//set the GUI size to cover the same area as the game window//
display_set_gui_size(target_width, target_height);

//set limits for resizing the game window//
//compare the best possible width and height values and take the worst option as the magnification basis//
magnification_max = min ((floor(display_width / target_width)), (floor(display_height / target_height)));
magnification_min = 1;

//set starting magnification variable (fullscreen if monitor is only able to manage 1 * target room dimensions)//
window_set_fullscreen(false);
magnification = magnification_max - 1;
if (magnification) == 0
{
    magnification = 1;
    window_set_fullscreen(true);
}

//set the game window to the correct dimensions//
surface_resize(application_surface, target_width, target_height);
window_set_size(target_width * magnification, target_height * magnification);

Display control object step event

GML:
/*
HANDLE PLAYER INPUT FOR CHANGING WINDOW MAGNIFICATION
-----------------------------------------------------
*/

var magnification_up = keyboard_check_pressed(vk_pageup);
var magnification_down = keyboard_check_pressed(vk_pagedown);

//if player is not pressing pageup or pagedown (or is pressing both), exit script//
if !(abs(magnification_up - magnification_down))
    exit;

//store what magnification the game window is currently running on//
var magnification_previous = magnification;

//determine desired magnification level depending on what button (pageup / pagedown) is being pressed//
magnification += (magnification_up - magnification_down);
magnification = clamp(magnification, magnification_min, magnification_max);
//if the magnification level has not changed, exit script//
if (magnification == magnification_previous) exit;

//set fullscreen or correct magnification level//
if (magnification == magnification_max)
    window_set_fullscreen(true);
else
{
    window_set_fullscreen(false);
    window_set_size(target_width * magnification, target_height * magnification);
}
surface_resize(application_surface, target_width * magnification, target_height * magnification);
Oh, should have added, this is for a game where the whole room is displayed and the dimensions of all rooms are in the same ratio (16:9). You'll need to ensure that the view you are displaying in the room is the same resolution as the target_width and target_height
 
Last edited:
Okay, I kinda get the Create Event but I do not how to implement the Step Event on my code because the Step Event of my camera object controls the way of how it follows the player.

However, I still tested it on my laptop, and when I go full screen using the magnification code, I get the pixel distortions (this does not happen on my PC monitor, since it's 1920×1080). Even if I change the options to be 4:3 in the Create Event, it still shows the problem.

By the way, I was reading through the forums and other websites and I got a GM2 project where it shows how you can handle Pixel Perfect Scaling with a Box around it. Here:


You can open it by going into the File Option, choose Import and open it on your GMS2.

I think it's very interesting but when I looked at the code, I got scared, lol.

Is there a way to replicate this on my project?
 
Btw, I forgot to mention that on the project file, you can change the Width ane Height in the Create Event of the camera object. It's set as 320×120 but you can change it to anything and check how it looks when you run the game.
 

Roleybob

Member
I've added the camera set up to the create event just after setting the target_width and target_height variables. If you plug in the appropriate details into the arguments in the camera_create_view() function then GM will automatically make the camera follow the player object, look up camera_create_view() in the manual for an explanation of each of the required arguments.

GML:
/*
SET UP THE WINDOW SIZE AND MAGNIFICATION OPTIONS
------------------------------------------------
*/

//determine monitor dimensions//
var display_width = display_get_width();
var display_height = display_get_height();

//desired basic window resolution (480:270 = 16:9 aspect ratio)//
target_width = 480;
target_height = target_width * (9/16);

view_enabled = true;
view_visible[0] = true;
view_camera[0] = camera_create_view(0, 0, target_width, target_height, 0, -1, -1, -1, 0, 0);

//set the GUI size to cover the same area as the game window//
display_set_gui_size(target_width, target_height);

//set limits for resizing the game window//
//compare the best possible width and height values and take the worst option as the magnification basis//
magnification_max = min ((floor(display_width / target_width)), (floor(display_height / target_height)));
magnification_min = 1;

//set starting magnification variable (fullscreen if monitor is only able to manage 1 * target room dimensions)//
window_set_fullscreen(false);
magnification = magnification_max - 1;
if (magnification) == 0
{
    magnification = 1;
    window_set_fullscreen(true);
}

//set the game window to the correct dimensions//
surface_resize(application_surface, target_width, target_height);
window_set_size(target_width * magnification, target_height * magnification);
The step event code is so that the player can resize the window by pressing page up / page down, and will toggle fullscreen on and off when at the highest resolution that the monitor can display.

It's board game night now so I have to go
 
I've added the camera set up to the create event just after setting the target_width and target_height variables. If you plug in the appropriate details into the arguments in the camera_create_view() function then GM will automatically make the camera follow the player object, look up camera_create_view() in the manual for an explanation of each of the required arguments.

GML:
/*
SET UP THE WINDOW SIZE AND MAGNIFICATION OPTIONS
------------------------------------------------
*/

//determine monitor dimensions//
var display_width = display_get_width();
var display_height = display_get_height();

//desired basic window resolution (480:270 = 16:9 aspect ratio)//
target_width = 480;
target_height = target_width * (9/16);

view_enabled = true;
view_visible[0] = true;
view_camera[0] = camera_create_view(0, 0, target_width, target_height, 0, -1, -1, -1, 0, 0);

//set the GUI size to cover the same area as the game window//
display_set_gui_size(target_width, target_height);

//set limits for resizing the game window//
//compare the best possible width and height values and take the worst option as the magnification basis//
magnification_max = min ((floor(display_width / target_width)), (floor(display_height / target_height)));
magnification_min = 1;

//set starting magnification variable (fullscreen if monitor is only able to manage 1 * target room dimensions)//
window_set_fullscreen(false);
magnification = magnification_max - 1;
if (magnification) == 0
{
    magnification = 1;
    window_set_fullscreen(true);
}

//set the game window to the correct dimensions//
surface_resize(application_surface, target_width, target_height);
window_set_size(target_width * magnification, target_height * magnification);
The step event code is so that the player can resize the window by pressing page up / page down, and will toggle fullscreen on and off when at the highest resolution that the monitor can display.

It's board game night now so I have to go
I will try to apply it just as you say and see what happens, I'll tell you the results.

Also, if you want, you can check out the project file.

Anyway, later and have fun!
 
Top