Layer Scrolling

Feb 15, 2011 at 7:38 PM

I've just finished adding Gleed2D to my project however when my camera moves forward the layers don't move at different speeds they just move as a whole?

 

Woundering if there is a line of code or a way of accessing the Layers so that they my according to my Camera?

I need this as i have implemented Farseer to my project and my physics objects move faster then my background so i need them all to scroll at the same speed.

 

Has anyone else had this problem or know of a way of accessing the Layer so that it works with my Camera?

 

Thanks

Feb 16, 2011 at 9:35 AM
Edited Feb 16, 2011 at 9:36 AM

I render each layer in separate sprite batches - and each of them have their own transform matrix - which all are computed using main camera position multiplied with layer's scale factor, rotation and scale.

My level object has reference to main camera, and it is accessible from all children layers - layers then use it to compute their transform matrices.

 

        public void updateTransform()
        {
            Transform = Matrix.Identity *
                    Matrix.CreateTranslation(-(parent as Scene).currentCamera.Position.X * scrollSpeed.X, -(parent as Scene).currentCamera.Position.Y * scrollSpeed.Y, 0) *
                    Matrix.CreateRotationZ((parent as Scene).currentCamera.Rotation) *
                    Matrix.CreateScale((parent as Scene).currentCamera.Scale) *
                    Matrix.CreateTranslation((parent as Scene).currentCamera.Origin.X, (parent as Scene).currentCamera.Origin.Y, 0);

        }

        public override void Update()
        {
            updateTransform();
            base.Update();
        }

        public override void Draw()
        {

            Engine.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, this.Transform);
            base.Draw();
            Engine.spriteBatch.End();
        }

 

Something like this. This code is from my Layer class, and parent is Level object.

Feb 16, 2011 at 1:42 PM

Thank you, i understand everything but the "parent as Scene" I'm taking it it something todo with Layers? I'm taking its a Custom method before hand.

Feb 16, 2011 at 7:34 PM

parent is reference to Level object which contains references to all layers and main camera...

Feb 17, 2011 at 11:28 AM

sorry i'm new to this and still picking up bits but i thought to call Layers its


foreach (Layer layer in Layers)

i had parrellex scrolling working in my own engine and i did it by

finding the Layers position and timing it by its scroller speed however i cant seem to find layers position?

Sorry, i know it must seem to are talking my directly thought what todo, but this is the last thing i have todo and i just want todo it instead of searching ages or waiting for the pin to dropp in my slow head.

Thank you for getting back to me

Feb 17, 2011 at 7:45 PM

Why do you need layer's position?
One camera position is enough for all layers,,,

Apr 1, 2011 at 8:46 PM
Edited Apr 1, 2011 at 9:49 PM

I'm in deep deep trouble with parallax. Although it seems easy to do, i still cannot get it.

I took the origin in a literal meaning, so i set it in the upper-left corner.

+-----------

|  the screen

|____________

 

Now scrollSpeed 1:1 works perfectly, but not the other layers: even without scrolling enabled, they are drawn on wrong coordinates, a matter of float points but that's:

On gleed:

http://i55.tinypic.com/4rb1a9.png

(this is how i understood to build the level):

http://i56.tinypic.com/207suox.png

BUT in game...

http://i52.tinypic.com/23ih3dx.png

OH Noes !! Look at the columns....

layers that are back to 1:1 are drawn shifted to left, layers that are in front of 1:1 are drawn shifted to right.

So i really can't get what's going on... And obviously, when i scroll the level, parallax works really bad, showing textures boundaries. Speeds are Ok, layers are scrolling respecting their speeds, but with that drawing issue the result is a mess.

 

