Legacy GM [SOLVED] Parallax Scrolling for Single Screen (static view) Game.

KamilSeven

Member
[POST-EDIT]
The issue (solved) in this thread was about smooth movement (subpixel movement) in low-resolution games.
[POST-EDIT/END]
Hi!
I want to have a parallax scrolling background for a single screen game with GM:S 1.4. The exact same effect is buildings bg. in Super Crate Box by Vlambeer. I've already checked some of the tutorials and threads on the topic. But most of them were about side-scrolling games.
I have tried using,
Code:
 background_x[0] = lerp(0, -obj_player.x, 0.2);
But depending on the speed, background eighter so fast or so jittery (like pixel by pixel not fluid).
My room size is 240x160px.

Example:
Like I said, I'm trying to figure out the buildings bg. (moves depending on the player's position) not the clouds.
 
Last edited:

obscene

Member
Maybe put that code in the End Step event and it will smooth out. 0.2 seems a little extreme IMO as well but I'm sure you've tried smaller values?
 

KamilSeven

Member
Maybe put that code in the End Step event and it will smooth out. 0.2 seems a little extreme IMO as well but I'm sure you've tried smaller values?
Tried using it in the End Step but didn't make any difference. And about the value, even when it's 0.2, it is still much faster than desired. But when I use smaller values to get the speed I want then it starts to move jittery.
I might be missing some simple step in this one.
 

kupo15

Member
Barring the fact that parallax technically shouldn't work that way as the camera isn't moving aside (it does make it look more interesting though) I think your code isn't correct

Code:
background_x[0] = lerp(BGX, -obj_player.x, 0.2);
I'm assuming the 0 is the x starting position of your bg? Well once the bg moves to a new location from the lerp you want to reference the new location to lerp to the next new location not the original location. You are also missing a key piece of data for this. You need to establish what the reference default position on the screen you want no parallax to be and find the xdifference the player is from that point and use that as your parallax adjustments.

bg_x = starting x of the bg+(xdisplacement_of_player_from the reference point in the screen * % reduction of that movement)

So if the player moved 100px to the right from the reference point on the screen you've set up and you only want the bg to move half as fast then the filled in calculation would be

bg_x = 0+(100*0.5) // this is for normal parallax

For lerping you would be lerping the bolded value

bg_x = lerp(bg_x,bolded calc,0.2) // lerp from the current bg_x to the new bg_x
 
Last edited:

samspade

Member
My guess is the parallax in the example is based on the players movement not the camera. If you watch the clouds just scroll by, however, the building clearly move relative to the player's x position. So you can probably just implement traditional parallaxing but do it on the player's x position rather than the camera's position. As far as choppy-ness personally, I don't think the Super Crate Box looks that smooth. The only way for it be smooth (assuming good code) is to have it drawn to the screen at a high enough resolution that a single pixel of movement is generally possible at low speeds.
 

kupo15

Member
The premise is super weird. The clouds are nice, but the buildings moving... I had never noticed that, and now that you brought that to my attention I can't unsee it. Wrong parallax reminds me of Jim Power.
Wow that game's parallax is wrong for a different bad reason lol


My guess is the parallax in the example is based on the players movement not the camera. If you watch the clouds just scroll by, however, the building clearly move relative to the player's x position. So you can probably just implement traditional parallaxing but do it on the player's x position rather than the camera's position.. .
The thing is though his game is a static non moving camera just like the game he showed off. Static camera means no parallax technically except for things like clouds and such but then is that really parallax or just moving objects?
 

KamilSeven

Member
My guess is the parallax in the example is based on the players movement not the camera. If you watch the clouds just scroll by, however, the building clearly move relative to the player's x position. So you can probably just implement traditional parallaxing but do it on the player's x position rather than the camera's position. As far as choppy-ness personally, I don't think the Super Crate Box looks that smooth. The only way for it be smooth (assuming good code) is to have it drawn to the screen at a high enough resolution that a single pixel of movement is generally possible at low speeds.
I agree. Now, I'm going to watch PixelatedPope's Parallax Scrolling video (the one using lerp) again and try to implement it to player's x instead of view_x. I'm going to post the outcome here. Thank you all for the replies.
 

