понедельник, 20 февраля 2012 г.

Java: Параметры объектов и их обработка клавиатурой.

Java: Параметры объектов и их обработка клавиатурой.

   Недавно начал изучать OpenGL. Как и полагается при экспериментировании над новой системой требуется организовать некоторую "динамику" параметров, чтобы было наглядно видно, что же происходит. Самым простым представляется метод изменения параметров клавишами на клавиатуре. В принципе организовать логику обработки уменьшения/увеличения одного параметра с помощью одной-двух клавиш - не проблема и без всяких наворотов, но если хочется не просто один параметр, а два-три-четыре и не просто включить/выключить, а линейное изменение или изменение с ускорением? В общем список пожеланий можно продолжить, а я хочу предложить некоторую реализацию этих желаний...

исходник.Скачайте исходник и продолжим рассмотрение решения.

Класс ParamChangeByKeybord представляет собой набор конструкторов для создания различных параметров, которыми пользователь хочет управлять с клавиатуры. Примеры параметров:

    private ParamChangeByKeybord params = new ParamChangeByKeybord();

    private ParamChangeByKeybord.Acc cubeRot = params.addAcc(0, 1000, 1000, 'c', 'v');
    private ParamChangeByKeybord.Linear cubeOrbitRadius = params.addLinear(0.5f, 0.5f, 'z', 'x');
    private ParamChangeByKeybord.Switcher cubeSwitcher  = params.addSwitcher(true, 'o', 'p');
    private ParamChangeByKeybord.Trigger sTrigger = params.addTrigger(true, 'q');
    private ParamChangeByKeybord.Linear lPos = params.addLinear(0.0f, 2f, 'e', 'r');
    private ParamChangeByKeybord.Linear pViewAngle = params.addLinear(0.0f, 300.0f, 'k', 'l');

ParamChangeByKeybord.Acc -изменение значения параметра происходит с заданным ускорением.
ParamChangeByKeybord.Linear - изменение значения параметра происходит линейно.
ParamChangeByKeybord.Switcher - одна клавиша включает параметр, другая выключает (true/false).
ParamChangeByKeybord.Trigger - одна и та же клавиша переключает параметр true/false.

   Обратите внимание, что создаваемые параметры "объединяются" под общей крышей params. Именно этот объект единолично следит за обработкой параметров от клавиш на клавиатуре.

Включение управлением параметров в программу.

Графический интерфейс программы должен наследовать и реализовать интерфейс implements java.awt.event.KeyListener следующим образом:

    @Override
    public void keyTyped(java.awt.event.KeyEvent e)
    {
        byte key = (byte)e.getKeyChar();
        params.keyTyped(key);
    }
   
    @Override
    public void keyReleased(java.awt.event.KeyEvent e)
    {
        byte key = (byte)e.getKeyChar();
        params.keyReleased(key);
    }

    @Override
    public void keyPressed(java.awt.event.KeyEvent e)
    {
        if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
        {
            System.exit(0);
        }
    }

В функции keyTyped происходит сохранение нажатой клавиши в буфере объекта params. Обработка клавиши должна происходить в методе display  (поскольку я рассматриваю OpenGL, но вы можете добавить эту функцию в любой метод, осуществляющий вывод на экран):

        public void display(GLAutoDrawable drawable)
        {
                     params.process( new Date().getTime() );
                     .
                     .
                     .
        }
Применение параметров, управляемых с клавиатуры у меня осуществлено в том же методе display (cubeOrbitRadius и cubeSwitcher):

        public void display(GLAutoDrawable drawable)
        {
                     params.process( new Date().getTime() );
                     .
                     gl.glTranslated(cubeOrbitRadius.value, 0, 0); 
                     if(cubeSwitcher.value==true)
                     {
                         gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, new float[]{1.0f, 1.0f, 1.0f,1.0f}, 0);
                         glut.glutSolidCube(0.4f);
                     }
                     .
                     .
                     params.resetLastTimeMesure();
        }


Обратите внимание на последний метод params.resetLastTimeMesure();. Этот метод запоминает момент времени, в который закончилось рисование. В дальнейшем этот момент времени будет учитываться для изменения значений параметров.

Вот, вроде и всё. Осталось предложить пример использования такого подхода: исходник.

Комментариев нет: