XNA Удерживайте и нажмите на тот же объект - PullRequest
0 голосов
/ 11 февраля 2012

Если у одного и того же объекта в игре есть два разных действия: щелкнуть по нему и удерживать нажатой кнопку мыши над ним, используя ввод по умолчанию (текущий и последний MouseState), вы активируете действие щелчка даже при удерживании,Например, вы используете удержание, чтобы перетащить объект на экран, но когда вы щелкнете по нему, он должен исчезнуть.В тот момент, когда вы просто нажимаете на объект, чтобы переместить его, он исчезнет, ​​что является нежелательным результатом.

MouseState current, last;

public void Update(GameTime gameTime) {
   current = Mouse.GetState();

   bool clicked = current.LeftButton == ButtonState.Pressed && last.LeftButton == ButtonState.Released;
   bool holding = current.LeftButton == ButtonState.Pressed;

   if(clicked) vanishObject();
   if(holding) moveObject(current.X, current.Y);

   last = current;
}

Я подумал, чтобы решить его, используя флаг «удерживается более N секунд» иустановите значение исчезновения на ReleasedClick, отметив флаг, но изменение времени события не кажется элегантным решением.Есть идеи?

Ответы [ 3 ]

0 голосов
/ 11 февраля 2012

Вы думаете о том, что нажали не тот путь. Самый простой способ реализовать это поведение - запускать действие Clicked только в том случае, если mouseState был нажат на последний кадр и выпустил этот кадр, и если определенное время не было достигнуто. В коде:

private const float HOLD_TIMESPAN = .5f; //must hold down mouse for 1/2 sec to activate hold
MouseState current, last;
private float holdTimer;

public virtual void Update(GameTime gameTime)
{
    bool isHeld, isClicked; //start off with some flags, both false
    last = current; //store previous frame's mouse state
    current = Mouse.GetState(); //store this frame's mouse state
    if (current.LeftButton == ButtonState.Pressed)
    {
        holdTimer += (float)gameTime.ElapsedTime.TotalSeconds();
    }
    if (holdTimer > HOLD_TIMESPAN)
        isHeld = true;
    if (current.LeftButton == ButtonState.Released)
    {
        if (isHeld) //if we're releasing a held button
        {
            holdTimer = 0f; //reset the hold timer
            isHeld = false;
            OnHoldRelease(); //do anything you need to do when a held button is released
        }
        else if (last.LeftButton == ButtonState.Pressed) //if NOT held (i.e. we have not elapsed enough time for it to be a held button) and just released this frame
        {
            //this is a click
            isClicked = true;
        }
     }
     if (isClicked) VanishObject();
     else if (isHeld) MoveObject(current.X, current.Y);
 }

Конечно, есть место для некоторой оптимизации этого кода, но я думаю, что он достаточно разумный.

0 голосов
/ 11 февраля 2012
   const float DragTimeLapsus = 0.2f;

   if (current.LeftButton == ButtonState.Released) time = 0;
   else time+= ElapsedSeconds;

   bool clicked = current.LeftButton == ButtonState.Released
               && last.LeftButton == ButtonState.Pressed 
               && time<DragTimeLapsus;
   bool holding = current.LeftButton == ButtonState.Pressed 
               && last.LeftButton == ButtonState.Pressed 
               && time>DragTimeLapsus ;
0 голосов
/ 11 февраля 2012

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

if (clicked && !holding) vanishObject();

Это должен быть самый простой способ получить то, что вы хотите.

...