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

C# .NET .NET (C# a Visual Basic) XNA - komponentka nereaguje na přepsání update American English version English version

Avatar
matesax
Redaktor
Avatar
matesax:

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
Redaktor
Avatar
matesax:

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

Components.Add(mi);
 
Nahoru Odpovědět 24.10.2012 6:14
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na matesax
David Čápka:

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

Nahoru Odpovědět 24.10.2012 9:17
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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
Redaktor
Avatar
matesax:

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 Čápka
Tým ITnetwork
Avatar
Odpovídá na matesax
David Čápka:

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

Nahoru Odpovědět 25.10.2012 12:22
Miluji svou práci a zdejší komunitu, baví mě se rozvíjet, děkuji každému členovi za to, že zde působí.
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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

decimal difference = 1 / (Bounds.Height / (decimal)notch);
 
Nahoru Odpovědět 25.10.2012 15:52
Avatar
matesax
Redaktor
Avatar
Odpovídá na David Čápka
matesax:

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.