• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker image_angle and distorted pixels

C

Cautious Cactus

Guest
Hey, I'm working on a topdown game at low resolution and I use image_angle to rotate my wepons, I use a 320x240 resolution scaled to 960x720 or 1280x960.

The weapons sprites get really distorted, see image : https://imgur.com/a/qSHJssF

I tried pixel interpolation but it only makes everything blurry.

Anyway I can fix this without scaling up all my sprites ?

Thanks
 
Pixels are square. You can't rotate anything on a display that uses square pixels without distortion. The trick is finding ways to minimize the distortion.

How are you upscaling the original picture? If you're just upscaling the application surface, you will get the same amount of distortion you get at 320x240, meaning there's a ton of horrible-looking distortion. If you instead upscale all your sprites (e.g. 3x Scale for 720p), distortion will be far less noticable. This is what games like Terraria do.
 
C

Cautious Cactus

Guest
I use the viewport to scale the resolution, I see games like Nuclear Throne and you can play the game at like 320x180 and there's no distortion, really wish there would be another way than scaling all the sprites up manually
 
There likely is another way, since the example you gave looks distorted beyond what I'd consider normal. I'd wait for someone else to chip in before doing anything drastic, if only because I'm not the best when it comes to this topic.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Increase the size of the application surface to double the pixel count. My game Alpha Dog is actually programmed at a resolution of 90x45 (!), yet the app surface is more like 5 times that, so the rotations are silky smooth. Basically, just get the size of the camera width/height and then set the app surface to the same values time 2 or times 3 (eg: a camera of 320x240 would have an app surface of 640x480 or even 960x720).

Here's how my game looks, btw...

 
Last edited:
C

Cautious Cactus

Guest
Exactly what I needed, I did a

view_w = camera_get_view_width(view_camera[0]);
view_h = camera_get_view_height(view_camera[0]);
surface_resize(application_surface, view_w*4,view_h*4);

at the start of the game and it already looks better, I will play around the multiplier to get it right, thanks Nocture :)
 

NightFrost

Member
I do my pixel stuff with the multiplier method as well, except I calculate the multiplier at the start of the game, comparing my target size (like 480x270) to display size. This global.Scaling is then used to scale up everything siuch as app surface, camera, sprite draws and movement speeds. A noninteger multiplier is not desirable for much of that so I floor it, and if necessary calculate a stretch ratio for when app surface gets drawn to buffer. For example if there existed a 2100 wide display, 2100/480=4.375 which floors to 4 and gives an app surface width of 1920, and 2100/1920=1.09375 for surface draw stretch. The same of course is done with height so aspect ratio can be taken into account and centering values can be calculated if display's aspect is not the same.

EDIT - also image_xscale and image_yscale. Since we're stretching sprites here we must set these to stretch the mask too. Otherwise GMS will use original sprite values for masks.
 
I know this post is VERY old now, but I am having an issue using the multiplier method. Everything works fine, but then I started applying shaders to the application surface which means moving it to the Post-Draw event. When I do that it seems to mess something up either with my camera and views or something else, because the surface is drawn zoomed in at the multiplied amount (lets use *2 for this) and I end up with one fourth (width * 2 and Height * 2) of the intended view.

Again, everything works fine when I don't move the application surface to the post draw event... Any help would be appreciated. Thanks!
 

Tangerine

Member
I know this post is VERY old now, but I am having an issue using the multiplier method. Everything works fine, but then I started applying shaders to the application surface which means moving it to the Post-Draw event. When I do that it seems to mess something up either with my camera and views or something else, because the surface is drawn zoomed in at the multiplied amount (lets use *2 for this) and I end up with one fourth (width * 2 and Height * 2) of the intended view.

Again, everything works fine when I don't move the application surface to the post draw event... Any help would be appreciated. Thanks!
You need to draw the application surface stretched with your camera width and height.
Like this:

GML:
draw_surface_stretched(application_surface, 0, 0, _cw, _ch);
Where _cw is camera width and _ch camera height.

Also be sure to use the draw GUI begin event
 
You need to draw the application surface stretched with your camera width and height.
Like this:

GML:
draw_surface_stretched(application_surface, 0, 0, _cw, _ch);
Where _cw is camera width and _ch camera height.

Also be sure to use the draw GUI begin event
That worked! Woohoo!

Now I'm wondering why the draw GUI begin event instead of the Post draw event?
 
Top