Перемещение квадрата
Прежде чем мы начнем рассмотрение кода класса Draw, давайте подумаем, как можно произвести перемещение объекта на экране. Самый простейший способ перемещения объекта по экрану вдоль оси X, заключается в постоянном увеличении, допустим на единицу, позиции этого объекта по оси X. При создании квадрата методом fillRect () задаются две координаты по оси X и по оси Y для первоначального вывода квадрата на экран. Поэтому достаточно создать переменную для координаты по оси X и затем в цикле прорисовки увеличивать ее на единицу, перемещая тем самым объект по экрану.
В листинге 7.5 класс Draw наследуется от класса Canvas, что дает возможность воспользоваться Методом paint (). для рисования графических элементов на экране и. реализации метода run () интерфейса Runnable. В методе run () создается цикл, постоянно обновляющий состояние графических элементов.
В начале кода класса Draw создается переменная position, отвечающая за координату по оси X для точки вывода квадрата на экран. Конструктор класса Draw вызывает метод super () для использования конструктора своего суперкласса Canvas.
В методе start () создается системный поток, который будет запущен в методе run (). Кстати, было бы не плохо предусмотреть выход из потока. Этот пример небольшой и проблем с ним не возникнет, а после разбора листинга 7.5, мы рассмотрим простой механизм, останавливающий системный поток и предусматривающий выход из бесконечного цикла while метода run (). В самом методе run () создается бесконечный цикл, в котором происходит постоянное увеличение переменной position на единицу, благодаря чему квадрат перемещается по оси X слева направо.
В методе paint () вас должны заинтересовать следующие строки кода:
int х = g.getClipWidthf); int у = g.getClipHeight(); g.setColor(0xffffff); g.fillRect(0.0,x,y);
Здесь используется отсечение (clipping) необходимое для корректной прорисовки графики. Если не использовать отсечение, то после того как вы нарисуете квадрат и начнете передвигать его, на экране будет рисоваться слева на право одна толстая синяя линия. То есть будет происходить постоянная перерисовка квадрата в новой позиции по оси X, но при этом будет оставаться и предыдущий нарисованный квадрат. Чтобы этого избежать имеется два способа: можно стирать определенный участок экрана, а можно просто перерисовывать цвет фона всего экрана.
Такая операция в Java 2 ME называется отсечением, и для произведения этой операции используются методы: getClipWigth() и getClipHeight (), производящие отсечение поверхности всего экрана и методы getClipX () и getClipY () для более точного указания координат заданной области экрана для отсечения. По сути, использование этих методов приводит к простому обновлению всего экрана либо заданной области экрана. В этом примере мы будем использовать перерисовку всего фона экрана. Ширина и высота экрана узнается с помощью методов getClipWigth () и getClipHeight (), полученные значения сохраняются в переменных х и у. Вызовом метода setColor () устанавливается белый цвет фона и в следующей строке кода задается прямоугольник для области отсечения:
g.fillRect(0, 0, х, у);
В конце метода paint () рисуем синий квадрат:
g.fillRect(position, 40, 20, 20);
С каждым проходом через графический цикл, цвет фона будет перерисовываться и стирать прошлую позицию квадрата, а квадрат постоянно перерисовывается на новом месте в соответствии со значением переменной position, что и создает иллюзию передвижения объекта по экрану телефона.
После компиляции примера из листинга 7.5, на экране появится синий квадрат и пересечет один раз дисплей телефона слева направо. Теперь что касается бесконечного цикла while. В методе run () в реальном приложении необходимо предусмотреть выход из него, а так же позаботиться о прекращении работы потока. Самый простой способ заключается в создании переменной отвечающей за состояние цикла в начале класса Draw, например:
boolean z;
Дальше в методе start () присвоить этой переменной значение true.
public void start() { z = true; Thread t = new Thread(); t.start(); }
А в методе run () использовать значение переменной z для входа в цикл:
while while(z) { // код цикла }
Для логического конца создается новый метод stop () в классе Draw, назначая переменной z значения false.
public void stop() { z = false; }
Вызовем этот метод в классе Main в методе destroyApp ():
public void destroyApp(boolean unconditional) { z.stop (); }