T
The Last Random
Guest
This is quite a helpful post, Thank you.
I can finally fix my weird and warped screen sizes
I can finally fix my weird and warped screen sizes
Right click on your font (in the Gamemaker font folder). Click properties, then disable high quality. That should make it less blurry. Hope this helps.Hi, just wondering if you could point me in the right direction in regards to scaling text - when I scale text it gets very blurry and strange.
Yes, please see this completely ignored post burried 8 pages deep in the programming forum, at least when scaling images to draw on a surface, save and load the resulting image into a sprite is concerned, which the only solution is the surface has to be a power of 2 to get it to work, and that completely breaks any scaling for mobile tricks when it comes to wanting to capture the application_surface, save, and do something with it because you'd have to scale your game and/or view to a power of 2 which no mobile devices i know of use that aspect ratio, I didn't even bother to report the bug because all my bug reports get ignored or swept under the rug with either a reply stating they have no intention of fixing it (loading animated gif's from file) or that it's not important enough to bother with (broken recognizerIntent in android)are all images busted for you guys?
Am not aware of this nor I think there is a function to get that info.When designing to properly scale my game to any device - whether a mobile or a large tablet - it would be more helpful to know the screen size than just the resolution, so I could change the GUI accordingly, knowing how big a button has to be for the user to be able to press it. Will there be anywhere I can find that information? My only guess so far is os_get_info, but there's no information anywhere on what information that function actually gives.
create event:
application_surface_enable(false);
window_set_fullscreen(true);
global.MonitorW = display_get_width();
global.MonitorH = display_get_height();
global.Xoffset = (global.MonitorW-640)/2;
global.Yoffset=(global.MonitorH-480)/2;
if(global.MonitorW>=1600 && global.MonitorH>=900)
then
{
surface_resize(application_surface,1600,900)
global.Xoffset=(global.MonitorW-1600)/2;
global.Yoffset=(global.MonitorH-900)/2;
}
post-draw event:
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
if surface_exists(application_surface)
{
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
}
else
surface_create(global.MonitorW,global.MonitorH);
Part 2 of the problem it not having the view position exactly on a round value.. you will get a similar sort of uneven distribution of lines thickness as you did with improper scaling because the math that progressively figures it out many lines to draw from the source data. it may be bias to choose one source line to make 2 lines on the display for a few lines and use choose one line to make 3 lines for the rest of the image. the fix is to round the view x and y so it's never fractionalWell after changing my resolution to be the same in every room I'm still having some very minor distortion, now pretty much only noticeable if the character is standing in the right places. For now, that's good enough for me. I'll keep experimenting in the future, and thanks a ton for getting me this far!
In my opinion you have 2 solutions for this problem.@RangerX great tutorial, thank you. I am following the pixel perfect method - my virtual resolution is 360p (640x360). On Macbook Pro 2017 (aspect ratio 16:10) calling
display_get_width() and display_get_height() returns the resolution 1680x1050 and thus the base resolution is scaled just twice leaving a lot of black space on X and Y axis. Would it be sensible to scale the game three times and "cut off" a parts of the screen on the X and Y axis instead of the black space? Is there any other solution to the black space?
application_surface_draw_enable(false);
window_set_fullscreen(false);
global.monitor_w=display_get_width();
global.monitor_h=display_get_height();
global.Xoffset=(global.monitor_w-480)/2;
global.Yoffset=(global.monitor_h-360)/2;
if(global.monitor_w>=960 && global.monitor_h>=720)
{
surface_resize(application_surface,960,720)
global.Xoffset=(global.monitor_w-960)/2;
global.Yoffset=(global.monitor_h-720)/2;
}
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
room_goto_next();
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
application_surface_draw_enable(false);
window_set_fullscreen(true);
global.MonitorW=display_get_width();
global.MonitorH=display_get_height();
global.Xoffset=(global.MonitorW-480)/2;
global.Yoffset=(global.MonitorH-360)/2;
if(global.MonitorW>=960 && global.MonitorH>=720)
then
{
surface_resize(application_surface,960,720)
global.Xoffset=(global.MonitorW-960)/2;
global.Yoffset=(global.MonitorH-720)/2;
}
room_goto_next();
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
application_surface_draw_enable(false);
window_set_fullscreen(true);
global.MonitorW=display_get_width();
global.MonitorH=display_get_height();
if (global.MonitorW>=2560 && global.MonitorH>=1440)
{
surface_resize(application_surface,2560,1440)
global.Xoffset=(global.MonitorW-2560)/2;
global.Yoffset=(global.MonitorH-1440)/2;
}
if (surface_exists(application_surface))
{
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
}
else
{
surface_create(global.MonitorW,global.MonitorH);
}
Does this procedure work the same in GMS2? Thanks!This tutorial is for Game Maker Studio 1.4 and up.
While made for the Windows target, the logic applies in general for all platforms
GM Version: 1.4, but should apply to all version
Target Platform: Window, but generally applicable to other platforms
Links: see links below for example
How to properly scale your 2D game to any screen size.
Understanding pixels
Yes it should. I mean, the logic should be the same. You will have to adapt it though. Per example, view variables changed in GMS2 and they are a called a cam anyways.Does this procedure work the same in GMS2? Thanks!
I've got the same issue.Hello, i have some problems with the "pixel perfect", the screen is scaled, but just the visual, here is a photo to show better what is happening: View attachment 1455
Does this give any trouble checking if the mouse cursor is on an instance? With the first method it doesn't give the right coordinates.This tutorial is for Game Maker Studio 1.4 and up.
While made for the Windows target, the logic applies in general for all platforms
GM Version: 1.4, but should apply to all version
Target Platform: Window, but generally applicable to other platforms
Links: see links below for example
How to properly scale your 2D game to any screen size.
Understanding pixels and pixel based displays.
To understand how to manage scaling you need to really understand what it means to display graphics in a pixel display. Heck you need to understand what pixels are for a start. Pixels are logic. The logic that builds that image you see on all your screens. They form the image you see on screen. As an example, a screen of a resolution of 1920x1080 means there's 1920 columns of 1080 pixels each in order to display what image is thrown at the screen.
Pixels are squares. They are lit up or they aren't. Each square is of one color. You clearly understand that when you draw very low res graphic, like pixel art in general. A sprite of 24x24 means its composed of 24 rows of pixels and 24 columns. It's also like my friend Bob. Yellow Bob. Don't be afraid of him he's actually quite nice while being ugly looking. He is composed of 24x24 pixels as you can see:
Why is there graphical deformation when scaling up?
The deformation occurs because you're asking the engine to resize the graphics by a fraction value instead of an integer. If you resize by integer, everything is intact. Take the example of Yellow Bob 24x24. If I upscale him by 2,he becomes 48x48 pixels. That is easy for the engine to do, it simply doubles every row and columns of pixels. A black square was one pixel of size is now 2x2. No graphical deformation occurs, everything is fine:
Now what will the engine do if I ask to resize my graphic by 1.5 instead of 2? How can you grow a pixel of "half a pixel"? Well, you can't! The engine will have a choice to make. An image like Yellow Bob that is 24x24, scaled up by 1.5 ends up 36x36. To achieve that, the engine will simply double 1 row out of two! Same for the columns (24+12=36). Only twelve columns and rows alternatively will get doubled so the image pass from 24x24 to 36x36. The result is obviously a distortion of the original:
See? That's why you want to resize your game only by an integer value (x2, x3, x4, etc). This way, your pixel art is NEVER messed up.
Different approaches to scaling depending your game's style and needs.
1) Games displayed "pixel perfect" at all time. (good for 2D games)
GMS by default is drawing your game on a surface called the application surface. GMS is doing a great deal for you by automatically setting the size of the application surface and the window the same as your view size. It centers it on screen and draws it every step for you too. This is very convenient that's for sure, but there's no options for GMS to always display your game "pixel perfect". Maybe this is odd for an engine primarily dedicated to 2D games production but at least they give you all the necessary functions in order to scale your game manually, all by yourself.
In order to be in complete control of how your game is displayed you will need to turn off GMS drawing/resizing/displaying control over the application surface and then you will resize it, center it and draw it yourself every step. I will walk you through how it's done along with some structure suggestions.
First of all, your game should have a setting room. A room for setting all your stuff when the game start. Not that its mandatory to make this whole thing work but it's convenient. With this first room you can set your view size, port size, initiate all you need to initiate an set the application surface for your game to be "pixel perfect". After that you make the real game start (splash screen, title screen, etc). So here's how we set this game to display 1:1 on any screen of this world:
Step 1:
Disable the automatic drawing of the application surface. For this you use the "application surface drawn enable" function.
https://docs.yoyogames.com/source/d...surfaces/application_surface_draw_enable.html
Step 2:
Set the game to be displayed fullscreen with "window set fullscreen" function.
https://docs.yoyogames.com/source/dadiospice/002_reference/windows and views/the game window/window_set_fullscreen.html
Step 3:
You will need to remember the monitor size in order to determine what size your game will get and to center it on screen. You can simply catch those values in variables:
global.MonitorW=display_get_width();
global.MonitorH=display_get_height();
https://docs.yoyogames.com/source/dadiospice/002_reference/windows and views/index.html
Here's how to calculate the necessary offsets you will need in order to draw the application surface centered on screen. In this example, a game with a native resolution of 800x450 (no scaling):
global.Xoffset=(global.MonitorW-800)/2;
global.Yoffset=(global.MonitorH-450)/2;
Step 4:
Determining the size your game can take in the screen and adjusting the application surface size and centering accordingly. If we follow the example of a 800x450 game, you know can already know what are the desired sizes your game can display at. (x2 - 1600x900, x3 - 2400x1350, x4 - 3200x1800, etc).
By going through some simple conditions, you will determine what size it can can take. Here's an example to know if you can scale your 800x450 game by 2:
if(global.MonitorW>=1600 && global.MonitorH>=900)
then
{
surface_resize(application_surface,1600,900)
global.Xoffset=(global.MonitorW-1600)/2;
global.Yoffset=(global.MonitorH-900)/2;
}
https://docs.yoyogames.com/source/dadiospice/002_reference/surfaces/surface_resize.html
Step 5:
Now that the application surface is the right size and that we are done with all the necessary calculations, there's one more thing to do. You have to make an object draw your application surface on screen every step. Normally I would suggest that all your objects in the game that can draw something would do it in a "pre-draw" or normal "draw" event. This way you are sure everybody is done drawing when you display the application surface in a post-draw event. Here's an example of how the code could look:
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
https://docs.yoyogames.com/source/dadiospice/002_reference/drawing/drawing surfaces/draw_surface_ext.html
2) Games displayed scaled but always respecting the screen ratio. (good for 3D games or vector art)
No need to code anything, GMS can do this for you:
3) Games with their displayed playfield changing size. (good for some very specific cases)
With this method you would actually set the view and port size of your room according the monitor's size. It's very easy to pull off and will be useful mostly in games like SimCity or other strategy games where the gameplay is not broken due to the fact a player can see larger of a playfield than another. It's rare you see this method used in professional games though because there are some drawbacks to understand before using it:
- Different players having different view sizes depending their monitor can advantage or disadvantage them in multiplayer.
- It can also make a game harder than planned or easier than planned.
- It can influence a lot of other design aspects of the game like hiding secrets, controlling what the player sees in order to give an impression or a feeling.
- You game will be harder to balance in general and to debug.
4) Games that use the overscan method.
Similarly to the first method (pixel perfect), someone who wouldn't want to ever see their game appearing letteboxed on screen could decide to resize the application surface bigger than the game window (still at an integer size) in order to hide all the letterboxing. This is rarely used in pro games here again because it's hard to control what the player see and does not see on screen depending his/her monitor's resolution. This leads to the same kind of drawbacks as the third method described in this tutorial.
Other very useful tutorials:
http://www.yoyogames.com/blog/65 (Scaling for devices part 1)
http://www.yoyogames.com/blog/66 (Scaling for devices part 2)
Alternate scaling method entirely
(and aspect ratio tutorials + other excellent tutorials by PixelPope)
https://forum.yoyogames.com/index.p...-aspect-ratio-management-for-game-maker.7106/
draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
Actually, that line of code only draws the application surface to screen. Nothing else. So if you have graphical problems, they happen before that.i'm trying to add this to my game, but i'm using a dynamic light system.. and the shadows bugs when i draw thisCode:draw_surface_ext(application_surface,global.Xoffset,global.Yoffset,1,1,0,c_white,1);
i'll try another light system script, i'm a novice and idk how scripts work exactly. tyActually, that line of code only draws the application surface to screen. Nothing else. So if you have graphical problems, they happen before that.