![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
|
Здравствуйте.
Передо мной была поставлена задача сделать «рисовалку» на AS3. По нескольким причинам я решил делать программное рисование не через graphic.lineTo, а через BtimapData и draw. Основными причинами к этому были: 1) Нестандартные «кисти» с размытыми краями. 2) Возможность «стирать» нарисованное. За саму часть рисования у меня отвечает следующий код: function onMouseMove(event:MouseEvent) { if (this.instrument_mc) { this.instrument_mc.x = Main.stage.mouseX; this.instrument_mc.y = Main.stage.mouseY; // if (event.buttonDown) { this.toDraw(); } } } function onMouseDown(event:MouseEvent) { this.toDraw(); } Проверяет наличие инструмента для рисования «в руке». А блок с: Проверяет нажата ли кнопка мышки. Если все условия выполняются, то запускается функция toDraw(), в которой и реализован механизм рисования. Механизм примерно такой: this.matrix.tx = toX; this.matrix.ty = toY; this.bitmap.draw(_mc, this.matrix, this.colorTransform, instrumentBlendMode); instrumentBlendMode — бывает BlendMode.NORMAL и BlendMode.ERASE, что позволяет либо рисовать, либо стирать нарисованное. Но это всё было отступлением, проблема заключается в том, что если быстро вести мышкой при зажатой кнопке, то линия получается обрывистой, что видно на следующем скриншоте: ![]() На картинке, быстрее всего была проведена верхняя линия, две линии ниже идут по уменьшению скорости. Вот и вопрос, есть ли способ с этим как-то бороться, или же стоит смотреть в сторону graphic.lineTo и можно ли там (graphioc.lineTo) как-то добиться размытости кистей? Как всё работает «в живую» можно посмотреть тут (65кб, прелодера нет): http://flashist.ru/files/azat/school/index.html P.S.: updateAfterEvent() пробовал, не помогло. Может быть я как-то не так пробовал? Так же пробовал, при нажатии на кнопку мыши, запускать таймер который бы вызывался 200 раз в секунду и рисовал Btimap, а при отпускании кнопки мышки таймер бы приостанавливался. Тоже не помогло. Может быть опять как-то не так пробовал? UPD.: Изменять количество FPS до максимальных 120 тоже пробовал, тоже не помогло =( Последний раз редактировалось koIIImarik; 16.03.2009 в 02:38. |
|
|||||
|
Тут все просто - MOUSE_MOVE срабатывает аналогично ENTER_FRAME - тобишь каждый кадр. Из-за этого отрисовка потворяется <кол-во кадров в секунду> раз в секунду и наблюдаются разрывы. В Вашем случае необходимо будет воспользоваться идеологией метода lineTo/moveTo - Т.е. вам придется написать функцию подобно lineTo, только с Вашими потребностями (метод Draw(), размытые кисти и т.п.).
Последний раз редактировалось serenkiy; 16.03.2009 в 00:13. |
|
|||||
|
Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
|
Сейчас обновил пост, написал о том, что пробовал увеличивать до максимального количество FPS, но это тоже не помогло.
Цитата:
Просто я тоже думал о таком принципе, но мне кажется, что должно быть более изящное решение проблемы. |
|
|||||
|
Я Вас прекрасно понял, Вы совершенно правы: кликаем на холст - запоминаем точку - двигаем мышь - рисуем линию от запомненной точки до текущего положения мыши. Отрисовку "от точки до точки" делать с помощью цикла. Это один из вариантов решения проблемы. Тут так же можно использовать кривые безье для сглаживания линий, но это чуть сложнее.
Второе что пришло мне в голову - рисовать изначально через lineTo/moveTo с примененным фильтром blur (или glow), а при MOUSE_UP отрисовывать через draw() на холсте. |
|
|||||
|
Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
|
Спасибо за советы, но это всё как-то через «жопу», хотелось бы более изящного и простого решения (что-то типо lineTo для Bitmap).
Посмотрим, может кто-то из других форумчан подскажет такое более «изящное» решение. |
|
|||||
|
Ну насчет более изящного решения - вместо отрисовки в событии MOUSE_MOVE, создаем таймер и рисуем в событии TimerEvent.TIMER. Тем самым мы можем указать интервал таймера вплоть до миллисекунды, что сократит разрывы.
|
|
|||||
|
Регистрация: Jul 2007
Адрес: Россия, Москва
Сообщений: 522
|
Я пробовал и этот вариант, к сожалению, он тоже не дал желаемых результатов =(
Скорее всего, остановлюсь на циклах «дорисовки», просто хотелось бы узнать мнения у чуть большего количества людей, все ли считают, что больше подходящих решений нет. Спасибо вам ещё раз, за то, что пытаетесь мне помочь советом =) |
|
|||||
|
Регистрация: Jan 2009
Сообщений: 1,651
|
это не через жопу, это именно правильный вариант. Если бы у вас был планшет, то вы бы знали, что если быстро вести кривую линию на планшете, то она получается ломанной, а не гладкой именно по причине работы того самого алгоритма. Если хотите заморочиться, то можете запрограммировать, чтобы алгоритм сглаживал быструю линию пользуясь информациях о предыдущих поставленных точках.
Да, кстати, не забывает event.updateAfterEvent() в слушателе. |
|
|||||
|
[+4 14.03.09]
|
при быстром движении курсор мышки начинает "прыгать" поэтому он пропускает промежутки. Проверить это можно так: нарисуйте круг (рад: 30 пикс), его в символ и эвент слушатель на Маус_Овер и соответственно Трейс("что-то") чтобы узнать был ли маус_овер, и быстро проведите мышкой над обьектом, вы увидете что иногда даже если мышка проходит над обьектом Трейс не работает.
Поэтому я тоже считаю lineTo это правильный вариант. |
|
|||||
|
Регистрация: Nov 2005
Сообщений: 1,155
|
Все серьезные графические программы используют интерполяцию промежуточных точек при движении курсора. Имейте так же в виду что операция draw очень дорогая, поэтому одно ее выполнение притормаживат всю систему, а значит и отслеживание системой позиции курсора, таким образом линия движения мыши получается ломаной в любом случае. Сделайте простой эксперимент
Как видите, соседние координаты даже при безобидном умеренном движении мыши расположены далеко друг от друга, это без прорисовки. Выход для вас либо использовать lineTo на клипе с фильтром блюр (самый простой выход для размытия линий, самый примитивный) - либо использовать быстрые операции с растром copyPixels, либо более медленные draw c интерполяцией промежуточных точек - ищите литературу как это делать, на этом форуме я когда то уже обсуждал эту тему. Говорю это как человек, съевший на рисовалках собаку, кошку, корову и лошадь со сбруей. |
![]() |
![]() |
Часовой пояс GMT +4, время: 22:10. |
|
|
« Предыдущая тема | Следующая тема » |
| Теги |
| bitmap , рисование |
|
|