Возникли проблемы с использованием KeyEvent

Мой вопрос в том, как я могу заставить мои методы move() работать с использованием KeyEvents, т.е. KeyEvent.VK_DOWN? В настоящее время я пытаюсь использовать import java.awt.event.KeyEvent;, в котором я буду использовать клавиши со стрелками, а НЕ клавиши цифровой клавиатуры для перемещения игрока в двухмерной сетке. У меня есть действия moveUp(); moveRight(); moveDown(); и moveLeft(); в моем суперклассе User и классе Player extends User и содержит метод ключевого события. Когда я использую клавиши со стрелками, актер просто не двигается, однако, когда я вручную нажимаю на актера в сетке и выбираю метод, он будет двигаться. Поэтому мои методы перемещения работают, поэтому я предполагаю, что моя установка KeyEvent не работает. Фотографии, показывающие, как я вручную управляю методами, прилагаются.

Пользователь, содержащий методы перемещения

package info.gridworld.actor;
import info.gridworld.grid.Grid;
import info.gridworld.grid.Location;

public class User extends Actor {
    private boolean isStopped = false;

    public User()
    {
        setColor(null);
    }

    public void moveUp(){
        moveTo(getLocation().getAdjacentLocation(Location.NORTH));
    }

    public void moveDown(){
        moveTo(getLocation().getAdjacentLocation(Location.SOUTH));
    }

    public void moveLeft(){
        moveTo(getLocation().getAdjacentLocation(Location.WEST));
    }

    public void moveRight(){
        moveTo(getLocation().getAdjacentLocation(Location.EAST));
    }
}  

Класс игрока содержит KeyEvents

package game.classes;
import info.gridworld.actor.User;
import java.awt.event.KeyEvent;


public class Player extends User{

    public Player(){
    }

    public void keyPressed(KeyEvent e){
        int keys = e.getKeyCode();
        if((keys == KeyEvent.VK_UP)){
            moveUp();
        }
        else if((keys == KeyEvent.VK_DOWN)){
            moveDown();
        }
        else if((keys == KeyEvent.VK_LEFT)){
            moveLeft();
        }
        else if((keys == KeyEvent.VK_RIGHT)){
            moveRight();
        }
    }


}  

Основной класс

package game.classes;
import info.gridworld.grid.*;

public class PlayerRunner{


    private static GameGrid world = new GameGrid();

    public static void main(String[] args)
    {
        Player player = new Player();
        world.add(new Location(0, 0), player);
        world.show();
  }
}  

PreMove

moveDown() Выбрано


person Adamc23    schedule 10.06.2014    source источник
comment
Я не думаю, что это так работает, разве World не получает ключевую информацию?   -  person MadProgrammer    schedule 10.06.2014
comment
Возможный дубликат Как переместить ошибку в GridWorld с помощью стрелки ключи   -  person MadProgrammer    schedule 10.06.2014
comment
Я бы рекомендовал использовать keyBinding для этого   -  person Rod_Algonquin    schedule 10.06.2014
comment
@MadProgrammer Я попробую этот пример. Я также не видел метода keyPressed в классе ActorWorld.   -  person Adamc23    schedule 10.06.2014
comment
@Rod_Algonquin Я тоже так думал, но OP использует gridworld API, который работает немного по-другому ... не говоря о том, что это невозможно, но если мы сможем найти что-то, что работает с API, это даст лучшие результаты, если это не удастся. ..взломать, взломать, взломать ;)   -  person MadProgrammer    schedule 10.06.2014
comment
@MadProgrammer проблема с созданием нового класса, который расширяет ActorWorld, заключается в том, что у меня не будет доступа к моим методам move () .... Если я удалю стандартный метод keyPressed в классе World, будут ли мои методы работать?   -  person Adamc23    schedule 10.06.2014
comment
Вы должны иметь доступ к Actor через World#getGrid#get... я думаю... раньше не использовали API;)   -  person MadProgrammer    schedule 10.06.2014
comment
@MadProgrammer Извините, я отредактировал свой комментарий сразу после того, как вы ответили, но если я удалю метод KeyPressed, смогу ли я сохранить свой первоначальный дизайн?   -  person Adamc23    schedule 10.06.2014
comment
Понятия не имею, какой оригинальный дизайн?   -  person MadProgrammer    schedule 10.06.2014
comment
Что у меня есть в моем вопросе о настройке пользователя / игрока. Я не совсем понимаю настройку CharacterWorld, которую вы упомянули в дублирующем вопросе.   -  person Adamc23    schedule 10.06.2014


