2014-01-07 4 views
3

В страхе изобретать колесо, я задаюсь вопросом:libGDX: Как реализовать плавное движение персонажей с черепицей/сеткой?

Каков наилучший подход к реализации плавного движения на основе игрового персонажа сетки на нисходящем Плиточные (2D) карты с libGDX?

Персонаж должен плавно перемещаться между плитами до тех пор, пока нажата клавиша со стрелкой (или событие касания происходит в определенном направлении персонажа), и должно заканчиваться в положении сетки на клавише/сенсорном выпуске. Движение должно быть независимым от частоты кадров.

Я был бы рад некоторым уже реализованным примерам, которые можно изучить и привести к правильному использованию API-интерфейса libGDX.

ответ

6

Проверьте, нажата ли какая-либо кнопка (или коснулась экрана), если она установлена, установите правильную целевую плиту (плитку, в которой игрок пойдет) в поле и начните движение туда, это движение закончится только тогда, когда игрок находится в следующей плитке. Когда это произойдет, снова проверьте вход, чтобы продолжить движение (т. Е. Повторить).

Предположим, ваша ширина/высота плитки равна 1, и вы хотите переместить 1 плиту в секунду. Ваш пользователь нажал клавишу со стрелкой вправо. Затем вы просто устанавливаете targettile на плитку справа от игрока.

if(targettile!=null){ 
    yourobject.position.x += 1*delta; 
    if(yourobject.position.x>=targettile.position.x){ 
     yourobject.position.x = targettile.position.x; 
     targettile = null; 
    } 
} 

Этот код упрощен только для правостороннего перемещения, вам также нужно сделать его для других направлений.
Не забудьте повторно опросить вход, если игрок не двигается.

Edit:

InputPolling для ключей:

if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)){ 

InputPolling для Touchs (кулачок камера, и TouchPoint является Vector3 для хранения unprojected касания координаты и moverightBounds а (libgdx) Прямоугольник):

if (Gdx.input.isTouched()){ 
    cam.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0)); 
    //check if the touch is on the moveright area, for example: 
    if(moveRightBounds.contains(touchPoint.x, touchPoint.y)){ 
     // if its not moving already, set the right targettile here 
    } 
} 

И noone уже сказал, что это, вы получите в виде дельта параметр в визуализации метод, или вы можете получить его в другом месте с помощью:

Gdx.graphics.getDeltatime(); 

Ссылки:

+0

Спасибо за помощь. Не могли бы вы объяснить немного больше, где вызывать этот код и как делать входной опрос? Кроме того, я не уверен, как вычислить 'delta' в соответствии с изменяющейся частотой кадров. –

+1

@JensPiegsa Вы получаете дельта от LibGDX как параметр в методах render(). В противном случае вы можете получить его через Gdx.graphics.getDeltaTime(). – noone

+1

Отредактированный мой ответ: вы вызываете это в методе рендеринга (каждый кадр) – Lestat

2

Это только одно измерение, но я надеюсь, что вы получите идея, проверяя клавиши направления и добавляя/вычитая 1, а затем бросая его на int (или напольное покрытие), даст вам следующую плитку. Если вы отпустите ключ, у вас все еще есть недостигнутая цель, и сущность продолжит движение, пока не достигнет целевой плитки. Я думаю, что это будет выглядеть примерно так:

void update()(
    // Getting the target tile 
    if (rightArrowPressed) { 
     targetX = (int)(currentX + 1); // Casting to an int to keep 
             // the target to next tile 
    }else if (leftArrowPressed){ 
     targetX = (int)(currentX - 1); 
    } 

    // Updating the moving entity 
    if (currentX < targetX){ 
     currentX += 0.1f; 
    }else if (currentX > targetX){ 
     currentX -= 0.1f; 
    } 
} 
+0

То, что я ответил за несколько часов до ... и это использует фиксированный шаг, вместо того, чтобы использовать время между кадрами для достижения независимого от кадра кадра. – Lestat

+1

Жаль, ваш ответ не был виден для меня, когда я отправил свой ответ. –

+0

Однако, спасибо за помощь! –