KamilSeven

Member
So guys,
I've watched PixelatedPope's parallax scrolling tutorial again. But I was unable to implement it for player x position because it uses view_wview. Even if I could, I'm not sure if it would solve the problem. I know in the example video, SCB's building bg looks choppy, but if you download the game and check, you'll see it's smooth as butter. Here is the thing, when the player moves from left margin to right margin, building bg moves in a very short distance, yet, it moves very smooth. I'm almost sure Super Crate Box's room size is 240x160px. I cannot find any explanation how it is possible (I'm a beginner at programming). I've tried effecting backgrounds hspeed with the player's speed variable, also tried bg.'s x position with player's x, divided those numbers to make it slow. I have also tried higher resolution bg. Still, even when it moves pixel by pixel (which looks really ugly) it still takes a longer distance than SCB's parallax bg.
 
C

Caique Assis

Guest
Did you define the View in the room editor? I remember that when you do it that way, if you check the "object following" box too, the View will pretty much ceil any decimal value. So, for example, if you define it by the room editor, you'd only be able to move by values of 1px. But through code, you'd be able to move it by decimal values. (I don't remember if creating the View through the room editor alone causes that, or you had to check the "object following" box. Take this comment with a grain of salt...)
 

KamilSeven

Member
Did you define the View in the room editor? I remember that when you do it that way, if you check the "object following" box too, the View will pretty much ceil any decimal value. So, for example, if you define it by the room editor, you'd only be able to move by values of 1px. But through code, you'd be able to move it by decimal values. (I don't remember if creating the View through the room editor alone causes that, or you had to check the "object following" box. Take this comment with a grain of salt...)
No, I didn't use object following in, room editor. The game has a single screen and the view size is fixed to room size which is 240x160px. I'm trying to move background via player position, not the view position.
 
S

Sandro

Guest
Looks linear to me. Maybe something like this:
Code:
background_x[0] = (obj_player.x - room_width/2)/n;
Replace n with some number to determine the speed in which you want the background to scroll. Higher numbers will be slower.
 

KamilSeven

Member
Looks linear to me. Maybe something like this:
Code:
background_x[0] = (obj_player.x - room_width/2)/n;
Replace n with some number to determine the speed in which you want the background to scroll. Higher numbers will be slower.
Thanks for the reply. But it is still choppy. When I use a lower number like 4, it moves very smooth, but background takes so much distance(Scrolling a lot of pixels). In SCB, background scrolls like 10px when the player moves the margin to margin and it moves really smooth.
 

kupo15

Member
Maybe you can show some sort of video about the choppiness you are seeing because from the multitude of good responses here I can't understand how its not doing what you want. Did you not look at my response earlier?
 
S

Sandro

Guest
Thanks for the reply. But it is still choppy. When I use a lower number like 4, it moves very smooth, but background takes so much distance(Scrolling a lot of pixels). In SCB, background scrolls like 10px when the player moves the margin to margin and it moves really smooth.
Try using a power of 2 for n; so: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192...
If your player's movement speed is also a power of 2, everything should just divide nicely without creating really crazy decimals.
 

KamilSeven

Member
Maybe you can show some sort of video about the choppiness you are seeing because from the multitude of good responses here I can't understand how its not doing what you want. Did you not look at my response earlier?
I've seen your first response and try to implement it, but I couldn't figure it out. The 0 on lerp I have used was just to reduce the number as I saw it in the gms documentation for lerp.

Code:
background_x[1] = -(obj_player.x - room_width/2)/12;
Scrolling distance is okay but the movement is choppy.


Code:
background_x[1] = -(obj_player.x - room_width/2)/4;
Movement is smooth but scrolling distance is too much.

 
You need to resize your application surface to be larger than your game's view/room size. This will give you more pixels for movement and scrolling. But be warned, this is essentially increasing the resolution of your game, and you should expect the same impact on performance that you would get from increasing a 3D game's resolution setting.
 
S

Sandro

Guest
I'm pretty sure the chopping effect is from floating point rounding errors. 4 works because it's a power of 2. Try 16, not 12;

Assume your player movement speed is 4,
4/12 = 0.333333333
4/16 = 0.25

0.333333333 + 0.333333333 + 0.333333333 = 0.999999999 // Will never align with 1 pixel
0.25 + 0.25 + 0.25 + 0.25 = 1 // Perfect
 

kupo15

Member
Assume your player movement speed is 4,
4/12 = 0.333333333
4/16 = 0.25

0.333333333 + 0.333333333 + 0.333333333 = 0.999999999 // Will never align with 1 pixel
0.25 + 0.25 + 0.25 + 0.25 = 1 // Perfect
I don't think that is it though. Assume his movement speed is 5

5/16+5/16 etc will never line up with a whole pixel either
 
S

Sandro

Guest
I don't think that is it though. Assume his movement speed is 5

5/16+5/16 etc will never line up with a whole pixel either
Yes it will, for every 16 pixels the player moves, the background will move exactly 1 pixel.
5/16 = 0.3125;
The computer will keep track of decimals, but It has to round crazy ones that would go off the end of your calculator's screen.
In which case the computer will do the best it can: in the case of 4/12 = 0.333333333; The background will shift 1 pixel for every 11, OR SOMETIMES 12, pixels the player moves
 

KamilSeven

Member
Yes it will, for every 16 pixels the player moves, the background will move exactly 1 pixel.
5/16 = 0.3125;
The computer will keep track of decimals, but It has to round crazy ones that would go off the end of your calculator's screen.
In which case the computer will do the best it can: in the case of 4/12 = 0.333333333; The background will shift 1 pixel for every 11, OR SOMETIMES 12, pixels the player moves
I have also tried powers of 2 and it didn't make any difference. I guess the reason for choppiness was about the low resolution of room/view. I'll try resizing application surface as PixelatedPope suggested when I get back home. Again, thanks to all of you for your time and responses. I'll update the thread depending on the result.
 

KamilSeven

Member
You need to resize your application surface to be larger than your game's view/room size. This will give you more pixels for movement and scrolling. But be warned, this is essentially increasing the resolution of your game, and you should expect the same impact on performance that you would get from increasing a 3D game's resolution setting.
Thank you for your quick response, your highness. I'll try it when I get home.
 

KamilSeven

Member
You need to resize your application surface to be larger than your game's view/room size. This will give you more pixels for movement and scrolling. But be warned, this is essentially increasing the resolution of your game, and you should expect the same impact on performance that you would get from increasing a 3D game's resolution setting.
Thanks to Pixelated Pope's quick response, the problem has been solved. I'm really grateful for all the replies. All of them was correct on the parallax controlling setting but looks like my problem was about the low resolution of the room. This is why I've been unable to come up with an idea because I couldn't imagine how it would possible to smooth a movement between two pixels (there are no half pixels). The solution was multiplying my application surface with forces of 2. as is:

Code:
 surface_resize(application_surface,ideal_width*8,ideal_height*8);
(I was already using Pixelated Pope's display manager in my study project so, I just multiply my height and width with 8.

Here is the result:

[OFF TOPIC]
As sound designing was my main focus for a long time, I'm uploading some of the sounds I've designed to freesound.org. You can download the machine gun sound you hear in the video above also some other sound FXs such as interface sounds for free. I'll be updating these packs in time.
Here is the link. My gratitude to the GM community.

https://freesound.org/people/GokhanBiyik/

Thank you all...
 
Top