Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze: XNA - komponentka nereaguje na přepsání update

Aktivity
Avatar
matesax
Tvůrce
Avatar
matesax:23.10.2012 19:16

Dobrý den,
kromě toho, že mi to nebere "override void Update" to asi ani nebere input... (Alespoň ne myš.)

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

public struct MouseEventArgs
{
    public Vector2 Position { get; set; }
}

public class MenuItem : GameComponent
{
    public string Name { get; set; }
    public string Text { get; set; }

    public delegate void ClickHandler(object sender, MouseEventArgs me);
    public event ClickHandler Click;

    public MenuItem(Game game) : base(game)
    {

    }

    public override void Update(GameTime gameTime)
    {
        if (Mouse.GetState().LeftButton == ButtonState.Pressed)
            Click(this, new MouseEventArgs());

        base.Update(gameTime);
    }
}

Použití:

mi = new MenuItem(this);
mi.Click += new MenuItem.ClickHandler(ButtonClick);
Editováno 23.10.2012 19:16
 
Odpovědět
23.10.2012 19:16
Avatar
matesax
Tvůrce
Avatar
matesax:24.10.2012 6:14

Heej - tak takovou kravinu jste mi mohli napsat rovnou... :)

Components.Add(mi);
 
Nahoru Odpovědět
24.10.2012 6:14
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:24.10.2012 9:17

Máš to v tutoriálech :P Ještě existuje DrawableGameCom­ponent.

Nahoru Odpovědět
24.10.2012 9:17
You are the greatest project you will ever work on.
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:24.10.2012 11:05

Z něj právě dědím... :) (Změnil jsem to...) Rovnou se zeptám - je to dobrý návrh?:

Komponentka GameMenu. Třída MenuItemCollection. Komponentka MenuItem. MenuItem se nezávisle na ničem rovnou vykresluje - potřebuje k tomu pochopitelně parametr Game. A zároveň vytváří známé eventy - click, hover... Má border, text, name,... A teď - odkud bych měl čerpat MenuItemCollection? (Aktuálně CollectionBase) Zatím tedy GameMenu nemá valné využití - ale asi nakonec potřeba bude. Na jednu stranu jsem se vyhnul cyklům - ale zase si hodně předávám parametr Game...

 
Nahoru Odpovědět
24.10.2012 11:05
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:24.10.2012 17:03

