Программирование мобильных телефонов на Java



8.7. Обработка событий с клавиш телефона



В профиле MIDP 2.0 предусмотрена улучшенная обработка событий получаемых с клавиш телефона. Используя метод getKeyState () можно определять состояние клавиш телефона и действовать адекватным образом. 'В демонстрационном примере к этому разделу мы выведем на экран мячик, созданный при помощи класса MySprite являющимся подклассом класса Sprite. В листинге 8.2 представлен код примера, в котором на экране рисуется синий мяч, а с помощью клавиш телефона Up, Down, Left и Right этот мяч можно передвигать по экрану. Листинг 8.2 состоит из трех классов: MainGame. MyGameCanvas и MySprite, расположенных в трех разных файлах MainGame.java, MyGameCanvas.java и MySprite.java.

/**
Листинг 8.2 класс MainGame
*/
import javax.microedition.Icdui.*;
import javax.microedition.midlet.*;
public class MainGame extends MIDlet implements
CommandListener
{
// команда выхода
private Command exitMidlet = new Command("Выход",
Command.EXIT, 0);
// объект класса MyGameCanvas
private MyGameCanvas mr;
public void startApp()
{
// обрабатываем исключительную ситуацию
 try
{
// инициализируем объект класса
MyGameCanvas mr = new MyGameCanvas();
// запускаем поток mr.start();
// добавляем команду выхода
mr.addCommand(exitMidlet);
mr.setCommandLis'tener (this) ;
// отражаем текущий дисплей
Display.getDisplay(this).setCurrent(mr);
}
catch (Java.io.lOException zxz) {} ;
}
public void pauseApp() {}
public void destroyApp(boolean unconditional)
{
// останавливаем поток
if(mr != null) mr.stopt);
 }
public void commandAction (Command c, Displayable d;)
 {
if (с == exitMidlet)
{
destroyApp(false); notifyDestroyed();
}
}
}
/**
файл MyGameCanvas.Java класс MyGameCanvas
 */
import java.io.*;
import javax.microedition.Icdui.*;
import javax.microedition. Icdui .game .*;
public class MyGameCanvas extends GameCanvas implements
Runnable
{
// создаем объект класса MySprite
private MySprite bol;
// создаем объект класса Lay'erManager
private LayerManager lm;
// логическая переменная
boolean z;
public MyGameCanvas() throws IOException
{
// обращаемся к конструктору суперкласса Canvas
super(true);
// загружаем изображение
Image im = Image.createlmage("/bol.png");
// инициализируем объект bol
bol = new MySprite (itn, 23, 23);
// выбираем позицию в центре экрана
bol.setPosition(getWidth()/2, getHeight()/2);
// инициализируем менеджер уровней
1m = new LayerManager();
// добавляем объект bol к уровню
lm.append(bol); }
public void start()
{
z = true;
// создаем и запускаем поток
Thread t = new Thread(this);
t.start();
 }
// останавливаем поток
 public void stop()
{ z = false;
}
public void run()
{
// получаем графический контекст
Graphic's g = getGraphics () ;
while (z)
{
// обрабатываем события с клавиш телефона
 inputKey();
// рисуем графические элементы init(g);
// останавливаем цикл на 20 миллисекунд
 try { Thread.sleep(20);
}
catch (Java.lang.InterruptedException zxz) {};
 }
 }
private void inputKey()
{
// определяем нажатую клавишу
int keyStates = getKeyStates();
// код обработки для левой нажатой клавиши
-if ((keyStates & LEFT_PRESSED) != 0) bol.moveLeft();
// код обработки для правой нажатой клавиши
if ((keyStates & RIGHT_PRESSED) != 0) bol.moveRight();
// код обработки для клавиши вверх
if ((keyStates & UP_PRESSED) != 0) bol.moveUp();
// код обработки для клавиши вниз
if ((keyStates & DOWN_PRESSED) != 0) bol.moveDown();
}
private void init(Graphics g)
{
// белый цвет фона g.setColor(0xffffff);
// перерисовываем экран
g.fillRect (0 , 0, getWi.dth () , getHeight());
// рисем уровень в точке 0,0
lm.paint(g, 0, 0) ;
// двойная буферезация
flushGraphics();
};
}
/**
файл MySprite.Java
класс MySprite
*/
import javax.microedition.Icdui.*;
 import javax.microedition.Icdui.game.*;
