Создайте экземпляр DrawableGameComponent позже в игре в XNA

Я долгое время боролся со своим умом.

I have my main Game Class called Game1 and a DrawableGameComponent-inherited ShowUp Class called myShowUp

Обычным способом было бы добавить компонент myShowUp в объект Game1 , чтобы он был частью игры (непосредственно в методе Initialize Game1 ) следующим образом :

class Game1 : Microsoft.Xna.Framework.Game
{
    ShowUp myShowUp;

    ...

    protected override Initialize ()
    {
        this.myShowUp = new ShowUp(this);
        this.Components.Add(this.myShowUp);
    }
    ...
}

Этот метод работает, и myShowUp отображается и становится независимым объектом в игре.

Я бы хотел, чтобы позже активировать и добавить объект в список игровых объектов (например, после щелчка в окне)

Это моя попытка:

class Game1 : Microsoft.Xna.Framework.Game
{
    MouseState myMouseState;

    ...

    ...

    protected override void Update(GameTime gameTime)
    {
        myMouseState = Mouse.GetState();

        if (myMouseState.LeftButton == ButtonState.Pressed)
        {
            this.myShowUp = new ShowUp(this);  //Nothing
            this.Components.Add(this.myShowUp);//Happens..
        }

        base.Update(gameTime);
    }

    ...
}

Я нашел метод до сих пор, я просто сохраняю первый синтаксис (т. Е. Сохраняю instanciation в методе Initialize) и определяю логическое значение в классе ShowUp с именем активировано . Если активировано истинно, я выполняю инструкции, чтобы показать его, или ничего. И в моем методе обновления моего объекта Game я вызываю активировать() из myShowUp , если моя левая кнопка нажата, чтобы изменить активированную в значение true.

Этот метод работает, но я не совсем удовлетворен, я бы хотел, чтобы это было просто так, чтобы просто создавать объекты в объекте Game в любом месте кода, чтобы сделать их частью этого. Есть ли способ сделать так?

Что-то вроде :

class Game1 : Microsoft.Xna.Framework.Game
{
    ShowUp myShowUp;
    MouseState myMouseState;

    ...

    ...

    protected override Initialize ()
    {
        this.Components.Add(this.myShowUp);
    }

    ...

    protected override void Update(GameTime gameTime)
    {
        myMouseState = Mouse.GetState();

        if (myMouseState.LeftButton == ButtonState.Pressed)
        {
            this.myShowUp = new ShowUp(this);
        }

        base.Update(gameTime);
    }

    ...
}

Это было бы хорошо.

0
nl ja de
@Charleh В моем Draw методе Game1 у меня нет ничего, что действительно добавляет компонент this.myShowUp к игре (т. Е. This.Components.Add (this.myShowUp )) позволяет переопределить метод Draw в DrawableGameComponent (как сделать новый поток для рисования в глобальном холсте)
добавлено автор vdegenne, источник
Глядя на документы, нигде не говорится, что вы не можете делать то, что хотите - не говорите, что вам нужно добавить компонент во время метода Initialise в Game . Я замечаю, что вы назначаете this.myShowUp - есть ли причина, по которой вы назначаете ее члену вашего подкласса Game ? Можете ли вы опубликовать код Draw для своего класса Game1 и кода для класса ShowUp , поскольку у меня есть идея, что может быть проблемой
добавлено автор Charleh, источник
Как насчет ShowUp - как он знает, что рисовать? Рисует ли DrawableGameComponent заполнитель, если вы не переопределяете метод Draw ? Вы переопределили DrawableGameComponent.Draw ? Я не коснулся XNA какое-то время - могу ли вы опубликовать код ShowUp ?
добавлено автор Charleh, источник

1 ответы

В вашем коде есть одна незначительная ошибка. Вы будете создавать несколько экземпляров вашего компонента - по одному на обновление. Это связано с тем, что вы не проверяете, что состояние мыши previous Released или что myShowUp равно null, перед созданием компонента. Вот некоторые проверенные рабочие коды (которые проверяют оба условия):

MouseState lastMouseState;

protected override void Update(GameTime gameTime)
{
    MouseState mouseState = Mouse.GetState();

    if(mouseState.LeftButton == ButtonState.Pressed
            && lastMouseState.LeftButton == ButtonState.Released
            && myShowUp == null)
    {
        Components.Add(myShowUp = new ShowUp(this));
    }

    lastMouseState = mouseState;

    base.Update(gameTime);
}

Конечно, я не уверен, почему эта ошибка не приведет к тому, что ShowUp не появится вообще - поскольку вы создаете несколько экземпляров этого файла - вы ожидаете увидеть его. Может быть ошибка в вашем компоненте ShowUp .

Для чего это стоит, вот код, который я тестировал:

class ShowUp : DrawableGameComponent
{
    public ShowUp(Game game) : base(game) { }

    Texture2D texture;
    SpriteBatch sb;

    protected override void LoadContent()
    {
        sb = new SpriteBatch(GraphicsDevice);
        texture = this.Game.Content.Load("test");
        base.LoadContent();
    }

    public override void Draw(GameTime gameTime)
    {
        sb.Begin();
        sb.Draw(texture, new Vector2(100), Color.White);
        sb.End();
        base.Draw(gameTime);
    }
}

Обратите внимание, что добавление компонента после Game.Initialize запускает вызовы методов Initialize и LoadContent этого компонента < как только он будет добавлен в коллекцию Components .

Обратите внимание, что для вашей будущей ссылки DrawableGameComponent уже есть свойства Enabled и Visible ), что позволяет пропустить Update и Draw соответственно для этого экземпляра.

1
добавлено
Работает ли это для вас ? Я даже придерживаюсь той же структуры вашей кодировки, но все равно ничего не происходит, вот пастихины моего кода.
добавлено автор vdegenne, источник
добавлено автор vdegenne, источник
добавлено автор vdegenne, источник
После нескольких минут попытки я понял, где проблема, есть небольшая ошибка в вашем фрагменте, я изменил myShowUp! = Null на myShowUp == null в условном структура Game.Update и, наконец, работает, спасибо за ваше лидерство (измените свой код, и я подтвержу ваш ответ)
добавлено автор vdegenne, источник
О, крики! Мой плохой - извините - подумал, что я бы проиллюстрировал обе проверки в последнюю минуту и ​​представил ошибку! Рад, что вы его отсортировали :)
добавлено автор Andrew Russell, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot