Math XNA中的滚动屏幕-轻松数学(轻弹手势)

Math XNA中的滚动屏幕-轻松数学(轻弹手势),math,xna,gesture,easing,Math,Xna,Gesture,Easing,我一直在来回尝试,但我不知道在使用flick手势时如何滚动视图(或者说偏移所有对象)。我想滚动有一些缓解了 public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen) { float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; //Some

我一直在来回尝试,但我不知道在使用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;
            }
        }
    }
这应该没那么难,但我的大脑冻结了:)请帮帮我

我想你所说的“放松”是指它逐渐做到它应该做的事情(我不太清楚这一点(我不太了解触摸屏和手势)

有几种方法可以做到这一点。你可以采取物理方法,使用牛顿定律,简单地解微分方程

我通常这样做的方式(比如用鼠标滚动窗口时逐渐停止),就是简单地使用一些带有参数的函数逐渐降低速度,我可以修改这些参数以获得我想要的感觉

在你的例子中,我得到了你想要做的,你只需要根据速度来更新位置

假设你在水平方向上做这件事(通常你会做2D)

X_新=X_旧+速度*dt 速度=最大值(0,速度*0.95-0.2)

这样做的目的是逐渐移动x坐标(每次通过循环时x_old变为x_new(通常在线程中这样做)),这样它不会完全停止,而是继续移动,直到速度达到零。我使用一个简单的pow函数来逐渐减小它,但你可以使用任何类型的函数

你也可以考虑指针到边缘的距离。我在我的一个程序中这样做,当鼠标光标离开边缘时,它滚动的速度取决于滚动的距离(所以如果你想滚动一点,你就移动一点,移动很多)

请注意,你必须在一个线程中处理这个问题,可能是因为它会继续发生。你也可以计算加速度,并使用简单的物理计算基于它的位置。x=x0+x'*t+1/2*x'*t^2类型的东西。

我想你所说的“放松”是指它逐渐做它应该做的事情(我对此不太清楚(我对触摸屏和手势不太了解)

有几种方法可以做到这一点。你可以采取物理方法,使用牛顿定律,简单地解微分方程

我通常这样做的方式(比如用鼠标滚动窗口时逐渐停止),就是简单地使用一些带有参数的函数逐渐降低速度,我可以修改这些参数以获得我想要的感觉

在你的例子中,我得到了你想要做的,你只需要根据速度来更新位置

假设你在水平方向上做这件事(通常你会做2D)

X_新=X_旧+速度*dt 速度=最大值(0,速度*0.95-0.2)

这样做的目的是逐渐移动x坐标(每次通过循环时x_old变为x_new(通常在线程中这样做)),这样它不会完全停止,而是继续移动,直到速度达到零。我使用一个简单的pow函数来逐渐减小它,但你可以使用任何类型的函数

你也可以考虑指针到边缘的距离。我在我的一个程序中这样做,当鼠标光标离开边缘时,它滚动的速度取决于滚动的距离(所以如果你想滚动一点,你就移动一点,移动很多)

请注意,你必须在一个线程中处理这个问题,可能是因为它会继续发生。你也可以计算加速度,并使用简单的物理计算基于它的位置。x=x0+x'*t+1/2*x'*t^2类型的东西。

你可以在两个值之间“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();
    //..
}
position;//对象的当前位置。
targetPosition;//通过滚动设置,位置应逐渐接近此值
漂浮重量;//目标位置相对于位置的重量
//实际上,这意味着位置接近targetPosition的速度有多快。
//首先尝试0到1之间的值,例如0.8f。
公共无效卷轴(矢量2 amount)
{
//我们假设滚动条向下滚动1个像素,意味着对象应该向上滚动1个像素。
//因此,targetPosition应该将相同的弹药移动到相反的位置。
//如果您不希望滚动对应于1:1,可以将amount乘以float。
targetPosition-=amount;
}
公开作废更新(游戏时间游戏时间)
{
//..
//执行每次更新后,position都会很快接近targetPosition。
位置=矢量2.Lerp(位置,目标位置,重量);
//因为我们的Lerp位置只会非常接近目标位置,永远不会精确地对准它。
//大多数情况下,这已经足够好了,如果不是这样,请使用以下代码
浮动ω=0.05f;//夹紧前位置和目标位置之间的最小距离
if(矢量2.距离(位置,目标位置)
您可以在两个值之间“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();
    //..
}
position;//对象的当前位置。
targetPosition;//通过滚动设置,位置应逐渐接近此值
漂浮重量;//目标位置相对于位置的重量
//实际上,这意味着位置接近targetPosition的速度有多快。
//首先尝试0到1之间的值,例如0.8f。
公共voi