2011-01-20 4 views
0

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

public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) 
    { 
     float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; 

     //Some math to change 'matrixOffsetY' 
     //I use 'matrixOffsetY' to offset my objects in Draw() 

     base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen); 
    } 

Вот это событие жест

public override void HandleInput(InputState input) 
    { 
     if (input == null) 
      throw new ArgumentNullException("input"); 

     while (TouchPanel.IsGestureAvailable) 
     { 
      GestureSample gesture = TouchPanel.ReadGesture(); 

      switch (gesture.GestureType) 
      { 
       case GestureType.Flick: 
        { 
         //Set a variable with some math? Using: 
         //gesture.Delta 

         //gesture.Delta gives us pixels/sec 
         break; 
        } 
       default: return; 
      } 
     } 
    } 

Это не должно быть трудно, но у меня есть мозг-Фриз :) Пожалуйста, помогите мне!

ответ

3

Вы можете «lerp» (линейная интерполяция) между двумя значениями постепенно приближаться (начинать быстро, заканчивая медленно).

Предполагаю, что вы прокручиваете 2D. Таким образом, позиция представляет собой вектор2.

Попробуйте что-то вроде этого:

position; //current position of the object. 
targetPosition; //set by scrolling, position should gradually come close to this 
float weigth; //how much the weight is of the targetPosition compared to the position 
//practically this means how fast position approaches targetPosition. 
//First try values between 0 and 1, for example 0.8f for starters. 
public void Scroll(Vector2 ammount) 
{ 
    //We assume scrolling the scrollbar 1 pixel down, means the object should go 1 pixel up. 
    //So the targetPosition should move the same ammount opposite. 
    //If you don't want scrolling to correspond 1:1, you can multiply ammount by a float. 
    targetPosition -= ammount; 
} 

public void Update(GameTime gameTime) 
{ 
    //.. 
    //Executed every update, position closes in on targetPosition pretty fast.  
    position = Vector2.Lerp(position, targetPosition, weigth); 

    //Because we Lerp position will only get extremely close to targetPosition. Never exactly at it. 
    //most of the time this is good enough, if this isnt use the following code 

    float omega = 0.05f; // the minimum dinstance between position and targetPosition before we clamp 
    if(Vector2.Distance(position, targetPosition) < omega) 
    { 
     position = targetPosition; 
    } 
    //.. 
} 

public void Draw(GameTime gameTime) 
{ 
    //.. 
    spriteBatch.Begin(); 
    spriteBatch.Draw(texture, position, Color.White); 
    spriteBatch.End(); 
    //.. 
} 
+0

Ничего себе. Работает безупречно и лучше, чем я ожидал! Благодарю. – Frexuz

+0

Привет, Frexuz, рад, что я мог бы помочь! –

3

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

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

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

В вашем случае, я получаю то, что вы пытаетесь сделать, просто хотите обновить позицию, основанную на скорости.

Пусть ваши дела по горизонтали (в обычно вы будете делать это для 2D),

X_new = X_old + скорость * дт скорость = тах (0, скорость * 0,95 - 0,2)

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

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

Помните, что вам придется обрабатывать это в потоке, вероятно, потому, что это то, что продолжает происходить. Вы также можете вычислить ускорение и использовать простую физику для вычисления позиции на ее основе. x = x0 + x '* t + 1/2 * x' '* t^2 тип материала.

0

Как обычно, если это XNA, Шон, вероятно, решить вашу проблему уже. В нескольких сообщениях он объясняет переходы с использованием Lerp, SmoothStep and other math operations и physics based approach. В примерах используется проект управления государственными играми, но идеи можно использовать в любом месте.

И, кстати, вам может потребоваться не перемещать все объекты вокруг камеры.Вы можете хранить vector2 или vector3 cameraOffset где-то и использовать transformMatrix в SpriteBatch.Begin. Конечно, это наиболее полезно, если вы используете один или два цикла spritebatch для рисования всех ваших объектов мира.

+0

На самом деле я делал это раньше, но одновременно рисовал так много объектов, давал мне около 3 кадров в секунду, так как мой «холст» был высотой 5000 пикселей. Поскольку Y объектов не изменяется, я не мог понять, как рисовать только видимые объекты. – Frexuz

+0

Точно так же вы выбираете, что рисовать, если камера статична. Вместо того, чтобы рисовать что-либо внутри прямоугольника (0, 0, screenWidth, screenHeight) плюс отступы, прямоугольник будет (cameraPos.X - halfScreenWidth, cameraPos.Y - halfScreenHeight, screenWidth, screenHeight) плюс отступы. Вы даже можете держать прямоугольник, прикрепленный к камере, и проверить пересечения. Все, что пересекает его viewRect на его Z, окрашено. Добавление разделов в зону игры сделает его еще быстрее. – Elideb

 Смежные вопросы

  • Нет связанных вопросов^_^