Модераторы: javastic, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двойное нажатие клавишь. getKeyStates() для Motorolla 
:(
    Опции темы
TigraZver
Дата 31.5.2008, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Помогите кто может. 
Пробежалась по темам о getKeyStates() и keyPressed(int keyCode) и не нашла ответ на мой вопрос.
Как я понимаю getKeyStates() позволяет опросить состояние клавы на момент вызова, может быть нажато несколько кнопок. Например ка это делается у меня:

Код

public void Process(){

       int KeyStates = getKeyStates();
       
      
       boolean IS_LEFT=((KeyStates&LEFT_PRESSED)!=0);
       boolean IS_RIGHT=((KeyStates&RIGHT_PRESSED)!=0);
       boolean IS_UP=((KeyStates&UP_PRESSED)!=0);
       boolean IS_DOWN=((KeyStates&DOWN_PRESSED)!=0);
       boolean IS_FIRE=((KeyStates&FIRE_PRESSED)!=0);


       switch (curScene)
        {
            case 1:
                StartScene(GameMenu.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
            case 2:
                StartScene(GameEng.Process(IS_UP,IS_DOWN,IS_LEFT,IS_RIGHT,IS_FIRE));
                break;
                
           case 3:
                StartScene(GameSetting.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
           case 4:
                StartScene(GameHighScore.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;   
                
           case 5:
                StartScene(GameAbout.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
           case 6:
                StartScene(GameOver.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;                
                           
           case 7:
                 this.Quit();
                 break;
                
            default:
            break;
        }

    }


Проблема у меня возникает в вызове StartScene(GameMenu.Process(IS_UP,IS_DOWN,IS_FIRE)):

Код

public int Process(boolean IS_UP, boolean IS_DOWN, boolean IS_FIRE){
        
     int ret = 1;

    
        if (IS_UP) state--;
        if (state<1) state =1;
        
        if (IS_DOWN) state++;
        if (state>4) state =5;       
        
        if (IS_FIRE){
            
            switch (state){
                case 1:
                    ret = 2; 
                    break;
                case 2:
                    ret = 3; 
                    break;
                case 3:
                    ret = 4; 
                    break;    
             ...
                default:
                    break;
            }
        }

    return ret;    
    }


В эмуляторе все работает так как надо - верх, вниз, fire - переход происходит и выполняется. Но вот при тестировании на Motorole происходит двойное нажатие  - перескакивает через один. 
,
В одной из тем разбиралась подобная проблема  и один из челов предложил, что keyRelease считаеться за еще одно нажатие, поэтому следует переопределить этот метод.
Подскажите как это сделать в данной конструкции или как по другому решить данную проблемку.

Добавлено через 3 минуты и 9 секунд
Да еще один баг, если так можно назвать. На Моторе Fire или кнопка 5 не активны. Вместо этого клавиша # - выполняет ее действия. Как исправить чтоб работало как надо?
PM MAIL   Вверх
TigraZver
Дата 1.6.2008, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Ну пока ответов нет, накрутила сама кое что:
  
Код

public int Process(boolean IS_UP, boolean IS_DOWN, boolean IS_FIRE){
        
     int ret = 1;
        
     boolean count=true;
        
        if (IS_UP )
            if(count && flag !=1)
                {state--; flag=1; count=false;}
            else { count=true; flag=0;}

        if (state<1) state =1;
        
        if (IS_DOWN )
            if(count && flag!=2)
                {state++; flag=2; count=false;}
            else {count=true; flag=0;}

        if (state>4) state =5;       
        
        if (IS_FIRE ){
            if(count && flag!=3)
               {
                    flag=3;count=false;
                    switch (state){
                        case 1:
                            ret = 2; 
                            break;
                        case 2:
                            ret = 3; 
                            break;
                        case 3:
                            ret = 4; 
                            break;    
                        case 4:
                            ret = 5;
                            break;
                        case 5:
                            ret = 7;
                            break;  
                        default:
                            break;
                    }
                }
             else {count=true; flag=0;}
        }
    return ret;    
    }


flag глобальный. Криво конечно... Но другого варианта пока нет.
Но помогло не сильно. Задержка небольшая получилась, но дело вроде в том, что нажатие кнопки Мотор воспринимает как длинное нажатие, то есть как многоразовое нажатие.  Чем дольше держишь кнопку тем больше нажатий.
Вообщем кто знает как избавиться от этого чуда - напишите. Жду.
PM MAIL   Вверх
Dummy
Дата 1.6.2008, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Небольшая поправочка, GameCanvas.getKeyStates() возвращает не совсем состояние клавиатуры на момент вызова. Она возвращает переменную-защелку, в которой биты, соответствующие нажатым с момента последнего вызова getKeyStates() клавишам, выставлены в 1, а остальные - в 0. Т. е. любая клавиша, нажатая между двумя вызовами GameCanvas.getKeyStates() (или от момента старта мидлета до первого вызова getKeyStates()), будет включена в возвращаемое значение, даже если на момент вызова она уже отжата. Твой код учитывает эту особенность?

Это сообщение отредактировал(а) Dummy - 1.6.2008, 21:33
PM MAIL   Вверх
TigraZver
Дата 2.6.2008, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Цитата(Dummy @ 1.6.2008,  21:29)
Небольшая поправочка, GameCanvas.getKeyStates() возвращает не совсем состояние клавиатуры на момент вызова. Она возвращает переменную-защелку, в которой биты, соответствующие нажатым с момента последнего вызова getKeyStates() клавишам, выставлены в 1, а остальные - в 0. Т. е. любая клавиша, нажатая между двумя вызовами GameCanvas.getKeyStates() (или от момента старта мидлета до первого вызова getKeyStates()), будет включена в возвращаемое значение, даже если на момент вызова она уже отжата. Твой код учитывает эту особенность?

Я так понимаю что не учитывает.
Какие есть варианты ? Где посмотреть , что почитать?:

Добавлено через 9 минут
Обнулять значение нажатой клавиши после каждого считывания? 
PM MAIL   Вверх
Dummy
Дата 2.6.2008, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



getKeyStates() обнуляет внутреннее состояние защелки после каждого вызова. Можно, например, при переходе в новое состояние, вызывать getKeyStates() вхолостую, просто чтобы сбросить накопленные ранее клавиши. Т. е. при каждом 
Код

state = <что-то>

ты делаешь getKeyStates().

Мое личное мнение - стиль кодирования в твоем примере зубодробительный (без обид smile ), поэтому вместо  лучше неочевидных 
Код
state = <что-то>
 и 
Код
state++
 завести функцию наподобие goToState(), которая будет переводить приложение из состояния в состояние, меняя значения переменной state (для которой лучше завести набор констант типа STATE_MENU, STATE_SETTINGS и т. п.) и, возможно, делая какие-то еще действия, и уже поместить getKeyStates() в эту функцию для любого успешного перехода в новое состояние.


Это сообщение отредактировал(а) Dummy - 2.6.2008, 13:29
PM MAIL   Вверх
i_SweP
Дата 2.6.2008, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 126
Регистрация: 23.6.2007

Репутация: нет
Всего: нет



А решение-то простое! Надо сделать задержку в цикле. 

Например
Код

while(continueFlag)
{
    // свой код, где-то здесь вызов getKeyStates()
    try
    {
        Thread.sleep(200);  // хочу заметить, что это вызов паузы для Текущего треда
    }
    catch (InterruptedException ex)
    {
        ex.printStackTrace();
    }
}


И никакой keyReleased() не считается за ещё одно нажатие. 

Это сообщение отредактировал(а) i_SweP - 2.6.2008, 20:49
PM MAIL   Вверх
TigraZver
Дата 2.6.2008, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Цитата(Dummy @ 2.6.2008,  13:26)
Мое личное мнение - стиль кодирования в твоем примере зубодробительный (без обид smile ), поэтому вместо  лучше неочевидных 
Код
state = <что-то>
 и 
Код
state++
 завести функцию наподобие goToState(), которая будет переводить приложение из состояния в состояние, меняя значения переменной state (для которой лучше завести набор констант типа STATE_MENU, STATE_SETTINGS и т. п.) и, возможно, делая какие-то еще действия, и уже поместить getKeyStates() в эту функцию для любого успешного перехода в новое состояние.

Ну прежде всего спасибо за инфу, приняла к сведению.  smile 
Только твой вариант с отдельной функцией и в ней уже описывать getKeyStates() в данном случае мне не много не подходит так как у меня главный класс class Engine extends GameCanvas implements Runnable и в него включены остальные в том числе и Меню и сама Игра - Game :
Код

    private Menu GameMenu;
    private Game GameEng;
    private About GameAbout;
    private Setting GameSetting;
    private Score GameHighScore;
    private GameOver GameOver;

там же и определена функция, которая снимает показание с клавиш и уже в зависимости от того какая сцена запущена, выполняет функцию Process() в своих собственных классах( например : GameEng.Process(IS_UP,IS_DOWN,IS_LEFT,IS_RIGHT,IS_FIRE) - снятие показания клавиш для самой игры,  GameMenu.Process(IS_UP,IS_DOWN,IS_FIRE) - для меню, и т.д) :
Код

public void Process(){  
        
       boolean IS_LEFT=(((getKeyStates())&LEFT_PRESSED)!=0);
       boolean IS_RIGHT=(((getKeyStates())&RIGHT_PRESSED)!=0);
       boolean IS_UP=(((getKeyStates())&UP_PRESSED)!=0);
       boolean IS_DOWN=(((getKeyStates())&DOWN_PRESSED)!=0);
       boolean IS_FIRE=(((getKeyStates())&FIRE_PRESSED)!=0);

       switch (curScene)
        {
            case 1:
                StartScene(GameMenu.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
            case 2:                            
                StartScene(GameEng.Process(IS_UP,IS_DOWN,IS_LEFT,IS_RIGHT,IS_FIRE));
                break;
                
           case 3:
                StartScene(GameSetting.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
           case 4:
                StartScene(GameHighScore.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;   
                
           case 5:
                StartScene(GameAbout.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;
                
           case 6:
                StartScene(GameOver.Process(IS_UP,IS_DOWN,IS_FIRE));
                break;                
                           
           case 7:
                 this.Quit();
                 break;
                
            default:
            break;
        }

    }


а уже в самом классе, например того же Game в функции Process() я прописываю действия на эти клавиши:
Код

    
    public int Process(boolean IS_UP, boolean IS_DOWN, 
                        boolean IS_LEFT, boolean IS_RIGHT, boolean IS_FIRE){
      int ret = 2;  
      
      bulwait++;

      if (rnd.nextInt(60)==30) asters.CrAster(-5,8+rnd.nextInt(200),rnd.nextInt(360),2+(4/(1+rnd.nextInt(4))));

      if ((IS_FIRE)&&(bulwait>5)){
          bulwait = 0;
          bullets.CrBullet(PlayerX,PlayerY,PlayerAngle, -Velocity);
      }
          
      
      if (IS_RIGHT) PlayerAngle+=10;
      if (PlayerAngle==360) PlayerAngle = 0;
      
      if (IS_LEFT) PlayerAngle-=10;
      if (PlayerAngle==0) PlayerAngle = 360;
      
      if (IS_UP){     
         // particles.AddEffect(PlayerX,PlayerY,1,10,PlayerAngle+180);
          Velocity-=0.9f;
          if (Velocity<-8.5f) Velocity=-8.5f;       
      } else {
          
          if (IS_DOWN){
          Velocity+=0.9f;
          if (Velocity>5.5f) Velocity=5.5f;                     
          } else {
           if (Velocity<0)
           {Velocity+=0.5; if (Velocity>0.0f) Velocity=0.0f;} else 
           {Velocity-=0.5; if (Velocity<0.0f) Velocity=0.0f;}
           
          }
          
      if (status == 1)
      {
        ret = 6;
        Score.totalScore=score;
        Score.BestScore=highScore;
        return ret;
         }
      }
              
      Collisions();       
      return ret;
    }
 

А в классе Menu я использую кнопки верх вниз и ввод для перехода с одной подменюшки на другую: 
Код

 public int Process(boolean IS_UP, boolean IS_DOWN, boolean IS_FIRE){        
     int ret = 1;
            
        if (IS_UP && state>1) {state--; IS_UP = false;}      
        if (IS_DOWN && state<5) {state++; IS_DOWN = false;}        
        if (IS_FIRE ){   
                    switch (state){
                        case 1:
                            ret = 2; 
                            break;
                        case 2:
                            ret = 3; 
                            break;
                        case 3:
                            ret = 4; 
                            break;    
                        case 4:
                            ret = 5;
                            break;
                        case 5:
                            ret = 7;
                            break;  
                        default:
                            break;
                    }  
                    IS_FIRE = false;
        }
    return ret;    
    }


переменная ret  возвращает новое значение сцены и уже в классе Engine происходит обработка в его собственном Process() (описание в самом начале).

Так вот предложенный тобой вариант как я понимаю предполагает, что эти функции, и класса Игра, и Меню будут прописаны в главном классе Ядре, чтоб иметь возможность применить метод getKeyStates(). Или же прописывать GameCanvas в каждом классе. 
если я не так тебя поняла, поясни пожалуйста.

на данный момент кнопки рабочие, и в Игре и в Меню так как надо, только в Меню все же перескакивают довольно резво и от быстрого одноразового нажатия. Может есть вариант прописки по KEY_REPEAT?


И еще одна вещь которая работает не так как надо -  FIRE_PRESSED - реагирует на #, а не на 5 или центральную клавишу джойстика. Пробовала через  FIRE и KEY_NUM5 -  javax.microedition.lcdui.Canvas, не то не другое не работает.
Может есть идеи на этот счет?

PM MAIL   Вверх
Dummy
Дата 2.6.2008, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Цитата

А решение-то простое! Надо сделать задержку в цикле. 


i_SweP, объясни, пожалуйста, что за проблема решается таким способом. Вообще, решения вида "задержки на магическое число миллисекунд" вряд ли могут являться исчерпывающими, т. к. их магические свойства имеют свойства пропадать при переходе на другую платформу, версию JVM и т. п.

Цитата

Так вот предложенный тобой вариант как я понимаю предполагает, что эти функции, и класса Игра, и Меню будут прописаны в главном классе Ядре, чтоб иметь возможность применить метод getKeyStates(). Или же прописывать GameCanvas в каждом классе. 
если я не так тебя поняла, поясни пожалуйста.


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

Дизайн, сделанный тобой, честно говоря, не слишком хороший и не слишком в Java-стиле даже для меня, не большого специалиста в области архитектурных решений и никакого специалиста в области игр.

Я бы как минимум сотворил для всех сцен: Menu, About и других - общий родительский абстрактный класс Scene с абстрактным методом Process, который бы каждый из них переопределил, как нужно. А Engine хранил бы одну ссылку на текущую сцену и просто вызывал бы Process(). Да и раз уж Engine по смыслу контроллер, то можно было бы отделить его от GameCanvas. Потом на основании того, что Process() текущей сцены возвращает, можно принимать решение в Engine о том, в какое состояние переходить дальше.

Я, например, так переписал - и получилось, что, вроде бы, и не надо лишний раз вызывать getKeyStates():

Код

public abstract class Scene {
     abstract int process(int keyStates);
     abstract void render(Graphics g);
}

public class Menu extends Scene() {
     int process(int keyStates) {
           
     }
}

public class Engine {
     private Scene currentScene;
     private int      currentState;

     void process()  {
          int ret = currentScene.process(canvas.getKeyStates());
                    
          // обрабатываем возвращаемое значение в зависимости от состояния
          // currentState, возможно, вызываем goToState()
     }

     private void goToState(int state) {
          Scene newScene = null;

          switch (state) {
               // здесь, если необходимо сменить сцену,
               // выставляем newScene в нужное значение
          }

          if (newScene != null) {
              currentScene = newScene;
              update();
          }
     }

     public void update() {
          if (currentScene == null) {
              return;
          }

          canvas.getKeyStates(); // обнуляем защелку
          currentScene.render(canvas.getGraphics());
          canvas.repaint();
     }
}


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

Цитата

И еще одна вещь которая работает не так как надо -  FIRE_PRESSED - реагирует на #, а не на 5 или центральную клавишу джойстика. Пробовала через  FIRE и KEY_NUM5 -  javax.microedition.lcdui.Canvas, не то не другое не работает.


Можно попробовать простенький тестик - переопределить в Canvas / GameCanvas keyPressed() и вывести для # код game action:

Код

protected void keyPressed(int keyCode) {
     System.out.println("key ' " + keyCode + " --> game action ' " +  getGameAction(keyCode) + " '");
}


Если клавише # действительно соответствует game action FIRE, то, видимо, остается только смириться - так вот на этой мотороле сделано. Если нет - дальше будем думать)))

Это сообщение отредактировал(а) Dummy - 2.6.2008, 22:29
PM MAIL   Вверх
i_SweP
Дата 3.6.2008, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 126
Регистрация: 23.6.2007

Репутация: нет
Всего: нет



Цитата(Dummy @  2.6.2008,  22:26 Найти цитируемый пост)
i_SweP, объясни, пожалуйста, что за проблема решается таким способом. Вообще, решения вида "задержки на магическое число миллисекунд" вряд ли могут являться исчерпывающими, т. к. их магические свойства имеют свойства пропадать при переходе на другую платформу, версию JVM и т. п.

А вот и сам удивляюсь магии. Хотя, конечно, это не универсальное решение.
Как я понял основная проблема тут:
Цитата(TigraZver @  31.5.2008,  20:07 Найти цитируемый пост)
 Но вот при тестировании на Motorole происходит двойное нажатие  - перескакивает ерез один. 

Если добавить паузу, результат весьма заметен
Не верите, запустите пример в атаче

И вот его код:
Код

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class MyGameCanvas extends GameCanvas implements Runnable
{
    private boolean continueFlag = true; // ну можно и без этого обойтись
    private Thread t;
//---------------------------------------------------------------------------------------
    public MyGameCanvas()
    {
        super(true);        
    }
//---------------------------------------------------------------------------------------
    public void start()
    {
        t = new Thread(this);
        t.start();
    }
//---------------------------------------------------------------------------------------
    public void run()
    {
        int key;
        int a = 0;
        Graphics g = this.getGraphics();        
        
        while(continueFlag)
        {
            g.setColor(0xFFFFFF);
            g.fillRect(0, 0, g.getClipWidth(), g.getClipHeight());
            
            key = getKeyStates();
            if((key & UP_PRESSED) != 0)    a++;
            if((key & DOWN_PRESSED) != 0)    a--;

            g.setColor(0);    // set black            
            g.drawString(Integer.toString(a), 50, 50, Graphics.TOP | Graphics.LEFT);            
            flushGraphics();
            
            try
            {
                t.sleep(150);
            }
            catch (InterruptedException ie)
            {
                ie.printStackTrace();
            };
        }
    }
}


Это сообщение отредактировал(а) i_SweP - 3.6.2008, 12:23

Присоединённый файл ( Кол-во скачиваний: 1 )
Присоединённый файл  GameCanvasTests.zip 4,25 Kb
PM MAIL   Вверх
Dummy
Дата 3.6.2008, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 21.5.2007

Репутация: 7
Всего: 19



Все, догнал, в чем дело. Спасибо, i_SweP, твой пример помог уяснить суть проблемы smile 

Я просто не очень внимательно прочитал спецификацию. А там написано, что getKeyStates() выставляет соответствующий бит с случае, если кнопка была нажата  хоть раз с момента последнего вызова getKeyStates() или нажата в настоящий момент.

Если внутри цикла, который ты описал, нет задержки в виде Thread.sleep() или явной отдачи управления планировщику потоков через Thread.yield(), то существует вероятность (которая в твоем случае реализуется постоянно), что при заходе на новую итерацию цикла событие о том, что соответствующая клавиша (например, FIRE) уже отжата, еще не успеет отработать, и соответствующий бит в защелке (FIRE_PRESSED) еще не будет сброшен, а успеет сброситься только, например, через итерацию или еще позже, в результате получится. Иными словами, в этом примере проявляется инерционность системы событий JVM (вполне ожидаемое и нормальное явление).

TigraZver,

Если ты еще не начала читать мой длинный пост от 2.6.2008, 22:26, то и не читай пока smile  Там, как выяснилось, не по делу немножко.

В твоем случае самым простым (хотя и далеко не универсальным) решением будет вставка Thread.sleep() на небольшой интервал или, вероятно, лучше - Thread.yield() после каждого getKeyStates().

Но вообще говоря, я бы рекомендовал следующее решение. Для тех случаев, когда нужна дискретность нажатий и инерция может приводить к багам (например, для случая перемещения по элементам меню вверх-вниз), использовать обработку keyPressed() / keyReleased(). Когда нужны "непрерывные", длительные нажатия и небольшая инерционность не является критичной (перемещение курсора или другого объекта по игровому полю) - можно использовать GameCanvas.getKeyStates().


PM MAIL   Вверх
TigraZver
Дата 3.6.2008, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 26.3.2008

Репутация: нет
Всего: нет



Цитата(Dummy @ 3.6.2008,  13:20)
Все, догнал, в чем дело. Спасибо, i_SweP, твой пример помог уяснить суть проблемы smile 
Если внутри цикла, который ты описал, нет задержки в виде Thread.sleep() или явной отдачи управления планировщику потоков через Thread.yield(), то существует вероятность (которая в твоем случае реализуется постоянно), что при заходе на новую итерацию цикла событие о том, что соответствующая клавиша (например, FIRE) уже отжата, еще не успеет отработать, и соответствующий бит в защелке (FIRE_PRESSED) еще не будет сброшен, а успеет сброситься только, например, через итерацию или еще позже, в результате получится. Иными словами, в этом примере проявляется инерционность системы событий JVM (вполне ожидаемое и нормальное явление).

TigraZver,

Если ты еще не начала читать мой длинный пост от 2.6.2008, 22:26, то и не читай пока smile  Там, как выяснилось, не по делу немножко.

Но вообще говоря, я бы рекомендовал следующее решение. Для тех случаев, когда нужна дискретность нажатий и инерция может приводить к багам (например, для случая перемещения по элементам меню вверх-вниз), использовать обработку keyPressed() / keyReleased(). Когда нужны "непрерывные", длительные нажатия и небольшая инерционность не является критичной (перемещение курсора или другого объекта по игровому полю) - можно использовать GameCanvas.getKeyStates().



Ну во первых, Dummy,  я успела прочитать твой предыдущий пост и считаю, что было весьма полезно. Тест на кнопки дал неоднозначный результат. На моторе при нажатии на
 # показывает - "key 35  --> gAct  0" , 
5 -- "key 53  --> gAct  8" , 
2 -- "key 50  --> gAct  1" , 
4 -- "key 52  --> gAct  2" , 
6 -- "key 54  --> gAct  5" , 
8 -- "key 56  --> gAct  6" , 
Fire на джойстике - "key 20  --> gAct  8" , 
Up на джойстике - "key -1  --> gAct  1" , 
Left на джойстике - "key -2   --> gAct  2" , 
Right на джойстике - "key -5  --> gAct  5" , 
Down на джойстике - "key -6 --> gAct  6" , 

при нажатии на # - стреляет, а при 5 или Fire - ничего не происходит.
может заменить по коду ?

теперь по поводу инерции:

Thread.sleep() - есть  :
Код

 public void run(){
        
        Graphics g = getGraphics();
        
        this.setFullScreenMode(true);
        
        while (looping)
            if (!paused)
            {
          
               Process(); 
               Draw(g);
               
               flushGraphics();
               
               try {Thread.sleep(RenderSpeed);}
               catch (InterruptedException ex) {ex.printStackTrace();}  
            }
        
         Midlet._instance.KillMidlet();
                     
         }
             
    } 


но использовать его в качестве решения мне не подходит , так как во время игры в классе Game будет тормозить мой Звездолет. А он то как раз летает так как надо. А вот в меню слишком быстро. Поэтому второй вариант про использование  keyPressed() / keyReleased() мне кажется  подойдет больше.

переделываю, позже напишу что получилось.

есть замечания,  предложения пишите.

п.с. И конечно Dummyi_SweP признательное мое мерси за терпение и помощь smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.1196 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.