2.11.2013 / 00:02 | |
Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| Такая проблема: методы keyPressed и keyReleased устанавливают флаг, а в отдельном треде уже в зависимости от кнопки просчитываются новые координаты и вызывается repaint(). public void keyRepeated(int keyCodeNew) {
keyCode = keyCodeNew;
oneClick = false;
pressedMove = true;
}
public void keyReleased(int keyCode) {
pressedMove = false;
}
public void run() {
while (running) {
if (pressedMove) {
if (keyCode == KEY_NUM4) {
mapX = mapX <= 0 ? 0 : mapX - 1;
updateGraphics();
} else if (keyCode == KEY_NUM2) {
mapY = mapY <= 0 ? 0 : mapY - 1;
updateGraphics();
} else if (keyCode == KEY_NUM6) {
mapX = mapX >= w ? w : mapX + 1;
updateGraphics();
} else if (keyCode == KEY_NUM8) {
mapY = mapY >= h ? h : mapY + 1;
updateGraphics();
}
if (oneClick) {
pressedMove = false;
}
// от закоментированной задержки зависит синхронизация этого треда и отрисовки
// не подходит, потому что задержку нужно подбирать под каждый телефон..
//try {
// Thread.sleep(1);
//} catch (InterruptedException ex) {}
} else {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {}
}
}
}
private void updateGraphics() {
curX = getXOnScreen(mapX);
curY = getYOnScreen(mapY);
repaint();
}
Проблема в том, что paint(Graphics g) выполняется намного дольше чем просчет новых координат, поэтому пока отрисуется один кадр, уже просчитаны координаты далеко вперед и следующий кадр «перескакивает». Пробовал в методе paint сделать synchronized блок на переменную pressedMove - ничего не изменилось. Делал synchronized paint(...) тоже самое.. Получилось только через еще один флаг paintInProgress. Как сделать синхронизацию через synchronized блок или метод? |
2.11.2013 / 00:10 | |
aNNiMON Супервизор Сейчас: Offline
Имя: Витёк Регистрация: 11.01.2010
| Naik, а почему ты synchronized в paint ставишь? Ты же переменные в keyPressed и keyReleased изменяешь, вот там и пробуй. А, и в run надо, там тоже изменяется переменная. Не совсем понял, архитектуру данного решения. Почему переменные устанавливаются в keyPressed, влияют на paint, а проверяются вообще в отдельном потоке?
__________________
let live Изменено aNNiMON (2.11 / 00:12) (всего 1 раз) |
2.11.2013 / 06:11 | |
gost6678 Пользователь
| Naik, попробывал уменьшить размер сохраняемой картинки- сохранило нормально! Спасибо.
|
2.11.2013 / 06:14 | |
gost6678 Пользователь
| Naik, вот пример синхронизированного метода: synchronized void method1(){ }
Изменено gost6678 (2.11 / 06:14) (всего 1 раз) |
2.11.2013 / 12:56 | |
Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| aNNiMON, в keyPressed устанавливается код кнопки полю класса и вспомог. переменные. Нажатие обрабатывается в отдельном треде чтобы облегчить методы keyPressed, keyReleased. Получается в главный поток занят только отрисовкой, а в другом производятся все вычисления. Вот здесь советуют писать как можно более быстровыполняемые методы, которые вызываются системой (keyPressed, etc) — http://www.mobilab.ru/articles/4/ |
2.11.2013 / 13:17 | |
vl@volk Пользователь Сейчас: Offline
Имя: Владислав Откуда: Земля Регистрация: 26.12.2012
| Naik, там какая-то беда с системными вызовами. поставил небольшой сон в методе paint, мидлет поспал и потом вывел всё сразу, хотя должно было вылезти по очереди. надо поманипулировать с вызовами системнымных методов, тесты погонять.
__________________
знает толк |
2.11.2013 / 13:27 | |
Naik Пользователь Сейчас: Offline
Имя: %name% Регистрация: 14.03.2010
| Короче сделал без всяких synchronized. Синхронизирую вручную с пом. paintInProcess: Открыть спойлер Закрыть спойлер public void paint(Graphics g) {
mapHolder.draw(g, mapX - curX, mapY - curY);
g.drawImage(cursor, curX - 7, curY - 7, Graphics.LEFT | Graphics.TOP);
paintInProcess = false;
}
public void keyPressed(int keyCodeNew) {
keyCode = keyCodeNew;
oneClick = true;
pressedMove = true;
}
public void keyRepeated(int keyCodeNew) {
keyCode = keyCodeNew;
oneClick = false;
pressedMove = true;
}
public void keyReleased(int keyCode) {
pressedMove = false;
}
public void run() {
while (running) {
if (pressedMove && !paintInProcess) {
if (keyCode == KEY_NUM4) {
mapX = mapX <= 0 ? 0 : mapX - 1;
updateGraphics();
} else if (keyCode == KEY_NUM2) {
mapY = mapY <= 0 ? 0 : mapY - 1;
updateGraphics();
} else if (keyCode == KEY_NUM6) {
mapX = mapX >= w ? w : mapX + 1;
updateGraphics();
} else if (keyCode == KEY_NUM8) {
mapY = mapY >= h ? h : mapY + 1;
updateGraphics();
}
if (oneClick) {
pressedMove = false;
}
} else {
try {
Thread.sleep(1);
} catch (InterruptedException ex) {}
}
}
}
private void updateGraphics() {
curX = getXOnScreen(mapX);
curY = getYOnScreen(mapY);
paintInProcess = true;
repaint();
}
Теперь как и нужно на каждое изменение координат приходится одно выполнение paint. |
2.11.2013 / 15:27 | |
Nokia_372Oc Пользователь
| Соберите плиз!
Прикрепленные файлы: src.zip (1.42 кб.) Скачано 17 раз |
2.11.2013 / 18:27 | |
gost6678 Пользователь
| Nokia_372Oc, собрал, только исправил неправильный доступ к переменной ln из главного класса на такой: Main.m.ln
Прикрепленные файлы: Main.jar (2.73 кб.) Скачано 118 раз |