![]() |
Разрывы в рисование с помощью Bitmap
Здравствуйте.
Передо мной была поставлена задача сделать «рисовалку» на AS3. По нескольким причинам я решил делать программное рисование не через graphic.lineTo, а через BtimapData и draw. Основными причинами к этому были: 1) Нестандартные «кисти» с размытыми краями. 2) Возможность «стирать» нарисованное. За саму часть рисования у меня отвечает следующий код: Код AS3:
Код AS3:
А блок с: Код AS3:
Код AS3:
instrumentBlendMode — бывает BlendMode.NORMAL и BlendMode.ERASE, что позволяет либо рисовать, либо стирать нарисованное. Но это всё было отступлением, проблема заключается в том, что если быстро вести мышкой при зажатой кнопке, то линия получается обрывистой, что видно на следующем скриншоте: http://flashist.ru/files/azat/school...screenshot.jpg На картинке, быстрее всего была проведена верхняя линия, две линии ниже идут по уменьшению скорости. Вот и вопрос, есть ли способ с этим как-то бороться, или же стоит смотреть в сторону graphic.lineTo и можно ли там (graphioc.lineTo) как-то добиться размытости кистей? Как всё работает «в живую» можно посмотреть тут (65кб, прелодера нет): http://flashist.ru/files/azat/school/index.html P.S.: updateAfterEvent() пробовал, не помогло. Может быть я как-то не так пробовал? Так же пробовал, при нажатии на кнопку мыши, запускать таймер который бы вызывался 200 раз в секунду и рисовал Btimap, а при отпускании кнопки мышки таймер бы приостанавливался. Тоже не помогло. Может быть опять как-то не так пробовал? UPD.: Изменять количество FPS до максимальных 120 тоже пробовал, тоже не помогло =( |
Тут все просто - MOUSE_MOVE срабатывает аналогично ENTER_FRAME - тобишь каждый кадр. Из-за этого отрисовка потворяется <кол-во кадров в секунду> раз в секунду и наблюдаются разрывы. В Вашем случае необходимо будет воспользоваться идеологией метода lineTo/moveTo - Т.е. вам придется написать функцию подобно lineTo, только с Вашими потребностями (метод Draw(), размытые кисти и т.п.).
|
Сейчас обновил пост, написал о том, что пробовал увеличивать до максимального количество FPS, но это тоже не помогло.
Цитата:
Просто я тоже думал о таком принципе, но мне кажется, что должно быть более изящное решение проблемы. |
Я Вас прекрасно понял, Вы совершенно правы: кликаем на холст - запоминаем точку - двигаем мышь - рисуем линию от запомненной точки до текущего положения мыши. Отрисовку "от точки до точки" делать с помощью цикла. Это один из вариантов решения проблемы. Тут так же можно использовать кривые безье для сглаживания линий, но это чуть сложнее.
Второе что пришло мне в голову - рисовать изначально через lineTo/moveTo с примененным фильтром blur (или glow), а при MOUSE_UP отрисовывать через draw() на холсте. |
Спасибо за советы, но это всё как-то через «жопу», хотелось бы более изящного и простого решения (что-то типо lineTo для Bitmap).
Посмотрим, может кто-то из других форумчан подскажет такое более «изящное» решение. |
Ну насчет более изящного решения - вместо отрисовки в событии MOUSE_MOVE, создаем таймер и рисуем в событии TimerEvent.TIMER. Тем самым мы можем указать интервал таймера вплоть до миллисекунды, что сократит разрывы.
|
Я пробовал и этот вариант, к сожалению, он тоже не дал желаемых результатов =(
Скорее всего, остановлюсь на циклах «дорисовки», просто хотелось бы узнать мнения у чуть большего количества людей, все ли считают, что больше подходящих решений нет. Спасибо вам ещё раз, за то, что пытаетесь мне помочь советом =) |
это не через жопу, это именно правильный вариант. Если бы у вас был планшет, то вы бы знали, что если быстро вести кривую линию на планшете, то она получается ломанной, а не гладкой именно по причине работы того самого алгоритма. Если хотите заморочиться, то можете запрограммировать, чтобы алгоритм сглаживал быструю линию пользуясь информациях о предыдущих поставленных точках.
Да, кстати, не забывает event.updateAfterEvent() в слушателе. |
при быстром движении курсор мышки начинает "прыгать" поэтому он пропускает промежутки. Проверить это можно так: нарисуйте круг (рад: 30 пикс), его в символ и эвент слушатель на Маус_Овер и соответственно Трейс("что-то") чтобы узнать был ли маус_овер, и быстро проведите мышкой над обьектом, вы увидете что иногда даже если мышка проходит над обьектом Трейс не работает.
Поэтому я тоже считаю lineTo это правильный вариант. |
Все серьезные графические программы используют интерполяцию промежуточных точек при движении курсора. Имейте так же в виду что операция draw очень дорогая, поэтому одно ее выполнение притормаживат всю систему, а значит и отслеживание системой позиции курсора, таким образом линия движения мыши получается ломаной в любом случае. Сделайте простой эксперимент
Код AS3:
Выход для вас либо использовать lineTo на клипе с фильтром блюр (самый простой выход для размытия линий, самый примитивный) - либо использовать быстрые операции с растром copyPixels, либо более медленные draw c интерполяцией промежуточных точек - ищите литературу как это делать, на этом форуме я когда то уже обсуждал эту тему. Говорю это как человек, съевший на рисовалках собаку, кошку, корову и лошадь со сбруей. |
| Часовой пояс GMT +4, время: 22:21. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.