Now this is the code for moving the MAIN camera:

 #if ZUNE
                const float ViewMargin = 0.45f;
            #else
                const float ViewMarginX = 0.5f;
                const float ViewMarginY = 0.35f;
            #endif

            // Calculate the edges of the screen.
            float marginWidth = viewport.Width*ViewMarginX;
            float marginLeft = cameraPosition.X + marginWidth;
            float marginRight = cameraPosition.X + viewport.Width - marginWidth;

            float marginHeight = viewport.Height* ViewMarginY;
            float marginTop = cameraPosition.Y + marginHeight;
            float marginBottom = cameraPosition.Y + viewport.Height - marginHeight;

            // Calculate how far to scroll when the player is near the edges of the screen.
            float cameraMovementX = 0.0f;
            float cameraMovementY = 0.0f;

            // Update the camera position, but prevent scrolling off the ends of the level.
            //tenere conto della posizione di inizio nella mappa del livello per calcolare i bordi
            float maxCameraPositionX = 22000; //viewport.Width*6;
            float maxCameraPositionY = viewport.Height * 2;
            

            if (kandar.Position.X < marginLeft)
                cameraMovementX = kandar.Position.X - marginLeft;
            else if (kandar.Position.X > marginRight)
                cameraMovementX = kandar.Position.X - marginRight;
            else if (kandar.Position.Y < marginTop)
                cameraMovementY = kandar.Position.Y - marginTop;
            else if (kandar.Position.Y > marginBottom)
                cameraMovementY = kandar.Position.Y - marginBottom;
            

            cameraPosition.X = MathHelper.Clamp(cameraPosition.X + cameraMovementX, 0, maxCameraPositionX);
            cameraPosition.Y = MathHelper.Clamp(cameraPosition.Y + cameraMovementY, -2000f, maxCameraPositionY);

 

And it's pratically took from the platformer kit example... "kandar" is the player character, of course...

 

 In the level class, i use in the partial Layer class Update method

//don't need to rotate or scale by now...
Transform = Matrix.Identity
     * Matrix.CreateTranslation(-cameraPosition.X * this.ScrollSpeed.X, -cameraPosition.Y * this.ScrollSpeed.Y, 0);
 
And in Draw method:
 
sb.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, DepthStencilState.None, null, null, Transform);
(foreach item ....)
spriteBatch.Draw(texture, Position, source, TintColor, Rotation, Origin, Scale, effects, 0);
So... what's going on? Perhaps i missed some translation on the camera origin? But WHAT'S the camera origin? I still mean the upper left corner and i don't think that's the middlepoint of width and height....
Can u help me please? :( I'm so worried about that ... ^__^ Thank you!

Apr 2, 2011 at 12:33 AM
Edited Apr 2, 2011 at 12:42 AM

More hints:

This is the layer 1:1, world origin set by mouse is (0,0)

http://i56.tinypic.com/2whkx1w.png

This is the front layer, colum coordinates sets to 960, 320

http://i51.tinypic.com/2edrxis.png

BUT!! When i go back on 1:1 level and check the same point, mouse pointer says about 900, 320!!

http://i56.tinypic.com/29eg6py.png

So i think that importing textures i'm taking the coordinates of the texture in his own layer (960, 320) but i must set them to a 1:1 layer view (900, 320) or something like this... i must recall the real 100% 1:1 real view of gleed2d and i'm really confused because it's not a matter of scrolling but drawing. As i said, i got things on layer back shifted on the left and things in front shifted on the right because of this points issue... But i'm drawing just using the embedded level.cs draw function.... What i'm missing?

Apr 2, 2011 at 1:46 PM
Edited Apr 2, 2011 at 2:49 PM

I'm still investigating and the problem seems definitely a draw/layerspeed issue: it draws every layer keeping the 1:1 reference for each of it, not calculating the translation factor!

So if i have texure on 950,500 on layer speed 1.1:1, it draws at 950,500 in a 1:1 speed view reference, instead of a 1.1:1 reference (what should be the computation? if the main cameraPosition is 0,0, it starts drawing ALL in a 1:1 view, missing the right perspective).... It draws every layer at 1:1, ignoring his speed/perspective factor... :(

So if i use

 Transform = Matrix.Identity
                                  * Matrix.CreateTranslation(-cameraPosition.X * ScrollSpeed.X,
                                     -cameraPosition.Y * ScrollSpeed.Y, 0)
                                  * Matrix.CreateTranslation(-640 * ScrollSpeed.X, 0, 0)
                                  * Matrix.CreateTranslation(640, 0, 0);

It FINALLY WORKS on X-axis...   640 is to get 1280 (my viewport x) / 2 ... so it's a matter of camera origin??

 

Please please help me understanding this issue... :(