Jo a tak přemýšlím:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace GameMenu
{
    public struct MouseEventArgs
    {
        public MouseState MouseState { get; set; }
    }

    public class MenuItem : DrawableGameComponent
    {
        private Texture2D itemTexture;
        private SpriteBatch spriteBatch;
        private SpriteFont spriteFont;

        public string Name { get; set; }
        public string Text { get; set; }

        public Rectangle Bounds { get; set; }

        public Color BackgroundColor { get; set; }
        public Color BorderColor { get; set; }
        public Color ForeColor { get; set; }

        public int BorderWidth { get; set; }

        public delegate void ClickHandler(object sender, MouseEventArgs me);
        public event ClickHandler Click;

        public delegate void MouseHoverHandler(object sender, MouseEventArgs me);
        public event MouseHoverHandler MouseHover;

        public MenuItem(Game game, SpriteFont spriteFont) : base(game)
        {
            game.Components.Add(this);

            BorderWidth = 2;
            BorderColor = Color.RoyalBlue;
            BackgroundColor = Color.CornflowerBlue;
            this.spriteFont = spriteFont;
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            itemTexture = new Texture2D(GraphicsDevice, Bounds.Width, Bounds.Height);
            SetTexture();
        }

        public override void Update(GameTime gameTime)
        {
            if (Bounds.Intersects(new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 5, 5)))
            {
                MouseHover(this, new MouseEventArgs() { MouseState = Mouse.GetState() });

                if (Mouse.GetState().LeftButton == ButtonState.Pressed)
                    Click(this, new MouseEventArgs() { MouseState = Mouse.GetState() });
            }

            base.Update(gameTime);
        }

        private void SetTexture()
        {
            Color[] colors = new Color[Bounds.Width * Bounds.Height];

            for (int x = 0; x < Bounds.Width; x++)
                for (int y = 0; y < Bounds.Height; y++)
                    colors[x + (Bounds.Width * y)] = x < BorderWidth || y < BorderWidth || x > Bounds.Width - 1 - BorderWidth || y > Bounds.Height - 1 - BorderWidth ? BorderColor : BackgroundColor;

            itemTexture.SetData<Color>(colors);
        }

        public override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(itemTexture, Bounds, BackgroundColor);

            spriteBatch.DrawString(spriteFont, Text, new Vector2(Bounds.X, Bounds.Y), ForeColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

Neměly by být ty eventy někde mimo? Přijde mi blbost je pokaždé vytvářet...

 
Nahoru Odpovědět
24.10.2012 17:03
Avatar
matesax
Tvůrce
Avatar
matesax:25.10.2012 11:51

Nešlo by to zkrátit?

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace GameMenu
{
    public struct MouseEventArgs
    {
        public MouseState MouseState { get; set; }
    }

    public class MenuItem : DrawableGameComponent
    {
        private Game mum;
        private Texture2D itemTexture;
        private SpriteBatch spriteBatch;
        private SpriteFont spriteFont;
        private string spriteFontFile;

        public string Name { get; set; }
        public string Text { get; set; }

        public Rectangle Bounds { get; set; }

        public Color BackgroundColor { get; set; }
        public Color BorderColor { get; set; }
        public Color ForeColor { get; set; }

        public int BorderWidth { get; set; }

        public Texture2D Image { get; set; }

        public delegate void ClickHandler(object sender, MouseEventArgs me);
        public event ClickHandler Click;

        public delegate void MouseHoverHandler(object sender, MouseEventArgs me);
        public event MouseHoverHandler MouseHover;

        public MenuItem(Game game, string spriteFontFile) : base(game)
        {
            Text = "Konec";
            BorderWidth = 2;
            game.Components.Add(this);
            ForeColor = Color.AliceBlue;
            BorderColor = Color.RoyalBlue;
            BackgroundColor = Color.CornflowerBlue;
            this.spriteFontFile = spriteFontFile;
            mum = game;
        }

        private struct HSV
        {
            public decimal Hue { get; set; }
            public decimal Saturation { get; set; }
            public decimal Value { get; set; }
        }

        private HSV ToHSV(Color rgb)
        {
            decimal
                r = (decimal)rgb.R / 255m,
                g = (decimal)rgb.G / 255m,
                b = (decimal)rgb.B / 255m,
                minRGB = Math.Min(r, Math.Min(g, b)),
                maxRGB = Math.Max(r, Math.Max(g, b));

            if (minRGB == maxRGB)
                return new HSV() { Hue = 0, Saturation = 0, Value = minRGB };

            return new HSV() { Hue = 60 * ((r == minRGB ? 3 : b == minRGB ? 1 : 5) - (r == minRGB ? g - b : b == minRGB ? r - g : b - r) / (maxRGB - minRGB)), Saturation = (maxRGB - minRGB) / maxRGB, Value = maxRGB };
        }

        private Color ToRGB(HSV hsv)
        {
            decimal
                hi = Math.Floor(hsv.Hue / 60) % 6,
                f = hsv.Hue / 60 - Math.Floor(hsv.Hue / 60),
                p = hsv.Value * (1 - hsv.Saturation),
                q = hsv.Value * (1 - (f * hsv.Saturation)),
                t = hsv.Value * (1 - ((1 - f) * hsv.Saturation));

            decimal[] ret;

            switch ((int)hi)
            {
                case 0:
                    ret = new decimal[] { hsv.Value, t, p };
                    break;
                case 1:
                    ret = new decimal[] { q, hsv.Value, p };
                    break;
                case 2:
                    ret = new decimal[] { p, hsv.Value, t };
                    break;
                case 3:
                    ret = new decimal[] { p, q, hsv.Value };
                    break;
                case 4:
                    ret = new decimal[] { t, p, hsv.Value };
                    break;
                case 5:
                    ret = new decimal[] { hsv.Value, p, q };
                    break;
                default:
                    ret = new decimal[] { 0xFF, 0x00, 0x00, 0x00 };
                    break;
            }

            return new Color((int)(ret[0] * 255m), (int)(ret[1] * 255m), (int)(ret[2] * 255m));
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            spriteFont = mum.Content.Load<SpriteFont>(spriteFontFile);
            itemTexture = new Texture2D(GraphicsDevice, Bounds.Width, Bounds.Height);
            SetTexture();
        }

        public override void Update(GameTime gameTime)
        {
            if (Bounds.Intersects(new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 5, 5)))
            {
                if (MouseHover != null)
                    MouseHover(this, new MouseEventArgs() { MouseState = Mouse.GetState() });

                if (Mouse.GetState().LeftButton == ButtonState.Pressed && Click != null)
                    Click(this, new MouseEventArgs() { MouseState = Mouse.GetState() });
            }

            base.Update(gameTime);
        }

        private void SetTexture()
        {
            Color[] colors = new Color[Bounds.Width * Bounds.Height];

            for (int x = 0; x < Bounds.Width; x++)
                for (int y = 0; y < Bounds.Height; y++)
                    colors[x + (Bounds.Width * y)] = x < BorderWidth || y < BorderWidth || x > Bounds.Width - 1 - BorderWidth || y > Bounds.Height - 1 - BorderWidth ? BorderColor : BackgroundColor;

            itemTexture.SetData<Color>(colors);
        }

        public override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(itemTexture, Bounds, BackgroundColor);

            spriteBatch.DrawString(spriteFont, Text, new Vector2(Bounds.X, Bounds.Y) + ((new Vector2(Bounds.Width, Bounds.Height) - spriteFont.MeasureString(Text)) / 2), ForeColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

Převod barev tam je kvůli tomu, že tlačítka budou přechody - a snadno měnit světlost mohu právě v HSV... Hodně mě štvě, že jsem byl donucen si parametr Game dokonce ukládat - ale jak jinak na to jít?

Editováno 25.10.2012 11:54
 
Nahoru Odpovědět
25.10.2012 11:51
Avatar
David Hartinger
Vlastník
Avatar
Odpovídá na matesax
David Hartinger:25.10.2012 12:22

Ukládání Game je v pořádku, tak jsou komponenty navržené.

Nahoru Odpovědět
25.10.2012 12:22
You are the greatest project you will ever work on.
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:25.10.2012 12:24

Jo jasně - prostě mi jde o to mít to nejkratší a hlavně co nejméně náročné...

 
Nahoru Odpovědět
25.10.2012 12:24
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:25.10.2012 15:03

Nevíš, co je na tom špatně? :) :

int
    index = 0,
    notch = 100 / Bounds.Height;

decimal difference = 1 / ((decimal)notch / Bounds.Height);

for (decimal saturation = 0; saturation <= 1; saturation += difference)
{
    currentColor.Saturation = Math.Min(1, saturation);
    usedColor.Add(ToRGB(currentColor));
}

for (int y = 0; y < Bounds.Height; y++)
{
    for (int x = 0; x < Bounds.Width; x++)
        colors[x + (Bounds.Width * y)] = x < BorderWidth || y < BorderWidth || x > Bounds.Width - 1 - BorderWidth || y > Bounds.Height - 1 - BorderWidth ? BorderColor : usedColor[index];

    if (y % notch == 0)
        index++;
}

Nejprve si spočítám differenci - aby mi barva vystačila, ale ona mi nestačí - zkusil jsem si i dát rezervu...

 
Nahoru Odpovědět
25.10.2012 15:03
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:25.10.2012 15:52

Jé - já to prohodil... :)

decimal difference = 1 / (Bounds.Height / (decimal)notch);
 
Nahoru Odpovědět
25.10.2012 15:52
Avatar
matesax
Tvůrce
Avatar
Odpovídá na David Hartinger
matesax:25.10.2012 20:54

Game není třeba ukládat - je to vlastnost komponentky... :)

 
Nahoru Odpovědět
25.10.2012 20:54
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.