Ответы (2)


Класс World на самом деле имеет метод keyPressed(). Вы можете просто расширить World и переопределить этот метод. Это даст вам строковый параметр для работы вместо KeyEvent. Используйте javax.swing.KeyStroke.getKeyStroke(description).getKeyCode(), чтобы выяснить, какая клавиша была нажата. Источником класса World является она: https://github.com/parkr/GridWorld/blob https://github.com/parkr/GridWorld/blob/master/framework/info/gridworld/world/World.java aster/framework/info/gridworld/world/World.java

Что касается доступа к вашим методам Актера, я бы поместил ссылку на Актера в класс World. Затем, когда вы добавите актера, которого хотите переместить в мир, вы можете просто установить его там. Затем, когда вы имеете дело с нажатиями клавиш, у вас есть доступ к Актеру, которым вы хотите манипулировать.

person Mar Johnson    schedule 11.06.2014
comment
Хорошо, это должно работать, но в чем причина параметра местоположения? Это местонахождение актера? (получить местоположение();)? - person Adamc23; 11.06.2014
comment
Также я считаю, что одна из ваших ссылок не работает, я не смог отредактировать свой предыдущий комментарий, поэтому я создал этот новый. - person Adamc23; 11.06.2014
comment
Я думаю, что это Актер, выбранный в графическом интерфейсе мира. Вы не должны нуждаться в этом для того, что вы делаете, хотя - person Mar Johnson; 12.06.2014

Вы расширяете Актера, который не имеет ничего общего с графическим интерфейсом, а KeyEvents и связанные с ними вещи - это качели. Вам действительно нужно добавить KeyListener в JPanel. Насколько я могу судить, прямо сейчас у вас есть только дополнительные методы в классе Actor.

Графический интерфейс на самом деле не находится в тесте AP, поэтому о нем не так много, но похоже, что вы можете расширить info.gridworld.gui.GridPanel. Поэтому переопределите конструктор как:

public GridPanel(DisplayMap map, ResourceBundle res)
{
    super(map, res);
    addKeyListener(new KeyListener()
    {
        // Put the KeyListener methods here. 
        // (All of them: KeyListener is an interface
    }
}

Это немного грубо, но я думаю, что это должно сработать.

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

person Mar Johnson    schedule 10.06.2014
comment
@ user3709396 super(карта, разрешение); не соответствует аргументам в методе JPanel и требует, чтобы я удалил карту и разрешение.........` Конструктор JPanel(DisplayMap, ResourceBundle) не определен Удалить аргументы для соответствия 'JPanel()'` - person Adamc23; 11.06.2014
comment
Кроме того, где бы я разместил свои методы move()? они недоступны из gridPanel, и их перемещение на панель сетки не работает, потому что у меня нет доступа к геттерам местоположения - person Adamc23; 11.06.2014
comment
Вы расширяете GridPanel или JPanel? - person Mar Johnson; 11.06.2014
comment
Все дело в том, что я не понимаю, что вы делаете, вы модифицируете конструктор в GridPanel или вы говорите, что создаете отдельный класс, который все это делает? Поместите это в класс игрока в класс пользователя? Я могу создать все KeyEvents и еще много чего. Я просто не понимаю, куда добавить это, чтобы оно работало правильно? - person Adamc23; 11.06.2014
comment
Извините, но только что понял, что это ПЛОХОЙ способ сделать это. Написал лучший ответ... - person Mar Johnson; 11.06.2014