public class MySprite extends Sprite
{
// конструктор
public MySprite(Image image, int fw, int fh)
{
// обращаемся к конструктору суперкласса
super (image, fw, fh);
}
// метод для клавиши Left public void moveLeft() ;
 {
// передвигаем спрайт
move(-1,0);
}
// метод для клавиши Right public void moveRight()
{
/ / передвигаем спрайт
move(1,0);
}
// метод для клавиши Up public void moveUp()
{
// передвигаем спрайт
move(0,-1);
}
// метод для клавиши Down public void moveDown()
{
// передвигаем спрайт
move(0,1);
'}
 }


В файле MySprite.java находится класс MySprite, с которого и начнем рассмотрение листинга. Конструктор класса MySprite обращается к конструктору своего суперкласса Sprite!

super(image, fw, fh);


Этот конструктор имеет три параметра - это исходное изображение спрайта, ширина и высота фрейма. Спрайт, как вы помните, может иметь анимационную последовательность, поэтому необходимо точно знать ширину и высоту одного фрейма, при обязательном условии, что все фреймы спрайта должны быть одного размера. В этом примере мы не используем анимационной последовательности, и можно было обойтись и более простым конструктором суперкласса Sprite.

Для передвижения спрайта по экрану телефона созданы методы moveLef t (), moveRight (), moveUp () и moveDowri (), в основу которых положены вызовы метода move (). Метод move () имеет два параметра - это координаты по осям X и Y. Задавая необходимое смещение на 1, 2, 3 и более пикселей по одной из осей, вы будете производить движение объекта по экрану.

Класс MyGameCanvas работает по схеме, использованной в разделе 8.6, с той лишь разницей, что вместо фонового изображения загружается спрайт в виде мячика. В конструкторе класса MyGameCanvas происходит загрузка исходного изображения bol.png, это и есть наш мячик или спрайт. Спрайт размером 23x23 пикселя. При создании объекта bol класса MySprite

bol = new MySprite(im, 23, 23)


используется изображение bol.png, затем, в конструкторе класса MyGameCanvas происходит выбор позиции для первоначальной отрисовки спрайта на экране с помощью метода setPosition (). Мячик рисуется в центре экрана и добавляется методом append () к уровню.

В методе run () в игровом цикле происходит вызов двух методов. Метод init () производит рисование всех графических элементов с помощью менеджера уровней, а метод input Key () осуществляет обработку нажатий клавиш телефона.

private void inputKey()
{
int keyStates = getKeyStates();
if ((keyStates & LEFT_PRESSED) != 0) bol.moveLeft();
if ((keyStates & RIGHT_PRESSED) !=0) bol.moveRight();
if ((keyStates & UP_PRESSED) != 0) bol.moveUp();
if ((keyStates & DOWN_PRESSED) != 0) bol.moveDown ();
}


В методе inputKey () происходит определение нажатой клавиши посредством метода getKeyState (). Весь остальной код в методе inputKey () использует оператор if для обработки нажатых клавши, вызывая соответствующие методы moveLeftO, moveRight (), moveUp ()или moveDown () для перемещения объекта по экрану.

В классе MainGame из файла MainGame.java создается объект класса MyGameCanvas, запускается системный поток и отражается текущий экран.

В этом примере использовался спрайт файла ресурса bol.png состоящий из одного фрейма размером 23x23 пикселя. В следующем разделе мы рассмотрим технику анимации спрайтов в играх, и будем исполВзовать спрайт, состоящий уже из нескольких фреймов.

Назад Начало Вперед