Как сделать движение более плавным?

Поэтому мне нужна помощь, чтобы мой персонаж двигался более плавно. Проблема в том, что персонаж перемещается на один пиксель, когда я нажимаю клавишу, и примерно через секунду он бежит после этого «плавно». Как я могу исправить это, чтобы мне не нужно было ждать эту секунду, и он просто работал гладко с самого начала? Я ценю любую помощь и заранее спасибо!

public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.setColor(Color.GREEN);
    g.fillRect(x, y, 30, 30);
    update();
}
private boolean[] KB = new boolean[4];
public void update(){ 
    if(KB[0] = true)
    {
        y -= 10;
    }
    if(KB[1] = true)
    {
        x -= 10;
    }
    if(KB[2] = true)
    {
        y += 10;
    }
    if(KB[3] = true)
    {
        x +=10;
    }
    repaint();
}

public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_W)
    {
        KB[0] = true;
    }
    if(e.getKeyCode() == KeyEvent.VK_A)
    {
        x -= 10;
    }
    if(e.getKeyCode() == KeyEvent.VK_S)
    {
        y += 10;
    }
    if(e.getKeyCode() == KeyEvent.VK_D)
    {
        x += 10;
    }
}
public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

person Mushi Mushi    schedule 08.05.2017    source источник
comment
if(KB[0] = true) должно быть if(KB[0] == true) ? или просто if(KB[0])   -  person samgak    schedule 08.05.2017
comment
А почему у вас другая логика в keyPressed ? PS: вызов repaint() в paintComponent, вероятно, тоже не лучшая идея.   -  person AxelH    schedule 08.05.2017
comment
Вам нужно использовать Swing Timer для управления анимацией. См. раздел Движение с помощью клавиатуры. Пример KeyboardAnimation.java показывает, как использовать Swing Timer для плавной анимации, которой вы можете управлять.   -  person camickr    schedule 08.05.2017


Ответы (2)


Я бы рекомендовал не использовать KeyListener и рекомендовал использовать Как использовать привязки клавиш, он решит проблему, связанную с фокусом, с помощью KeyListener и предоставит гораздо более повторно используемое решение.

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

Не вызывайте update в paintComponent, рисование может происходить по ряду причин, многие из которых вы не контролируете, это может вызвать проблемы с поддержанием плавной анимации.

Вместо этого вам нужен «основной» цикл, который отвечает за обновление состояния и планирование перерисовки. В качестве простого решения вы можете использовать Swing Timer для этого, так как он обновляет состояние пользовательского интерфейса изнутри, не рискуя дополнительными проблемами с потоками.

Дополнительные сведения см. в разделе Как использовать таймеры Swing. .

Как уже было сказано, используйте if(KB[0]) вместо if(KB[0] = true), поскольку = — это задание, а не оценка. Использование первой формы исключает возможность случайного совершения подобных ошибок.

person MadProgrammer    schedule 08.05.2017
comment
Спасибо за помощь! - person Mushi Mushi; 08.05.2017

Это потому, что ваш метод update неверен. Вы используете оператор = вместо == в своем условии.

if (KB[0] = true)

назначит true для KB[0] и оценит его как true, поэтому все ваши значения будут установлены на true внутри вашего if. Измените = на ==, когда вы используете его в качестве условия, если вы не хотите присваивать значение.

person Lajos Arpad    schedule 08.05.2017
comment
Ааа вижу Спасибо! Мне помогло! Кстати, вы знаете, как я могу использовать таймер в своем коде, пока вы этим занимаетесь? был бы признателен, так как мой учитель хочет, чтобы у меня был такой :D - person Mushi Mushi; 08.05.2017
comment
@MushiMushi добро пожаловать, и вы можете взглянуть на этот небольшой учебник: docs.oracle.com/javase/tutorial/uiswing/misc/timer.html. Если мой ответ помог вам решить вашу проблему, вы можете принять его как правильный ответ. - person Lajos Arpad; 08.05.2017