B
Bence Monori
Guest
.
Last edited by a moderator:
1920x1200. There is only one bar at the top of the screen (rather than one at bottom and top). Not sure why turning it off is fixing it either.@IndieRex
I don't recommend using the pixel perfect scaling... but that said, it certainly shouldn't give you black bars. What's the resolution of your monitor?
Ah that makes sense! Thanks again for your help. Great series - really appreciated the lead-up videos explaining the background of the topic and laying the groundwork for the system.@IndieRex
Ah, because your room isn't tall enough! When you scale it to be pixel perfect, it will scale the height to be perfect. 540 doesn't go perfectly into 1200, so it resizes your view to be 600 tall. Your rooms are only 540 tall, so you see the outside of your room, which is black.
No black bars. Seems to be an issue in both Draw and Draw GUI events.Are you drawing your text in a gui event? When you are in full screen, do you have black bars at the top and bottom (you shouldn't)?
display_write_all_specs_GMS2(5,5);
//Perfect Pixel Scaling
if(display_width mod ideal_width != 0)
{
var d = round(display_width/ideal_width);
ideal_width=display_width/d;
}
if(display_height mod ideal_height != 0)
{
var d = round(display_height/ideal_height);
ideal_height=display_height/d;
}
thank you so much that does the trick !@rouzbeh78 Okay. First off, it looks like your game isn't pixel art based, so 720p is just fine .
So, remove the pixel perfect scaling portion of the code:
Remove all that. That alone may fix it for you depending on the resolution of your phone.Code://Perfect Pixel Scaling if(display_width mod ideal_width != 0) { var d = round(display_width/ideal_width); ideal_width=display_width/d; } if(display_height mod ideal_height != 0) { var d = round(display_height/ideal_height); ideal_height=display_height/d; }
As for view following your characters, I discuss how to do that in my Part 5 video.
camera_view_set_pos(view_camera[0],player.x,player.y)
camera = camera_create();
globalvar view_x,view_y,view_w,view_h;
view_x = 0;
view_y = 0;
view_w = ideal_width;
view_h = ideal_height;
camera = camera_create_view(0, 0, ideal_width, ideal_height, 0, -1, -1, -1, 0, 0);
var _view_w = camera_get_view_width(view_camera[0]);
var _view_h = camera_get_view_height(view_camera[0]);
var _view_x = instance_followed.x - _view_w / 2;
var _view_y = instance_followed.y - _view_h / 2;
var _round = _view_w / surface_get_width( application_surface );
camera_set_view_pos(view_camera[0], round_n( _view_x, _round ), round_n( _view_y, _round ) );
Hi. Did you find a solution? Thanks!Hi! I followed your tutorial in the hope it would solve my issues with jittering graphics, but it didn't. The camera follows the character and he looks fine, but when the view moves it seems as if everything else is wildly virbrating. Just look at the eye of the sprite in the beginning. I snapped a quick video of it with my phone (couldn't get the capture software to work with GM), can you help?
Thanks for the quick answer! I already use manual camera control (tried different versions). The main problem is that the player moves very smooth but other objects/characters are very blurry/jitter/ghosting?. Especially when the player (and the camera) move in the opposite direction than the other objects. It occurs more on higher move speeds, like 2px per step (640*360 base res.). This is really a show stopper. What do you mean by "add some smoothing as well."? Thanks in advance!@instaboy Chances are the view was using the "object following" feature while also using an increased application surface size, which many people use without even realizing it. This causes jittering. Best thing to do is move to a manual camera control, and maybe add some smoothing as well.
Ah, okay. So, try this. Can you capture the issue in a screenshot? If not, this is likely an art issue. Obviously I've not seen your game, but I'm guessing it is fairly early and using a lot of placeholder art, with bright colors. When things with bright colors move quickly on an LCD monitor, you are more likely to get "ghosting" and other strange looking things. This is not an issue with your code, but with your art. It happens in almost all 2D games with fast motion, but you don't notice it because there are more interesting things to be paying attention to. So ultimately, your only solution is to ignore it until it goes away as your game gets more content and better art.Thanks for the quick answer! I already use manual camera control (tried different versions). The main problem is that the player moves very smooth but other objects/characters are very blurry/jitter/ghosting?. Especially when the player (and the camera) move in the opposite direction than the other objects. It occurs more on higher move speeds, like 2px per step (640*360 base res.). This is really a show stopper. What do you mean by "add some smoothing as well."? Thanks in advance!
if(os_type == os_android)
{
window_set_size(464,261);
window_center();
surface_resize(application_surface,464,261);
}
Alright, I'll give that a try! Thank you very much for your help!Oh, yeah. If you are scaling down pixel art, that's going to look awful. If it's not pixel art, you could just turn on interpolation, and it would look pretty great.
I did a test on my pc with this code (not tested on mobile devices). In your opinion could you go using the view option? As for perfect pixel art scaling, should I have problems?Looks like you are on the right path! You need to use views to properly manage your resolution in most cases. Another option is to disable the automatic drawing of the application surface and draw your app surface manually in the GUI event. Then you can maximize the GUI and draw any image you want in the background while drawing your app surface scaled up as much as possible and perfectly centered.
ideal_width=360;
ideal_height=640;
//Aspect ratio
aspect_ratio = display_get_width()/display_get_height();
//Calculate new ideal width.
ideal_width=round(ideal_height*aspect_ratio);
ideal_height=round(ideal_width/aspect_ratio);
ideal_width=round(ideal_width);
ideal_height=round(ideal_height);
if (display_get_width() mod ideal_width != 0) {
var d = round(display_get_width()/ideal_width);
ideal_width = display_get_width()/d;
}
if (display_get_height() mod ideal_height != 0) {
var d = round(display_get_height()/ideal_height);
ideal_height = display_get_height()/d;
}
if(ideal_width & 1)
ideal_width++;
if(ideal_height & 1)
ideal_height++;
//Setup all the view ports so I don't have to.
globalvar Main_Camera;
Main_Camera = camera_create_view(0,0,ideal_width,ideal_height,0,noone,0,0,0,0);
camera_set_view_size(Main_Camera,ideal_width,ideal_height);
for(var i=1; i<= room_last; i++)
{
if(room_exists(i))
{
room_set_view_enabled(i,true);
room_set_viewport(i,0,true,0,0,ideal_width,ideal_height);
room_set_camera(i,0,Main_Camera);
}
}
surface_resize(application_surface,ideal_width,ideal_height);
display_set_gui_size(ideal_width,ideal_height);
window_set_size(ideal_width,ideal_height);
room_goto_next();
gms2 i dont use discord wants you to faff about signing up,@BitmapSkies
GMS1 or GMS2? Also, I recommend joining my discord server (link in my sig) and we can talk about this in real time. Much easier to debug that way.
ah yes i see cause im asking for the extra height ? hmm now i understand why scaling in none intergers is bad , ok then so gms2 wont work with none widescreen ? how do i stretch the height , keeping black borders on the side without being in a box ? i dont get this considering gms2 is supposed to be mostly for pixel art ? the old gm didnt have this problem dont tell me im going to have to redo all my pixel art for the sake of a few pixels ? its so annoying .Okay, so since you are on a more square aspect ratio, it's going to stretch your height out to fill the vertical space. So 1080 / 240 = 4.5. That .5 is the cause of any distortion you see. So your only real option is to manually draw the app surface so that it doesn't stretch to fill the whole window. This will result in a "black box" rather than black bars all around your game. But all pixel distortion will be eliminated as you'll be perfectly scaling to 4x instead of 4.5x
ps : all this has just reminded me why i stopped making games after gm8ah yes i see cause im asking for the extra height ? hmm now i understand why scaling in none intergers is bad , ok then so gms2 wont work with none widescreen ? how do i stretch the height , keeping black borders on the side without being in a box ? i dont get this considering gms2 is supposed to be mostly for pixel art ? the old gm didnt have this problem dont tell me im going to have to redo all my pixel art for the sake of a few pixels ? its so annoying .
ps : so what should i be using for the pixel art as close to 320x240 to get it to scale without making the game widescreen ? what if it get played on a none exact 1080 screen ? (16 bit platformer)
yeah i went away calmed down and had a nice brain squeltch, you've basicaly just replied what i was thinking of haha, yeah i'll be honest i'm a big emulator guy so i should know about all this , mabye i got confused by digesting 1000s of hours of pixel art lectures and the beauty of 240pixels of platformer specialisation (since making platformers in widescreen is .... silly unless you design your levels with widescreen in mind , i am however still dumbfounded as to why gamemaker doesnt just add the extra pixels into the borders on the side(how i would like) so doing a little calulator ive worked out the levels need to be made with 480 x 270 in mind ? i am also thinking , that mabye i never noticed the distortion back in 2008 cause i was on a 4:3 crt monitor , i just ran my stone age 2008 gm8 game on my 1080 and yes pixel distortion soooooo ...... looks like im going to be forced to make my levels in widescreen meh .@BitmapSkies
This has nothing to do with GameMaker. This is just how graphics work. You have a monitor with a set number of pixels, you have an image with a set number of pixels. If you try to scale the image to fit the monitor, and you have to scale with non-whole numbers, then some pixels are going to be smaller than other pixels. Your monitor is made up of physical pixels, and there's nothing you can do about that. Unless you want to use some fancy shaders to try and smooth out your scaling, you will have pixel distortion. That said, in my experience, depending on the art style, scaling up to anything over 3x usually doesn't look that bad. For example, take this screenshot from Seiken Densetsu 3
it's native resolution is 256x224. But that up there is scaled up to fit a 1080p monitor (if you view the image in full screen.) That's a scale of 4.821428...x Can you spot the pixel distortion? Even if you could pick it out in a static screenshot, I'd bet you'd have a hard time noticing it when actually playing the game. But it is definitely there.
Most people play emulated SNES games at 1080p on their PCs, and very few complain about this sort of distortion; not because it isn't present, but because it isn't noticeable at this scale.
So if you are seeing really serious distortion at your chosen resolution when scaled to 1080, I would first make sure you are scaling correctly and there isn't anything else at play. And then I'd examine your art style... maybe it's making distortion more obvious? I'd have to see a screenshot of your issues to know for sure.
Thank you so much pope , 280 x 216 was the golden number for my 8 bit games and 360 x 270 for my 16 bit games , you just fixed everything yippeeee !!!!That's not necessarily true either. Your desired aspect ratio is 4:3 (1.3333). So if you pick a desired height that is a whole number factor of 1080 (so either 270 or 216) and then calculate the width based on the desired aspect ratio (1.333) you get two possible, non full screen resolutions that will scale perfectly to 1080p with black bars on the sides: 280 x 216 or 360 x 270. Design your game around either of those resolutions, and you'll scale well on 1920x1080 monitors.
///Properties
ideal_width=0; //Doesn't matter because we are going to calculate this.
ideal_height=640;
display_width=display_get_width();
display_height=display_get_height();
//Aspect ratio
aspect_ratio = display_width/display_height;
//Calculate new ideal width or height
ideal_width=round(ideal_height*aspect_ratio);
//ideal_height=round(ideal_width/aspect_ratio);
ideal_width=round(ideal_width);
ideal_height=round(ideal_height);
//Perfect Pixel Scaling
if(display_width mod ideal_width != 0)
{
var d = round(display_width/ideal_width);
ideal_width=display_width/d;
}
if(display_height mod ideal_height != 0)
{
var d = round(display_height/ideal_height);
ideal_height=display_height/d;
}
//Check to make sure our ideal width and height isn't an odd number, as that's usually not good.
if (ideal_width & 1) {
ideal_width++;
}
/*if(ideal_height & 1)
ideal_height++;*/
surface_resize(application_surface,ideal_width,ideal_height);
display_set_gui_size(ideal_width,ideal_height);
window_set_size(ideal_width,ideal_height);
alarm[0] = 1; // Centra window puoi rimuovere
camera = camera_create();
room_goto(rInizializzazione);
camera_set_view_size(view_camera[0], ideal_width, ideal_height);
camera_set_view_pos(view_camera[0], room_width/2-camera_get_view_width(view_camera[0])/2, room_height/2-camera_get_view_height(view_camera[0])/2);
view_camera[0]=camera;
view_enabled=true;
view_visible[0]=true;
view_camera[0]=noone;
Okay, first off, since you are developing your game for a mobile device in portrait mode but aren't developing your game on a monitor in portrait mode, you will need to replace "display_get_width & height" with hard coded values to get your game window to display properly when building locally.Hello,
I'm sorry if I disturb you but I'm having trouble getting your codes to work properly. Here is my current code (I use the last version of GM2):
CREATE:
END STEP:Code:///Properties ideal_width=0; //Doesn't matter because we are going to calculate this. ideal_height=640; display_width=display_get_width(); display_height=display_get_height(); //Aspect ratio aspect_ratio = display_width/display_height; //Calculate new ideal width or height ideal_width=round(ideal_height*aspect_ratio); //ideal_height=round(ideal_width/aspect_ratio); ideal_width=round(ideal_width); ideal_height=round(ideal_height); //Perfect Pixel Scaling if(display_width mod ideal_width != 0) { var d = round(display_width/ideal_width); ideal_width=display_width/d; } if(display_height mod ideal_height != 0) { var d = round(display_height/ideal_height); ideal_height=display_height/d; } //Check to make sure our ideal width and height isn't an odd number, as that's usually not good. if (ideal_width & 1) { ideal_width++; } /*if(ideal_height & 1) ideal_height++;*/ surface_resize(application_surface,ideal_width,ideal_height); display_set_gui_size(ideal_width,ideal_height); window_set_size(ideal_width,ideal_height); alarm[0] = 1; // Centra window puoi rimuovere camera = camera_create(); room_goto(rInizializzazione);
ROOM START:Code:camera_set_view_size(view_camera[0], ideal_width, ideal_height); camera_set_view_pos(view_camera[0], room_width/2-camera_get_view_width(view_camera[0])/2, room_height/2-camera_get_view_height(view_camera[0])/2);
ROOM END:Code:view_camera[0]=camera; view_enabled=true; view_visible[0]=true;
This is a result:Code:view_camera[0]=noone;
My game room has dimensions 360x640 (horizontal orientation), and the background I use is 360x640. In the code I inserted an "ideal_height" of 640, just because I would like to keep the original height, and only modify the width to fix the aspect ratio.
The problem is that the height of the window is also changed and the resolution no longer has a height of 640 as you can see from the screen). Is it not possible to make the camera have a height that perfectly covers the height of the background?
Running the code on a mobile device, I encounter problems in the click of many objects that have been placed inside the room through normal coordinates (they are displayed correctly). Do I have to place them by code based on other coordinates?
///Properties
ideal_width=0; //Doesn't matter because we are going to calculate this.
ideal_height=512;
display_width=display_get_width();
display_height=display_get_height();
//Aspect ratio
aspect_ratio = display_width/display_height;
//Calculate new ideal width or height
ideal_width=round(ideal_height*aspect_ratio);
//ideal_height=round(ideal_width/aspect_ratio);
ideal_width=round(ideal_width);
//ideal_height=round(ideal_height);
//Perfect Pixel Scaling
if(display_width mod ideal_width != 0)
{
var d = round(display_width/ideal_width);
ideal_width=display_width/d;
}
if(display_height mod ideal_height != 0)
{
var d = round(display_height/ideal_height);
ideal_height=display_height/d;
}
//Check to make sure our ideal width and height isn't an odd number, as that's usually not good.
if (ideal_width & 1) {
ideal_width++;
}
if(ideal_height & 1) {
ideal_height++;
}
surface_resize(application_surface,ideal_width,ideal_height);
display_set_gui_size(ideal_width,ideal_height);
if (os_type == os_windows || os_type == os_macosx || os_type == os_linux) {
window_set_size(ideal_width,ideal_height);
}
room_goto(rGame);
camera_set_view_size(view_camera[0], ideal_width, ideal_height);
camera_set_view_pos(view_camera[0], room_width/2-camera_get_view_width(view_camera[0])/2, room_height/2-camera_get_view_height(view_camera[0])/2);
view_enabled=true;
view_visible[0]=true;
show_debug_message(ideal_width);
show_debug_message(ideal_height);
For that last solution to work, you would need to draw the application manually yourself. You can disable the automatic drawing of the app surface and then draw it yourself in a post-draw or draw GUI event.Hi Pixelated_Pope,
I'm having issues with pixel-perfect scaling for Iphone and I was wondering if you could help me. I can't find the exact answer inside your tutorial so that's why I'm asking here.
My game is developed for iOS, Android and Windows. The view size is 320x180 (16:9) which means it scales well on most Android devices and PC screens, because it almost always scales at integer values (x2,x3,x4,...)
However, Iphones 6 to 8 use a resolution of 1334x750, which is 16:9, but scales up with a non-integer value: 4,167.
The result is pixel deformation and it is incredibly noticable.
I can of course change the view size on these devices to make a bettter fit, but this means more (or less) of my room is visible and I would like to keep this the same between platforms.
I tried to limit the application surface to integer scaling only (in the case of 1334x750: x4), meaning the application surface will be smaller than the screen, centered with black bars around it.
However, this does not work, because the application surface position doesn't match the drawn application surface (Gamemaker can only keep aspect ratio or stretch). Example: Some of my objects are clickable and the game thinks they're in a different position than they're drawn, so the clicking is off.
My question is: Is there a better or alternative way to achieve pixel-perfect scaling on these Iphone devices?
Thanks in advance
That doesn't work, the actual application surface position is not the same as the drawn application surface position in this case.For that last solution to work, you would need to draw the application manually yourself. You can disable the automatic drawing of the app surface and then draw it yourself in a post-draw or draw GUI event.
ideal_width = 320;
ideal_height = 180;
application_surface_draw_enable(false);
window_set_size(1200,300); //or whatever
display_set_gui_size(ideal_width,ideal_height);
scale = floor(min(window_get_width()/ideal_width,window_get_height()/ideal_height))
var _xoff = window_get_width()/2 - (ideal_width*scale/2);
var _yoff = window_get_height()/2 - (ideal_height*scale/2);
draw_surface_ext(application_surface,_xoff,_yoff,scale,scale,0,c_white,1);
var _win_w = window_get_width();
var _win_h = window_get_height();
var _ideal_w = console.ideal_width;
var _ideal_h = console.ideal_height;
var _game_w = _ideal_w*scale;
var _game_h = _ideal_h*scale;
var _xmarg = (_game_w-_win_w)/(scale*2);
var _ymarg = (_game_h-_win_h)/(scale*2);
global.mx = lerp(_xmarg,_ideal_w-_xmarg,window_mouse_get_x()/_win_w);
global.my = lerp(_ymarg,_ideal_h-_ymarg,window_mouse_get_y()/_win_h);
if(point_in_rectangle(global.mx,global.my,bbox_left,bbox_top,bbox_right,bbox_bottom))
image_blend=c_black;
else
image_blend=c_white;