Как идентифицировать щелчки мыши по сравнению с мышью вниз в играх?


8

Какой самый распространенный способ обработки щелчков мыши в играх?

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

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

Но как лучше всего справиться с кликом? Это щелчок, когда мышь перемещается от мыши вверх-вниз или вниз-вверх, или это щелчок, если кнопка была нажата менее чем на x кадров / миллисекунд, а затем, если да, считается ли она мышью нажатой, а щелчок - если она нажата для х кадров / миллисекунд или щелчок мышью вниз?

Я вижу, что у каждого из подходов могут быть свои применения, но какой из них наиболее распространен в играх? А может быть, я спрошу более конкретно, что является наиболее распространенным в играх RTS?


1
Вы на правильном пути. Добавьте кое-что о том, что мышь вниз и мышь вверх должны быть расположены близко друг к другу (или внутри границ объекта, по которому щелкнули), и вы получили это. Нажатие на кнопку, затем перетаскивание и отпускание кнопки - это не щелчок мышью. Но нажатие на кнопку и отпускание ее в любом месте - это щелчок мышью.
Тим Холт

Ответы:


12

Вы на правильном пути, когда будете выяснять, когда мышь переходит с вершины вниз, и пишете обработчик для этого. Для многих игр достаточно хорошо рассматривать событие mouseUp как щелчок.

В зависимости от вашей игры, вы, вероятно, захотите обрабатывать оба события - например, в RTS, вы, вероятно, захотите включить выбор перетаскивания, а также выбор одним щелчком мыши. Разница заключается в том, как долго мышь находилась в состоянии «Вниз» до ее отпускания.

(Да, вы в основном ответили на свой вопрос)


2
Как отмечали другие комментаторы, вы, вероятно, также захотите проверить, указывали ли на ту же цель на mouseDown и mouseUp при работе с одиночными щелчками.
Билл

Я не совсем уверен. Например, кнопкам Windows не важно, где была указатель мыши, если кнопка получает событие «вверх». Может быть, другие операционные системы заботятся больше.
Джон Макдональд

@Джон МакДэй Это не столько техническое требование, сколько «выяснение того, что ваш пользователь действительно хотел нажать».
Билл

1
@ Джон Макд. это не правда. Нажмите кнопку мыши где-нибудь на рабочем столе, переместите курсор в меню «Пуск» и отпустите. Появляется ли меню «Пуск»? Это не для меня.
Килотан

@Kylotan, вы были бы правы, хотя «кнопка» в меню «Пуск» ведет себя иначе, чем все остальные стандартные кнопки. Похоже, стандартные кнопки в окнах на самом деле требуют как мыши, так и мыши вверх события, хотя ваша мышь может перемещаться за пределы кнопки между ними. Свернуть, Развернуть и Закрыть все работают так же, как и обычные кнопки внутри приложений. Но учтите, что до тех пор, пока кнопка мыши не будет отпущена, никаких действий не происходит (кроме как с помощью кнопки «Пуск»), люди, подобные мне, заметят. Annyway ... Билл прав, это сводится к требованиям.
Джон Макдональд

4

Нет «лучшего» - вам нужны все из них.

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

С другой стороны, если я нажимаю на элемент графического интерфейса, то я хочу дождаться полного щелчка, потому что это то, к чему я привык.

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


1

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

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

Это основная схема большинства кнопок. Идите вперед и найдите диалоговое окно. Нажмите на кнопку отмены, но не отпускайте. Кнопка становится нажатой, когда мышь находится над ней, и возвращается в нормальное состояние, если ваша мышь перестает зависать над ней, но она вернется к нажатой, если вы вернетесь к ней. Он запускает свое действие, только если вы отпустите, и вы над ним. Не используйте счет в миллисекундах, это в основном только для обнаружения двойных кликов в пределах вашего порога.

(и если вы действительно хотите получить фантазию, есть события, которые вы можете подключить к каждому из этих переходов. Например, MouseOver при входе и при выходе, MouseDown вход / выход, MouseUp вход / выход, MouseClicked вход / выход и т. д. )


1

Кнопки мыши и клавиши клавиатуры могут иметь несколько различных событий, которые зависят от выбранного вами языка / библиотеки, наиболее распространенные:

Клавиша вниз, срабатывает при нажатии кнопки.
Ключ, запускается при отпускании кнопки.
Клавиша запаздывает, запускается при нажатии кнопки, а затем многократно срабатывает с некоторым системным интервалом, пока клавиша не будет отпущена.

Вдобавок к этому может также быть звонок, чтобы сказать, нажата ли клавиша в настоящее время или нет.

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

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


0

XOr может быть вашим другом в этой ситуации.

bool oldIsButtonUp = true;

void pollMouse(bool isButtonUp) {
    if ((oldIsButtonUp ^ isButtonUp) && isButtonUp) {
        sendMouseClickEvent();
    }
    oldIsButtonUp = isButtonUp;
}

Это вызовет sendMouseClickEvent () всякий раз, когда состояние кнопки мыши изменяется с false на true.


4
Или, чтобы не сделать программисту создать truthtable в его (ее?) Голову: if (!oldIsButtonUp && isButtonUp) {.
замедленная

-1

Версия этого кода для 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 begins if the button 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); 
} 

Помимо этого, это код для MouseUp, а не MouseClick. Как часто выполняется обновление? Что произойдет, если клик короче, чем тик игрового времени?
Кромстер

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

На самом деле, это код для обнаружения события нажатия мыши.
Кен

Я не вижу фактического ответа на реальный вопрос в этом абстрактном примере кода XNA
Kromster

Спасибо за исправления, хотя я провел небольшой тест, и клик действительно занимает 16-100 мс, что немного больше, чем длина обновления. Тем не менее, я бы не рекомендовал обрабатывать входные данные в цикле обновления, поскольку временной интервал может составлять менее 60 кадров в секунду, особенно без ввода в очередь.
Кромстер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.