Kinetic scrolling of the <Rectangle> list in XNA

I am trying to scroll a row of rectangles vertically. Each rectangle has a fixed distance from the next. The first rectangle should never be below 10 pixels from the top of the screen, while the last rectangle should never be more than 20 pixels above the text box. In other words, I mimic the SMS application in Windows Phone.

The method below should theoretically scroll rectangles kinetically, and although this happens, in some cases some of the rectangles get closer to each other than they should (ultimately overlap). The effect seems to increase when clicks on the screen are slow.

private void Flick()
{
    int toMoveBy = (int)flickDeltaY;
    //flickDeltaY is assigned in the HandleInput() method as shown below
    //flickDeltaY = s.Delta.Y * (float)gameTime.ElapsedGameTime.TotalSeconds;

    for (int i = 0; i < messages.Count; i++)
    {
        ChatMessage message = messages[i];
        if (i == 0 && flickDeltaY > 0)
        {
            if (message.Bounds.Y + flickDeltaY > 10)
            {
                toMoveBy = 10 - message.Bounds.Top;
                break;
            }
        }
        if (i == messages.Count - 1 && flickDeltaY < 0)
        {
            if (message.Bounds.Bottom + flickDeltaY < textBox.Top - 20)
            {
                toMoveBy = textBox.Top - 20 - message.Bounds.Bottom;
                break;
            }
        }
    }
    foreach (ChatMessage cm in messages)
    {
        Vector2 target = new Vector2(cm.Bounds.X, cm.Bounds.Y + toMoveBy);
        Vector2 newPos = Vector2.Lerp(new Vector2(cm.Bounds.X, cm.Bounds.Y), target, 0.5F);
        float omega = 0.05f;
        if (Vector2.Distance(newPos, target) < omega)
        {
            newPos = target;
        }
        cm.Bounds = new Rectangle((int)newPos.X, (int)newPos.Y, cm.Bounds.Width, cm.Bounds.Height);
    }
}

I really don't understand Vectors, so I apologize if this is a stupid question.

+5
1

, . : (Vector2.Lerp) ( - ?):

Vector2 target = new Vector2(cm.Bounds.X, cm.Bounds.Y + toMoveBy); // <-- the target is Y-ToMoveBy different from the actual Y position
Vector2 newPos = Vector2.Lerp(new Vector2(cm.Bounds.X, cm.Bounds.Y), target, 0.5F); // <-- this line is equivalent to say that newPos will be new Vector2(cm.Bounds.X, cm.Bounds.Y + toMoveBy / 2);
float omega = 0.05f;
if (Vector2.Distance(newPos, target) < omega) // So the only chance to happen is toMoveBy == 0.10 ??? (because you modify `cm` each time `Flick()` is called ? - see next line) 
{
    newPos = target;
}
cm.Bounds = new Rectangle((int)newPos.X, (int)newPos.Y, cm.Bounds.Width, cm.Bounds.Height); // <-- Equivalent to  new Rectangle((int)cm.Bounds.X, (int)cm.Bounds.Y + toMoveBy / 2, ...)
0

All Articles