Мерцание фона при прокрутке в XNA

Я использую учебник по фоновой прокрутке на xnadevelopment.com (измененный в соответствии с моими требованиями), чтобы создать цикл вертикальной прокрутки для игры на Windows Phone 7.1. Кажется, что фон мерцает всякий раз, когда рисуется следующее изображение. Хотя я использую одно изображение для цикла, мерцание происходит, даже если используется несколько изображений. Я разместил видео на YouTube, показывающее мерцание, которое происходит в верхней части экрана.

http://youtu.be/Ajdiw2zILq0 Ниже приведен код, используемый для создания цикла:

Фоновый класс:

    private List<string> _road;
    private VericalBackgroundLoop _roadLoop;
    private readonly Vector2 _roadSpeed = new Vector2(0, 300);

    public void LoadContent(ContentManager contentManager)
    {
        _road = new List<string>
                         {
                             "Test\\Road_Bgnd",
                             "Test\\Road_Bgnd"
                         };

        _roadLoop = new VericalBackgroundLoop();
        _roadLoop.Initialize(_road, contentManager, Vector2.Zero, true);
    } 

    public void Update(TimeSpan elapsedTime)
    {
        _roadLoop.Update(_roadSpeed, elapsedTime);
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        _roadLoop.Draw(spriteBatch);
    }

Класс фонового цикла:

    private List<Sprite> _sprites;
    private bool _isLoopDirectionTopToBottom;
    private Vector2 _loopDirection;

    public void Initialize(List<string> spriteNames, ContentManager contentManager, Vector2 loopStartPosition, bool isLoopDirectionTopToBottom)
    {
        _sprites = new List<Sprite>();
        _isLoopDirectionTopToBottom = isLoopDirectionTopToBottom;

        _loopDirection = new Vector2(0, -1);

        // Build the sprite object's list
        foreach (string spriteName in spriteNames)
        {
            Sprite sprite = new Sprite();
            sprite.LoadContent(contentManager, spriteName);

            _sprites.Add(sprite);
        }

        if (_isLoopDirectionTopToBottom)
        {
            // Set the initial position for the sprite objects
            foreach (Sprite currentSprite in _sprites)
            {
                if (currentSprite == _sprites.First())
                {
                    currentSprite.Position = loopStartPosition;
                }
                else
                {
                    Sprite prevSprite = GetSpriteAtIndex(_sprites.IndexOf(currentSprite) - 1);
                    currentSprite.Position = new Vector2(0, prevSprite.Position.Y - prevSprite.Size.Height);
                }
            }
        }
     }

    public void Update(Vector2 loopSpeed, TimeSpan elapsedTime)
    {
        if (_isLoopDirectionTopToBottom)
        {
            foreach (Sprite currentSprite in _sprites)
            {
                if (currentSprite == _sprites.First())
                {
                    Sprite lastSprite = _sprites.Last();
                    if (currentSprite.Position.Y > (currentSprite.Size.Height))
                    {
                        currentSprite.Position.Y = lastSprite.Position.Y - lastSprite.Size.Height;
                    }
                }
                else
                {
                    Sprite prevSprite = GetSpriteAtIndex(_sprites.IndexOf(currentSprite) - 1);
                    if (currentSprite.Position.Y > (currentSprite.Size.Height))
                    {
                        currentSprite.Position.Y = prevSprite.Position.Y - prevSprite.Size.Height;
                    }
                }

                // Update the sprite X position with the speed and time
                currentSprite.Position -= _loopDirection * loopSpeed * (float)elapsedTime.TotalSeconds;
            }
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        foreach (Sprite sprite in _sprites)
        {
            sprite.Draw(spriteBatch);
        }
    }

    private Sprite GetSpriteAtIndex(int index)
    {
        return _sprites[index];
    }

Нужна помощь в том, чтобы разобраться, почему происходит мерцание и почему движение кажется рывками, а не плавностью (на аппарате чуть лучше, но все же рывками). IsFixedTimeStep имеет значение true в классе game.cs. Спасибо.

РЕДАКТИРОВАНИЕ: кажется, что мерцание не происходит, если используются 3 или более изображений. Это может быть связано с тем, что первое изображение недостаточно быстро возвращается в исходное положение. Но я все еще пытаюсь понять, почему анимация все еще такая дерганая :(


person user1147470    schedule 13.01.2012    source источник
comment
Я бы использовал миллисекунды, а не секунды для движения по времени. В противном случае вы теряете большую точность, потому что обычно кадр занимает меньше секунды.   -  person dowhilefor    schedule 13.01.2012
comment
Чтобы использовать миллисекунды, я считаю, что скорость должна быть изменена? Любая идея о том, насколько скорость должна быть обновлена?   -  person user1147470    schedule 13.01.2012
comment
Если вы разделите время на 1000, просто разделите скорость на 1000.   -  person annonymously    schedule 13.01.2012
comment
Спасибо вам обоим. Прокрутка кажется немного более плавной с миллисекундами. Самая большая разница (более плавная), кажется, происходит, когда для IsFixedTimeStep установлено значение false.   -  person user1147470    schedule 13.01.2012


Ответы (1)


Вы не будете первым, кто сообщит о мерцании или заикании. Об этом много сообщений на форумах App Hub. (кстати, рад, что вам повезло, используя мои уроки/образцы!)

Вот пример того, как кто-то сообщает о том, что видите вы -> http://forums.create.msdn.com/forums/t/30500.aspx

И вот лучший ответ, который я когда-либо видел от одного из разработчиков XNA Framework -> http://forums.create.msdn.com/forums/p/9934/53561.aspx#53561

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

person George Clingerman    schedule 29.01.2012