SFML community forums
Help => Graphics => Topic started by: Haikarainen on September 03, 2011, 09:42:41 pm
-
Shaders? Repeating sprites? Wanted to discuss this topic here since I never have created it before and wanted some nice pointers ;)
-
For starters the wikipedia page got a few methods: http://en.wikipedia.org/wiki/Parallax_scrolling
-
For starters the wikipedia page got a few methods: http://en.wikipedia.org/wiki/Parallax_scrolling
Yes, ive read that, talking about more C++ / SFML specific tho ;p
-
Ah! Well for the game I posted in the interview thread in the start screen there's a starfield that scrolls for infinity. That was achieved by using 2 sprites which both slowly move backwards, when a sprite is pushed to the end so it's not visible any more I swap it back to the starting position to have it scroll forever. Both sprites used the same texture though.
To achieve parallax just have several layers of what I just wrote.
-
How to do this effeciantly is a good question. In my game there's a fair bit of parallax going on, but it's really simple stuff.
I guess it depends how graphically intensive the end result needs to be. The layers method would be good if you needed to represent a game level in really stunning parallax, but a lot of work per level.
Donkey Kong Country on the Wii always makes my jaw drop off; I know there's some 3D going on in there somewhere, but the overall effect is largely 2D parallax and absolutely brilliant at that. Beautiful stuff.
-
I think i know a good solution, lets check on that
Lets call any parallel screen, that needs scrolling at diferent speeds, a layer.
Lets say a layer has a view associated.
When a view is moved, it is moved by a certain amount.
So, a good idea would be to add a speed_factor property to each layer, which multiplies the amount of movement the view suffers.
When your character moves, it will describe a movement along the axes, lets say player_movement variable.
normally, so the main layer view moves along with the player, it moves at the same rate, so it moves by player_movement.
To keep this afirmation true, the main layer speed_factor would be 1. This way the main layer view would follow the player exactly.
Now lets say a background layer should never move. Just assign it a speed_factor of 0, it never moves a inch.
And now just play with that speed_factor for anything in-between static and following the player.
This approach is so simple and effective that you should even achieve dynamic parallax scrolling easily, changing this value acording to your own algorithm. All you need is actually speed_factor and player_movement
You could even compute the speed_factor acordingly to the layer width, so when the main layer is on the end, all the others are too :)
Tell me what you think, if it is not clear, tell me too :)
-
I think i know a good solution, lets check on that
View's for each layer is an interesting option, wouldnt it be rather slow tho?
The thing is I have an environment set up already, tilemap, player, sidescrolling camera. So I need to pass the cameras center-position to the parallax layers, and set a depthfactor to each layer, and it will do the rest automatically. This will be as OO and Datadriven as possible, since the rest of my engine is.
Think im gonna start coding on this now, ill tell ya if i get progress ;D
-
Ah! Well for the game I posted in the interview thread in the start screen there's a starfield that scrolls for infinity. That was achieved by using 2 sprites which both slowly move backwards, when a sprite is pushed to the end so it's not visible any more I swap it back to the starting position to have it scroll forever. Both sprites used the same texture though.
To achieve parallax just have several layers of what I just wrote.
Have the exact same thing for consoleshaders (like in quake3) but i want a more elegant solution ;P Since they have to scroll infinitely, maybe have a vector of sprites (count based on resolutionsize/imagesize+1) and just set a fake-depth-factor and a position-offset to it? That should totally work!
-
Donkey Kong Country on the Wii always makes my jaw drop off; I know there's some 3D going on in there somewhere, but the overall effect is largely 2D parallax and absolutely brilliant at that. Beautiful stuff.
Yes, donkey kong really is a piece of work :D always been, remember playing DKC on SNES when i was little, was stunned by the parallax back then even ;) And yes, wii's is a huuge improvement :D
-
Changing the view should be a simple matrix multiplication as far as i know, i dont think it would be slower than changing the image any other way! :)
And if you dont want to change your approach, just make your "player_movement" the difference between the new passed camera-center and the previous one :) Should work if my mind is not failing :)
By the way, how do you guys go about those landscape images, eventually they will exceed your gpu limitations in width. Do you tile a few images or what?
-
Changing the view should be a simple matrix multiplication as far as i know, i dont think it would be slower than changing the image any other way! :)
And if you dont want to change your approach, just make your "player_movement" the difference between the new passed camera-center and the previous one :) Should work if my mind is not failing :)
By the way, how do you guys go about those landscape images, eventually they will exceed your gpu limitations in width. Do you tile a few images or what?
I was thinking about "virtual tiling" every layer. So that one image is always repeated unless specified otherwise.
-
I was thinking about "virtual tiling" every layer. So that one image is always repeated unless specified otherwise.
Wasn't that what I described?
-
Hi!
I know it's too late maybe, but I'd like to re-open the discussion.
My approach is the following: I have two different classes, 'layer' and 'level'. A level is actually composed by a set of layers, and a layer is onto where the objects are drawn. During the level setup, I create its layers, and I assign a scroll velocity to each layer.
layer1.setScrollVelocity(1.0f);
layer2.setScrollVelocity(0.5f); //layer 2 moves half slower than layer 1
In the update function of the frame, I update the position of all the objects in the layer and the movement of the layer itself.
This seems to work fine for me, but I have another problem. I'd like to check whether I'm on any screen limit in order to stop the movement of the layer. However, I don't know how to do this. If the layer (e.g. a background) is moving at a factor of 1.0, it's straightforward, as I can check if the position of the player is the size of the bitmap that fills the background. However, if the factor is less (and therefore is moving slower), I don't know how to check.
At the beginning, I assumed that if the background moves at 0.5f, and the width of the background bitmap is 2000 pixels, I should arrive at the right limit when the character is 4000, but this doesn't seem to work.
Any ideas?