| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Разработка Windows Forms > анимация с помощью Graphics |
| Автор: 4ybaka 21.5.2007, 21:13 |
| нужно выводить подряд неск битмапов,но само собой смещенных на какое то расстояние друг от друга.проблема в след-ем: при рисовалке след битмапа предидущий не стирается,а значит получаем размазанную картинку.нужно это както исправить. ЗУ: 1)функция рисования находится в отдельном файле,те не в классе формы. 2)тупая зарисовка фона не подходит - тогда не видно будет,что было за картинкой(она же не простой квадрат 3)каждый раз вызывать Paint для формы не подходит - оч много объектов. |
| Автор: archeg 22.5.2007, 00:14 |
| Рисовать все в Bitmap, а потом выводить на форму. Можно организовать несколько Bitmap`ов - в виде буфферa. Например перед отрисовкой картинки во второй Bitmap, копировать содержимое в первый а потом рисовать картинку. Таким образом мы получаем первый Bitmap, в котором нарисовано все, кроме картинки. И благодаря ему можно сделать "откат" на состояние без картинки и нарисовать уже новую, смещенную.... Если я правльно понял, что нужно |
| Автор: tol05 22.5.2007, 09:06 |
| archeg, в буфере хранить не надо. Ты же видишь, К тому же, при каждом новом битмапе, как я понял, старые нужно не прорисовывать, а стирать. 4ybaka, ты при рисовании битмапов запоминай где-нибудь их Rectangle (по отношению к контролу, на котором рисуешь), а потом, в нужный момент вызывай Control.Invalidate (Rectangle). |
| Автор: Ch0bits 22.5.2007, 12:59 |
| Это называется спрайтовая анимация. Есть полно готовых движков на codeproject.com |
| Автор: 4ybaka 26.5.2007, 23:18 |
| tol05, Control.Invalidate (Rectangle) просто добавляет к области обновления данный квадрат,а само обновление происходит когда получится?а Update() это делает сразу?и нужно ли блокировать форму при многопоточном вызове Control.Invalidate (Rectangle)?и вообще,какие методы можно вызывать без блокировки(при многопоточном вызовах)?...... |
| Автор: tol05 27.5.2007, 15:44 |
| Контролы позволяют с собой работать только в основном потоке, в котором они созданы. Это уже много раз обсуждалось... и все равно продолжает обсуждаться Так что в многопоточном формате у тебя просто не получиться вызвать хоть какой-нибудь член класса формы. Нужно через Invoke(). И поскольку вся работа с формой будет производиться в создающем ее потоке, ничего блокировать тебе не прийдется. Сколько бы потоков не просило бы форсу перерисоваться, эти запросы будут накапливаться в очереди запросов потока формы, а она будет их обрабатывать по мере своих возможностей, последовательно. Методы: Invalidate, Refresh, Update. Почитай о них в MSDN, чесное слово, там нормально написано. Я указал Invalidate просто потому что я им привык еще с плюсов пользоваться. И использую его почти всегда без Update. Некоторые уважают Refresh, все это - дело вкуса и конкретной задачи, ИМХО. |
| Автор: mr.DUDA 27.5.2007, 15:54 | ||||||
В обработчике события Paint или перекрытом методе OnPaint. Не сразу, а ставит в очередь виндошных сообщений. Сразу перерисовывает Refresh, но перерисовывает всё.
Для вызова перерисовки из другого потока надо вызывать метод Refresh или Update не напрямую а через Invoke:
|
| Автор: 4ybaka 27.5.2007, 22:08 | ||||||
я вот вызывал Invalidate из другого потока,а он нормально,ничего не ругался,даже вроде работает...
это как объяснить? |
| Автор: tol05 28.5.2007, 09:09 | ||||
| Бдительность проверяешь? Ну а объясняется просто: Invalidate отправляет форме только сообщение с просьбой, когда будет возможно, перерисовать (если не трудно) А Refresh и Update - методы прямого действия, и
Вот тебе тест. Попробуй раскоментировать любой из методов (одного достаточно) и получишь эксепшен.
|
| Автор: 4ybaka 28.5.2007, 20:16 | ||
а то! вот еще один вопрос возник:при перерисовке области окна у нас перерисовываются только контролы,входящие в область перерисовки(если не ошибаюсь).а если на форме на фоне рисуется битмап,то он же не перерисовывается?(только если надо всю форму перерисовать,а это долго...)так вот как можно сделать так,чтобы перерисовывалась и та часть битмапа,кот входит в указанную область? |
| Автор: tol05 28.5.2007, 22:09 | ||
Что за сложности на ровном месте? 4ybaka, попрактикуйся ты с функциями, параметрами, чем терять время на сомнения и предположения. Кому ты даешь задание перерисоваться? Форме или конкретному контролу? Форма - это тоже Control, так что для нее также действует Control.Invalidate(Rectangle), она перерисовывается сама и дает коменду перерисоваться контролам, это уже их головняк. Rectangle - это область, которую ты объявляешь недействительной. Вот ты свернул форму в трей - вся область недействительна, перекрыл ее (сбоку наполовину) другим окном - значит та половина недействительна. И контролы на ней перерисуются не все, а только те, что в инвалид-область попали... Но это поведение сама форма себе обеспечивает. А в твоей ситуации форму никто не трогает, никто не сворачивает, не перекрывает, она себе и спит спокойно. А ты Control.Invalidate(Rectangle) сообщаешь ей:"Эй, тебя перекрыли на 20%, давай перерисовывайся". И еще важный момент. Ты рисуешь в OnPaint. Контролы на форме сами должны прорисоваться, а ты еще два матюка ручками нарисовать хочешь. Матюки ты написать сумеешь (я почему-то в этом не сомневаюсь Некоторые на это дело забивают, потом долго жалуются по непонятным траблам... |
| Автор: 4ybaka 28.5.2007, 22:56 | ||||
форме.
просто добавляешь свой контрол(юзер или какой там нашел) в список контролов формы как: this.Controls.Add(),и все,дальше они сами пусть себя рисуют,только вот ворос то в другом был |