Посмотрите внимательно на содержимое цикла. Там условие выхода из цикла привязано к счетчику, а счетчик увеличивается только при некотором условии. Другими словами, если случилось так, что это условие неверно и вы в цикле, то счетчик не будет меняться и проверка условия будет молотить вечно, ведь ничего не меняется. Так получается бесконечный цикл.
Вообще такие вещи лучше описывать параметрически. То есть можно описать функцию, которая возвращает координату абсолютную от времени.
Обычно это делается так. Описывается класс, потомки от которого будут описывать характер движения. Паттерн называется "Стратегия".
У персонажа есть состояние, например "равномерная ходьба". Это состояние определяет стратегию движения. То есть когда началась равномерная ходьба, создаётся инстанс этой стратегии, который запоминает время начала ходьбы, начальные координаты и определяет скорость. У стратегии движения есть метод, который возвращает координату от абсолютного времени. Под капотом из этого времени вычитается время начала движения, а потом по простой линейной формуле можно вычислить координату персонажа на любое заданное время. Как только состояние персонажа сменяется на "Рывок", создаётся новый инстанс новой стратегии под названием "Рывок". Она определяет внутри другую функцию вычисления координаты от времени. Скорость тоже может быть задана функцией внутри реализации стратегии.
Такой подход позволит гибко менять динамику игры, настраивать ее в широких пределах, добавлять новые фишки, и при этом код не будет засоряться кучей нечитабельной логики с +\- единицами, будет меньше ошибок.