Перемещение спрайтов с помощью gameTime, зачем мне использовать +=?
Я пытаюсь переместить спрайт двухмерного теста с переменной gameTime.ElapsedGameTime.TotalMilliseconds;
Код для обновления позиции спрайтов работает так:
spritePosition.X += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
С помощью приведенной выше строки спрайт перемещается вправо во время выполнения, как и ожидалось.
Однако я не понимаю, почему мне нужно "+=". Т.е. почему не работает следующее:
spritePosition.X = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
(Я понимаю, что x += 1 - это сокращение от x = x + 1)
Я передаю gameTime в функцию обновления, не должна ли она постоянно меняться (и, следовательно, постоянно перемещать спрайт)? Я чувствую, что упускаю что-то прямо!
РЕДАКТИРОВАТЬ: спрайт не ускоряется. (Я могу проверить это, используя секунды, а не миллисекунды, и он явно движется со скоростью 1 пиксель в секунду, а не ускоряется)
Информация:
Язык: C# Я использую шаблон игры для Windows XNA Вышеупомянутая отдельная строка вызывается в функции обновления
3 ответа
Это потому что gameTime.ElapsedGameTime
время, прошедшее с последнего "кадра". Это означает, что при скорости 60 кадров в секунду всегда будет около 1/60 секунды.
Вы устанавливаете положение на постоянное значение.
См. Описание по http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.gametime.elapsedgametime.aspx
gameTime.ElapsedGameTime
время с момента последнего обновления. Поэтому вам нужно добавить эту дельту, поэтому +=. Вы бы использовали = для абсолютного времени (gameTime.TotalGameTime
).
Тебе нужно ElapsedGameTime
потому что вы не знаете, как часто вызывается обновление. Так что если вам нужна постоянная скорость, скажем, 1000px/s, и вы получаете только 1 вызов обновления в секунду (например, медленный процессор) ElapsedGameTime
будет 1000 мс каждый раз, и вы будете перемещать спрайт на 1000 пикселей каждую секунду.
Если вы получаете 50 кадров в секунду (так 50 обновлений вызовов в секунду) ElapsedGameTime
будет всегда 20 мс, и вы перемещаете спрайт на 50 * 20 мс = 1000 пикселей каждую секунду.
Таким образом, вам не нужно заботиться о лагах или скорости процессора.
В вашем примере это не имеет значения. Так как вы делаете только линейное движение, вы можете использовать Position.X = TotalGameTime
и это сделало бы то же самое. Но когда вам нужно определить, насколько далеко переместился спрайт, исходя из его собственной скорости с момента последнего обновления, вам понадобится Position += ElapsedGameTime * (object/sprite speed)
Разница в том, что +=
добавляет к текущей стоимости spritePosition.X
в то время как =
просто назначает новое значение.
Если spritePosition.X
имеет значение 5
а также gameTime.ElapsedGameTime.TotalMilliseconds
имеет значение 10 (ради этого аргумента), тогда первая строка кода оценивается как:
spritePosition.X += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
spritePosition.X = spritePosition.X + (float)gameTime.ElapsedGameTime.TotalMilliseconds;
spritePosition.X = 5 + (float)10; // 15
В то время как второй оценивает:
spritePosition.X = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
spritePosition.X = (float)10; // 10