Foros - Stratos

Stratos => XNA => Mensaje iniciado por: jbosch en 16 de Abril de 2012, 06:02:30 PM

Título: crear un scroll "a pelo"
Publicado por: jbosch en 16 de Abril de 2012, 06:02:30 PM
Hola,

Estoy con un juego que necesita un scroll. Hacerlo de cero me parece una matada increible... sabéis de algun game component o similar?

No me vale un scroll "normal", debo poderle meter texturas, spritefonts o cualquier cosa dentro.

Gracias!
Título: Re: crear un scroll "a pelo"
Publicado por: [EX3] en 17 de Abril de 2012, 12:20:40 AM
Yo el "invento" que tengo implementado en mi motor de XNA y que ya usaba con dx_lib32 entonces es que todos los objetos gráficos del motor se pueden ver afectados o no por una coordenada de desplazamiento a modo de cámara que gestiona el propio render, esto es, cada vez que se dibuja un objeto, si este no esta configurado como fijo, se le suma la coordenada de desplazamiento a su coordenada de posición en el momento de renderizarse. De esta forma puedes implementar un scroll sencillo controlando dicha coordenada de desplazamiento (ajustándola por ejemplo a la posición del jugador).

Salu2...
Título: Re: Re: crear un scroll "a pelo"
Publicado por: josepzin en 17 de Abril de 2012, 02:29:42 PM
La forma que dice EX3 creo que es la mas simple.

Enviado desde mi HTC Magic usando Tapatalk 2
Título: Re: crear un scroll "a pelo"
Publicado por: jbosch en 17 de Abril de 2012, 03:42:54 PM
bueno, el scroll como tal ya lo tengo, la pregunta iba más bien enfocada a hacer la "barra" del scroll
Título: Re: crear un scroll "a pelo"
Publicado por: blau en 18 de Abril de 2012, 10:14:53 AM
Entiendo que quieres hacer una barra de scroll tipo gui.

Yo lo hice así para mi gui: http://www.youtube.com/watch?feature=player_detailpage&v=3pakgHjnScs#t=28s

Aunque no sea exactamente lo que busques, espero que te sirva...

Código (csharp) [Seleccionar]

public class GuiScrollPanel : GuiPanel
    {
        protected Rectangle ScrollFrame;

        public GuiScrollBar ScrollbarVertical { get; private set; }

        bool _VerticalScrollEnabled = false;

        public bool VerticalScrollEnabled
        {
            get { return _VerticalScrollEnabled; }
            private set
            {
                if (_VerticalScrollEnabled != value)
                {
                    if (_VerticalScrollEnabled)
                    {
                        Controls.Remove(ScrollbarVertical);
                        ScrollbarVertical.Offset = 0;
                    }

                    _VerticalScrollEnabled = value;

                    if (_VerticalScrollEnabled)
                    {
                        Controls.Add(ScrollbarVertical);
                        ScrollbarVertical.Offset = 0;
                    }
                }
            }
        }

       
        protected override void LocalSetup()
        {
            ScrollbarVertical = new GuiScrollBar();
            ScrollbarVertical.OnChangedPosition += Scrollbar_OnChanged;
            ScrollbarVertical.Styles.Normal.BackgroundColor = new Color(Styles.Normal.BackgroundColor.ToVector4() * 1.1f);
            ScrollbarVertical.BackgroundCursorColor = new Color(Styles.Normal.BackgroundColor.ToVector4() * 1.5f);
           
            ScrollbarVertical.Setup();
        }

        protected override void LocalDispose()
        {
            ScrollbarVertical.OnChangedPosition -= Scrollbar_OnChanged;
            ScrollbarVertical.Dispose();           
        }

        void Scrollbar_OnChanged()
        {
            LayoutDirty = true;
        }

        protected override void DoLayout()
        {
            base.DoLayout();

            ScrollFrame = ContentFrame;

            UpdateChildrenLayout();

            int height = 0;
            int Ymin, Ymax;

            Ymin = int.MaxValue;
            Ymax = int.MinValue;           

            foreach (Control child in Controls)  // Calcular la altura de los controles que contiene el Panel
            {
                if (child != ScrollbarVertical)
                {                   
                    if (Ymin > child.MarginFrame.Y) Ymin = child.MarginFrame.Y;
                    if (Ymax < child.MarginFrame.Y + child.MarginFrame.Height) Ymax = child.MarginFrame.Y + child.MarginFrame.Height;
                }               
            }

            height = Ymax - Ymin;

            if (ContentFrame.Height < height)
            {               
                if (!VerticalScrollEnabled)
                {
                    VerticalScrollEnabled = true;
                    ScrollbarVertical.Offset = 0;
                    LayoutDirty = true;                   
                }
               
                ScrollbarVertical.LengthReal = height;
                ScrollbarVertical.LengthVisible = ContentFrame.Height;               
            }
            else
            {
                VerticalScrollEnabled = false;
            }

            ScrollFrame = ContentFrame;
            ScrollFrame.Offset(0, -ScrollbarVertical.Offset);
           
            if (VerticalScrollEnabled)
            {               
                ScrollbarVertical.UpdateLayout(_ContentFrame);
            }     
        }

        protected override void UpdateChildrenLayout()    {        }       
    }



Código (csharp) [Seleccionar]

   public class GuiScrollBar : Control
    {
        int _Real, _Visible, _Hidden;

        public int LengthReal { get { return _Real; } set { _Real = value; CheckOffset(); } }
        public int LengthVisible { get { return _Visible; } set { _Visible = value; CheckOffset(); } }

        public Color BackgroundCursorColor = Color.Orange;

        int _Offset;

        public int Offset
        {
            get { return _Offset; }
            set
            {
                if (_Offset != value)
                {
                    if ( value < 0) _Offset = 0;
                    else if ( value > _Hidden) _Offset = _Hidden;
                    else _Offset = value;
                    if (OnChangedPosition != null) OnChangedPosition();
                }
            }
        }

        void CheckOffset()
        {
            _Hidden = (_Real - _Visible);
            if (_Offset > _Hidden) Offset = _Hidden;                   
        }

        public event Action OnChangedPosition;

        public GuiScrollBar()
        {
            _Size.Width = 16; _Size.Height = 16;
            Styles.Normal.BackgroundColor = Color.DarkSlateBlue;           
        }

        public void Move(int offset)
        {
            Offset += offset;           
        }

        public void MovePage(int direction)
        {
            Move(direction * Size.Height);
        }

        protected override void DoLayout()
        {
            Align = Alignment.Right;
            _Size.Height = _ParentFrame.Height;
            base.DoLayout();
        }

        public override void Render(ref Microsoft.Xna.Framework.Rectangle ParentFrame)
        {
            base.Render(ref ParentFrame);

            int cursor_size = LengthVisible * LengthVisible / LengthReal;

            int cursor_offset = ((Size.Height - cursor_size) * this.Offset) / _Hidden;
           
            Rectangle dest = new Rectangle(ContentFrame.Left, (int) (ContentFrame.Top + cursor_offset), 16, cursor_size );

            Vector2 Origin = new Vector2(0, 0);
           
            GuiManager.Batch.Begin( SpriteSortMode.Immediate,BlendState.AlphaBlend);

            GuiManager.Batch.Draw(GuiManager.Sheet.Texture, dest, GuiManager.Sheet.SourceRectangle("white_1x1"), BackgroundCursorColor, 0, Origin, SpriteEffects.None, 1);

            GuiManager.Batch.End();
        }
       
        protected override void LocalDispose()
        {
            OnChangedPosition = null;           
        }

        protected override void LocalSetup()  { }
    }