Как обрабатывать ввод мыши в XNA?

13

Я занимаюсь разработкой карточной игры в XNA.

Есть ли OnClickв XNA событие для объектов?

Я пытаюсь заставить карты двигаться, когда игрок нажимает на них. В этом проекте есть класс Sprite, который тянет карту, но я немного застрял, потому что я не знаю, как использовать OnClickсобытия или что-то подобное.

Луис
источник

Ответы:

12

При работе с XNA в целом вы должны перейти от парадигмы кода, управляемого событиями, к парадигме кода, управляемого циклом. Ваш код обновления зацикливается 60 раз / сек. Поэтому каждый раз смотрите на состояние мыши, и если кнопка нажата, а указатель находится внутри вашего прямоугольника, переходите к коду, который вы обычно помещаете в событие OnClick.

Стив Н
источник
2
Кажется, что это может быть семантически правильно, но, на мой взгляд, неправильно. Нет никаких событий, когда вы начинаете смотреть на поток и каково текущее состояние в каждом цикле. Вот почему мы создаем наши собственные события и пишем соответствующие им обработчики. Я бы сказал, что использование управления потоком для перехода к каждому нажатию кнопки мыши может привести к сумасшествию в большом проекте. Вместо этого зарегистрируйте событие и напишите обработчики, где это необходимо. По этой причине события были придуманы в первую очередь.
Брэндон
5
Брэндон: Вы не «используете управление потоком для перехода к каждому нажатию кнопки мыши». Вы записываете текущее и предыдущее состояние мыши один раз в начале каждого кадра, а затем в каждом месте, где ваш код реагирует на нажатие mousedown, которое вы просто делаете if(MouseLeftPress()){ DoSomething(); }, MouseLeftPress()- это метод, который вы пишете для сравнения текущего и предыдущего состояния левой кнопки мыши. Я нахожу это проще, чем реализовывать события большую часть времени.
Ольховский
4
Простой опрос становится действительно уродливым за ваши основные элементы управления аркады. У меня есть класс диспетчера ввода, который фиксирует состояние геймпада как FlagAttributes и позволяет отображать делегатов на различные комбинации кнопок. Следующим шагом является внедрение времени. Все эти дебаты только подтверждают точку зрения Стива Х. Вы даете систему голосования и можете свободно использовать ее для поддержки любой парадигмы, которую вы предпочитаете.
michael.bartnett
6

XNA дает вам только достаточно для создания ваших собственных входных классов - и вы должны делать это, учитывая полезность, которую они предлагают.

Я бы порекомендовал класс ввода мыши, описанный в этом сообщении в блоге ( исходный код ). Он обнаруживает нажатие, удержание или отпускание кнопки и позволяет получить эту информацию с помощью опроса или событий.

В той же заметке в блоге также представлены классы устройств ввода клавиатуры и геймпада.

doppelgreener
источник
3

Фактический код для проверки щелчка мышью в XNA выглядит примерно так;

    MouseState previousMouseState;
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        //store the current state of the mouse
        previousMouseState = Mouse.GetState();
    }


    protected override void Update(GameTime gameTime)
    {
        // .. other update code


        //is there a mouse click?
        //A mouse click occurs if the goes from a released state
        //in the previous frame  to a pressed state 
        //in the current frame
        if (previousMouseState.LeftButton == ButtonState.Released 
            && Mouse.GetState().LeftButton == ButtonState.Pressed)
        {
            //do your mouse click response...

        }

        //save the current mouse state for the next frame
        // the current 
        previousMouseState = Mouse.GetState();

        base.Update(gameTime);
    }
кругозор
источник
2

Если ваша игра 3D, вы можете реализовать сбор, который описан здесь: http://create.msdn.com/en-US/education/catalog/sample/picking_triangle . По сути, это создает луч от камеры до места, где щелкает мышь (с небольшой матрицей, не выступающей там), затем вы проверяете, не пересекался ли какой-либо из ваших объектов с лучом.

Если ваша игра 2D, вы сможете довольно легко перевести координаты окна в игровые координаты. Затем проверьте, находятся ли выбранные координаты в пределах какого-либо из ваших объектов.

MichaelHouse
источник
1

Самый простой способ узнать, нажата ли мышь, это

//Create this variable
MouseState mouseState;

Теперь в методе обновления добавить это

mouseState = Mouse.GetState();

if (mouse.RightButton == ButtonState.Pressed)
{
     //Do Stuff
}

надеюсь, это помогло

Battle_Pasture
источник