Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411430 Posts in 69363 Topics- by 58416 Members - Latest Member: JamesAGreen

April 19, 2024, 07:10:57 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Problem with views... they're pixel perfect
Pages: [1] 2
Print
Author Topic: Problem with views... they're pixel perfect  (Read 6727 times)
Alessio
Level 0
***


Visual Artist


View Profile
« on: August 02, 2016, 09:43:04 AM »

I felt the need to open a new thread for this because i've got the feeling that i will never solve this nasty problem.  No No NO

Now i have problem making my background looking nice when scrolling through the level.

It's common that the code used for background parallax scrolling is something like this:
Code:
background_x[1] = view_xview[view_current] * 0.6

While this alone is fine, it doesn't seem to get on well wiht the Game Maker's view system.
I mean, i've replaced "view_xview" with something else and the background scrolls nicely... until i move the view and the background begints to tremble, flickering, shaking when i accelerate and decelerate the view's speed (which isn't view_hspeed but just view_xview)
Namely, when the view's x position (it applies to y too) increases or decreases, namely, is not constant, the object in question (can be an actual object or a background), when at non-integer values, can't catch up with the "pixel perfect" motion of the view and causes what looks a slight but annoying shaking.

My resolution is 320x240 but my port on screen is 1024x960. It seems that Game Maker: Studio, while at a high resolution port on screen everything in the game moves smoothly, namely, every monitor's pixel (my monitor resolution is 1920x1080), Game Maker's views move every view's pixel.

I believe this is just plain weird. But even if i keep my port on screen to the same size of the view, the background and any object that moves depending on the x/y position of another one, it gives flickering problems.

Someone suggests to use custom views or custom background scripts but i believe that they're not very practical and i'd prefer to work with what Game Maker offers by default. I've used few codes that tells how to make sub-pixel movements but i had this problem even with using Heartbeast's perfect platformer tutorial: the player object used to stutter while at non-integer positions. This problem is present only when i use views.

How do you fix this? Is there an option on a "professional" version of game maker (i use free standard) like there is an option for texture page size? Why does Game Maker force the view to move pixel perfect but not anything else?
Logged
oahda
Level 10
*****



View Profile
« Reply #1 on: August 02, 2016, 09:53:15 AM »

I'm wondering if it just has to do with integers and flooring or something. Does rounding the result of that multiplication help? Or having your own floating point number that keeps track of the view's x instead, by which you multiply the parallax positions, in case view_xview always gets floored or rounded to an int while your own value would not? These are just guesses from someone who hasn't used GM since 6.0, so I don't actually know if this has anything to do with it at all, but they seem like simple enough things worth trying just in case.
Logged

Polly
Level 6
*



View Profile
« Reply #2 on: August 02, 2016, 10:24:02 AM »

The view_xview / view_yview variables are ( treated as ) integers* The easiest workaround for this is to define your own view position variables and call "d3d_transform_set_translation(-my_xview, -my_yview, 0)" before or at the start of the draw event.

*When you want pixel-perfect scrolling this is the preferred setup, but when you want sub-pixel scrolling it's no good obviously.
Logged
Alessio
Level 0
***


Visual Artist


View Profile
« Reply #3 on: August 02, 2016, 12:40:44 PM »

I tried flooring or rounding, any of that actually help.

My graphics' style are retro, therefore i'd be fine with using pixel perfect motions.
Shovel Knight (i'll clarify i know that was made with a custom engine made with C++) uses very smooth movements although it's all pixel art. I don't know if they used an actual engine or they just have scaled up their sprites. Everything is smooth, in that game. Now, scaling up is not anything i'm gonna do. My "game" has a resolution of 320x240, like i've mentioned.

Now i just don't know why in the god didn't YoYo games developers put an option that makes me set the general game's smoothness (ie, if my character can move every pixel or every half pixel or even a quarte of pixel). Making the view's x/y position integers while everything's x/y position non-integers is, not to appear controversial, just insane. There isn't even an actual guide of it (AFAIK). I hope they fix this in GM 2.0 but they're two years late with that. Sometimes i even wonder if i ever have to switch to something else, kinda like Construct 2,
As i've side, mine is not polemic or controversy, i just wonder if i have to feel ashamed for jumping to something else. Because i still want to learn.

But back to the problem:
How am i supposed to use "d3d_transform_set_translation(-my_xview, -my_yview, 0)"? Isn't "d3d" used for 3D rendering?
Also, at this point, isn't it better that i make my stuff move every pixel like in the old 16 bit games? Because that i am looking for is a 16-bit motion, not a Shovel Knight motion (where everything moves smoothly).

That brings me to another question about sub-pixel motion: is there a way to force every object move to snap its position every pixel? Although i still have the problem of stuttering background because:
Code:
background_x[1] = (view_xview[view_current] * 0.6)
will make the background shake a little even at constant speed.
I wonder: are these features glitchy?
Logged
Polly
Level 6
*



View Profile
« Reply #4 on: August 02, 2016, 01:09:42 PM »

Sometimes i even wonder if i ever have to switch to something else

Every engine is going to have things that don't work as you'd expect / want to. As long as they are easy to circumvent, try not to worry about it too much.

How am i supposed to use "d3d_transform_set_translation(-my_xview, -my_yview, 0)"?

It's literally a matter of swapping out your view_xview / view_yview assignments with a d3d_transform_set_translation call.

Isn't "d3d" used for 3D rendering?

No, the d3d prefix refers to Direct3D, which is what Game Maker runs on.

Also, at this point, isn't it better that i make my stuff move every pixel like in the old 16 bit games? Because that i am looking for is a 16-bit motion, not a Shovel Knight motion (where everything moves smoothly).

In that case i'd recommend drawing your game to a 320x240 surface ( which solves all the problems you mention ).

Although i still have the problem of stuttering background

That's because the view coordinates are ( treated as ) integers. If you'd for example do "view_xview[0] += 0.4;" each step, the value never changes.

I wonder: are these features glitchy?

Nope Smiley
Logged
Alessio
Level 0
***


Visual Artist


View Profile
« Reply #5 on: August 02, 2016, 02:15:52 PM »

Quote
It's literally a matter of swapping out your view_xview / view_yview assignments with a d3d_transform_set_translation call.
Sorry but i still don't get it  Embarrassed
How should i actually define my variables? Should i set something like "my_xview = view_xview[view_current]"?

Quote
No, the d3d prefix refers to Direct3D, which is what Game Maker runs on.
I knew that standed up for "Direct3D" but in the docs i've read it's for 3D documentation.

Quote
In that case i'd recommend drawing your game to a 320x240 surface ( which solves all the problems you mention ).
Yeah i've read about this solution, still didn't implement it. This makes me question something else:
You mean that this code below is pointless then?
Code:
cx += vx;
cy += vy;
vxNew = round(cx);
vyNew = round(cy);
cx -= vxNew;
cy -= vyNew;
I've used this from a small platformer engine i've found in a platformer guide. That's a code that forces an object move every subpixel but only if you use the "vx/vy" variables. If you use x/y alone, this "pixel snapping" won't work, obviously.
I've even tried using "x= (x div 1)*1" but doesn't seem to work with background_x[num] and with sub-pixel movements.
With surface scaling, so, it's gonna be useless?

Quote
That's because the view coordinates are ( treated as ) integers. If you'd for example do "view_xview[0] += 0.4;" each step, the value never changes.
Got it but why does the background stutters? It does stutter even if i use background_x[1] = floor(view_xview[view_current] * 0.6).
Althoug i noticed that this happens with any object that has its x/y position with another one's positions and divided by a number. Why does the code "obj1.x = obj2.x *0.5" make the obj1x stutter when moving?

Quote
Nope Smiley
That's why i wondered why shouldn't the views move as smoothly as anything in the engine or viceversa. I think that's just illogical from YoYo.
Logged
oahda
Level 10
*****



View Profile
« Reply #6 on: August 03, 2016, 02:30:15 AM »

I wonder: are these features glitchy?
Nope Smiley
Nonetheless an odd decision. Easier to round a float manually if pixel-perfection is desired than to circumvent the built-in view system to get subpixel stuff working. Should be float by default. Waaagh!
Logged

Polly
Level 6
*



View Profile
« Reply #7 on: August 03, 2016, 03:34:12 AM »

Nonetheless an odd decision.

Agreed.

Easier to round a float manually if pixel-perfection is desired than to circumvent the built-in view system to get subpixel stuff working.

The workaround is ( as mentioned ) dead-easy too though Wink Anyway, Alessio wants pixel-perfect scrolling .. so no workaround required.
Logged
Alessio
Level 0
***


Visual Artist


View Profile
« Reply #8 on: August 03, 2016, 08:18:21 AM »

I wonder: are these features glitchy?
Nope Smiley
Nonetheless an odd decision. Easier to round a float manually if pixel-perfection is desired than to circumvent the built-in view system to get subpixel stuff working. Should be float by default. Waaagh!

Indeed what i was meaning. Why make everything in Game Maker with float values but make the views with integer ones? Not sure if it's an odd decision or an oversight. Which is weird from a company like YoYo Games. Sorry for sounding polemical but i want to point it out.

It's not acceptable from a very notorious 2D game framework thought for pixel games. Yeah, workaround is easy but why not then give the option by default and, maybe, have an option to set background scrolling from the room editor in the first place, why not?? This is directed to YoYo Games.

What i mean is that a lot of Game Maker users heavily criticizes the built-in functions like "solid", "hspeed", "check collision", "place free", "gravity" and many others that are also drag-n-drop features. The main complaints are that most of these don't work properly but i'm not entirely sure.

That's a good question i want to ask: why not use built-in variables? Why most do pro users discourage you from using them?

Game Maker, as a 2D game engine, is great, i admit it, otherwise it wouldn't be so popular. Shame it could be more accessible and more complete, with more automated features and actually working tools. Let's hope they really fix this in GM 2.0, if it will ever come out. But these oversight are just weird and awkward for a 2D game development kit. That's why i was thinking to try something else, but i'll try to stick with GM for now. I know i shouldn't be writing this in TIGsource, which cover all game engines, but i wanted to point it out anyway.

I was asking something, not to be repetitive.
I was using that code i've written in my previous post. It rounds my value and supports sub-pixel motion although my object's position snaps every pixel. But if i just change Game Maker's default application surface to 320x240, making everything scaled up manually (again, this should be an avaiable option by default), will i need it? I ask because i'd be forced to put that code in every instance, which isn't very handy, actually.

If i use the view workaround and change the application surface to 320x240, will it look nice and have a 16-bit feel anyway?
Logged
Polly
Level 6
*



View Profile
« Reply #9 on: August 03, 2016, 10:06:28 AM »

Indeed what i was meaning. Why make everything in Game Maker with float values but make the views with integer ones?

I suspect it was a combination of the view port variables being integers ( these have to be integers since they control the window size, and Windows / Mac / Linux don't support non-integer window sizes ) and their primary focus being pixel-perfect rendering.

What i mean is that a lot of Game Maker users heavily criticizes the built-in functions like "solid", "hspeed", "check collision", "place free", "gravity" and many others that are also drag-n-drop features. The main complaints are that most of these don't work properly but i'm not entirely sure.

Nothing wrong with these features. But when they don't work exactly like some people want / expect, they sometimes complain about them and / or suggest a DIY solution instead.

But these oversight are just weird and awkward for a 2D game development kit. That's why i was thinking to try something else, but i'll try to stick with GM for now.

All engines have ( small ) things to nit-pick about.

If i use the view workaround and change the application surface to 320x240, will it look nice and have a 16-bit feel anyway?

As soon as you use a 320x240 surface all the problems you mentioned will be solved. No workarounds needed.
« Last Edit: August 03, 2016, 10:31:38 AM by Polly » Logged
Alessio
Level 0
***


Visual Artist


View Profile
« Reply #10 on: August 03, 2016, 02:34:08 PM »

Quote
I suspect it was a combination of the view port variables being integers ( these have to be integers since they control the window size, and Windows / Mac / Linux don't support non-integer window sizes ) and their primary focus being pixel-perfect rendering.
Makes sense  Roll Eyes
But shouldn't have YoYo done the opposite then? Make everything else in the game integer (but still supporting floating point values)? If i did really want to make my pixel art move smoothly (like in Shovel Knight) there would have been an actual option where the whole graphics could be scaled up (or just scale up the graphics before importing them into Game Maker).
Not wanna do a caucus race, though. Mine are honest opinions.

Quote
Nothing wrong with these features. But when they don't work exactly like some people want / expect, they sometimes complain about them and / or suggest a DIY solution instead.
They're discouraged even by "officially supported by YoYo Games" users. The majority of tutorials just discourage you from using these. That's why i was doubtful of this. I wonder what's wrong this this matter.

Quote
As soon as you use a 320x240 surface all the problems you mentioned will be solved. No workarounds needed.

Eeew sorry, but there is still something wrong with it.
I've actually tried to change my view port to 320x240, like the view size (and use "allow resize window" to resize the surface so i can see the pixels) and, while everything moves pixel perfect as expected, my background still stutters. I swear to god.
That's why i just can't understand what's wrong with this.

And that's why i even tried your workaroud to see the effects but still don't get how to implement it right.
I've created an object called objViewFix and put it in the room i'm playing. I've put a "Create" event and set this:
Code:
global.my_xview = 0
global.my_yview = 0
Then i've put a "Begin Draw" event and set this:
Code:
d3d_transform_set_translation(-global.my_xview, -global.my_yview, 0)
In my total ignorance, i've put a "Begin Step" event and set this:
Code:
global.my_xview = view_xview[view_current];
global.my_yview = view_yview[view_current];
This gives funny results (a "beautiful fails" kind of one) and causes graphical glitches but i admit this stops the stuttering. What's wrong with this, though?
Logged
Polly
Level 6
*



View Profile
« Reply #11 on: August 03, 2016, 03:15:36 PM »

But shouldn't have YoYo done the opposite then? Make everything else in the game integer (but still supporting floating point values)?

Game Maker uses nearest neighbor filtering by default, so objects / sprites get drawn pixel-perfect regardless ( at native resolution ), while floating-point give you the benefit of staggered motion without having to resort to fixed-point / LUT solutions ( as you'd have to on real 16-bit systems ).

Forget about the workaround, you're going for pixel-perfect so you don't need it.
Logged
oahda
Level 10
*****



View Profile
« Reply #12 on: August 03, 2016, 09:13:54 PM »

Forget about the workaround, you're going for pixel-perfect so you don't need it.
Isn't it the opposite? The title of the thread says the problem with the views is that they're pixel perfect. And stuttering sounds like an artifact of that?
Logged

Polly
Level 6
*



View Profile
« Reply #13 on: August 04, 2016, 12:50:14 AM »

Isn't it the opposite? The title of the thread says the problem with the views is that they're pixel perfect. And stuttering sounds like an artifact of that?

The artifact is ( at least partly ) because he's driving the background position using the view coordinates, he should use a floating-point variable instead. The d3d_transform_set_translation workaround is only for when you want sub-pixel scrolling.
Logged
oahda
Level 10
*****



View Profile
« Reply #14 on: August 04, 2016, 01:08:13 AM »

I thought you were saying the opposite, that they should just stick to the built-in integers and not drive the view with custom floats. Tongue Misunderstanding somewhere then. All right. We seem to be on the same page after all.
Logged

Alessio
Level 0
***


Visual Artist


View Profile
« Reply #15 on: August 04, 2016, 04:00:49 AM »

Quote
Forget about the workaround, you're going for pixel-perfect so you don't need it.

I probably do, instead. I don't know if i didn't explain myself well.
Yes, i want a pixel perfect feel but... apparently, Game Maker gives issues with this too.
I've made an example application to show you better the issue i'm having, look:

http://download1322.mediafire.com/fzn13c5qhdgg/dzhna6n4rahmgdn/problem.exe

Everything in the game moves smoothly. the resolution and the port on screen is at 320x240 but you can resize it.

You'll notice how much everything in the game is stuttering. And it's just annoying. I believe it's because of the view that is forced to integers. Even if everything looks pixel perfect because of the resolution but everything
That's why i've been asking for a better explanation for that workaround: maybe with that, everything will stop stuttering.

By the way, my GM version is GM:Studio 1.4.1757.

edit:

Quote
The artifact is ( at least partly ) because he's driving the background position using the view coordinates, he should use a floating-point variable instead. The d3d_transform_set_translation workaround is only for when you want sub-pixel scrolling.

I understand what you're writing here. Indeed i tried using "background_x[1] = global.my_xview * 0.6" instead of "background_x[1] = view_xview[view_current] * 0.6" but that doesn't fix the stuttering even at view port set at 320x240 with a resolution of 320x240.
« Last Edit: August 04, 2016, 04:54:19 AM by Alessio » Logged
Eclipse
Level 10
*****


0xDEADC0DE


View Profile WWW
« Reply #16 on: August 04, 2016, 05:00:58 AM »

Shovel Knight is always pixel perfect (upscales it's game resolution)

your problem is probably not related to stuff being pixel perfect, as old games like Gunstar Heroes have very fluid scrolling with low resolution and just integer math. Besides rendering stuff at subpixel coordinates will make pixel art look like crap.

You are either updating the movements unevenly (for example using a delta time that changes wildly) or accumulating wrong sub pixel movements that makes your frame "jump" after a certain time.

You need to have a fixed timestep if you want to have a smooth looking scrolling background. I don't use GameMaker but probably you need something like (pseudocode)

ScrollTimer+=DeltaTime;
float ScrollUpdateTime = 1.0/60.0;

if (ScrollTimer>=ScrollUpdateTime)
{
   ScrollTimer-=ScrollUpdateTime;

   //move background using a fixed int value, not multiplying it with DeltaTime
   Background.position.x += scrollSpeed;
}

Logged

<Powergloved_Andy> I once fapped to Dora the Explorer
Polly
Level 6
*



View Profile
« Reply #17 on: August 04, 2016, 05:11:06 AM »

You'll notice how much everything in the game is stuttering.

Are you using the built-in speed variable to move the rectangle around? If so, you shouldn't use the rectangle coordinates to drive the view coordinates in the Step event, since you're working with data that's one frame old at that point.

Quick demo in Game Maker ( 30fps GIF ) ...

Logged
Alessio
Level 0
***


Visual Artist


View Profile
« Reply #18 on: August 04, 2016, 06:16:40 AM »

post

I'm not a real programmer so i don't know how i would be supposed to replicate that code.
Especially because Game Maker has its own logic and engines. GML is supposed to replicate programming experience but everything there but your own functions are pre-built. the code about background scrolling is actually the one recommended by everyone in the community. Yet something is very wrong with the view system in Game Maker, that forces its position in pixel coordinates while the rest doesn't. It's not something i've decided myself. The same problem with views was pointed out by Heartbeast in one of his tutorials, actually, therefore, it's not a specific problem of mine.
Quote
Are you using the built-in speed variable to move the rectangle around? If so, you shouldn't use the rectangle coordinates to drive the view coordinates in the Step event, since you're working with data that's one frame old at that point.

Quick demo in Game Maker ( 30fps GIF ) ...
*image*

No, i'm not using built in variables here. This is the code set for the horizontal speed: x += hspd. Therefore, no built in variable. But yeah, it was a quick demo so i've put the rectangle as "object following" In the other project i'm working, though, i use a "camera" object that follows the player around and is set in the view "object following" field. but there is no difference anyway. Every "object following" i use gives a very annoying stuttering effect and everything that moves actually stutter because of the views.
The code for the background scrolling is, as usual: background_x[1] = view_xview[view_current] * 0.6 and is separated from the rectangle object.

I have a question but don't want to sound rude or something: I've the feeling you're avoiding explaining me that workaround, but why? Wouldn't it make the game more polished? I would learn something then.
Logged
oahda
Level 10
*****



View Profile
« Reply #19 on: August 04, 2016, 06:44:18 AM »

AFAIK GM has a fixed time step by default (room speed) so you shouldn't need to mess with that anyway.
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic