![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
Enteropoly |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 17.6.2009 Репутация: нет Всего: нет |
Привет всем.
У меня такое дело. Я пишу что-то типа стратегической игры на C#, использую только GDI+. Итак, тайлы (клеточки на игровом поле) у меня имеют форму шестиугольника, с отрисовкой всей этой сетки всё нормально. Проблемы начинаются при перерисовке. По задумке, у меня "подсвечивается" только тот тайл, над которым находится курсор мыши. Для этого бы создан массив эти клеточек, написаны методы, с технической стороны проблем, в общем, нету. Всё работает как надо. НО! Перерисовка весит на MouseMove, поэтому получается, что с каждым движением у меня перерисовывается всё поле размером в, скажем, 1000х1000 клеток, посему, как результат, под 100% грузится процессор, что, как понятно, недопустимо. Так вот, мне нужно перерисовывать только видимую часть поля, ту, что видно на форме, а ту, что за кадром, оставить как есть до тех пор, пока она не станет видимой. Копал Invalidate, ничего путного не нашёл. Кто что может посоветовать? ЗЫ. Метод поиска нужной клетки для подсвечивания, по координатам, работает максимально быстро (по бинарному дереву), поиск по полю 32000х32000 проходит за 6-7 итераций. Грешу на перерисовку. ----------- Едит: Повесил перерисовку на таймер, но всё равно тормозит жутко. Слишком много перерисовывается всего. Это сообщение отредактировал(а) Enteropoly - 17.6.2009, 18:31 |
|||
|
||||
Heinzz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 381 Регистрация: 12.12.2008 Где: .net Репутация: 3 Всего: 9 |
Если каждый шестиугольничек является объектом, можно добавить ему метод
"перерисоваться" если содержит курсор мыши координаты мыши на всем поле вычислить проблем быть не должно |
|||
|
||||
Grok |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 123 Регистрация: 17.12.2007 Репутация: нет Всего: нет |
а почему Invalidate() не подходит?
Передавать туда прямоугольник который нужно перерисовать и должно работать нормально .... |
|||
|
||||
Enteropoly |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 17.6.2009 Репутация: нет Всего: нет |
Тут суть в том, что перерисовывать всё равно нужно все клетки, а ту, над которой курсор, просто по-другому =) |
|||
|
||||
Enteropoly |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 17.6.2009 Репутация: нет Всего: нет |
Воть.
Вот как-то так. Ладно, я тут пыхнул, и понял, что суть не в Invalidate. Просто надо разработать какой-то критерий, по которому определялось бы, надо перерисовывать клетку, или нет. В общем, будем искать. ![]() Это сообщение отредактировал(а) Enteropoly - 17.6.2009, 20:19 |
|||
|
||||
amarenkov |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 183 Регистрация: 21.2.2008 Где: Воронеж Репутация: нет Всего: нет |
Enteropoly, есть несколько вопросов и несколько советов
![]() Вопросы: 1. Я так понял, у тебя не все поле сразу видно, а 100-200 клеток? А каким образом это у тебя реализуется? Есть какие-то координатные преобразования? Или ты Image по форме двигаешь ![]() 2. Проекция у тебя изометрическая или чисто 2D? Другими словами, у тебя есть части, вылезающие за клетку? Советы: 1. Делай сразу на XNA, Tao или чистом DirectX, OpenGL - много сил сэкономишь ![]() 2. Перерисовывать надо не на MouseMove, а при изменении состояния, т.е. когда меняется подсвечиваемя клетка. Надо помнить на какой были и при движении мыши проверять, изменилась ли она. Если да - перерисовать. 3. Рисовать сначала стоит на Bitmap, который находится в памяти. Потом весь Bitmap рисовать на Image, а не сразу на Graphics'e Image-а. |
|||
|
||||
Enteropoly |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 17.6.2009 Репутация: нет Всего: нет |
1. 1 клетка = 1 экземпляр класса Tile. В классе реализован метод отрисовки. Всё прям напрямую через Graphics.Draw...... 2. Чисто 2D. 1. С XNA знаком, но в целях как бы... ммм... повышения уровня квалификации именно в традиционном C#, хочется написать на GDI+ ![]() 2. Щас уже перерисовывается по таймеру. Я как бы отвязал перерисовку от каких-то действий. Картинка меняется назависимо от происходящего, как лента в проекторе крутится постоянно, вне зависимости от того, что на ней нарисовано. А вот что на ней будет нарисовано (какие клетки надо перерисовать и как) - это у меня уже выполняет другая функция, которая как раз привязана к разным кликам, мувам и прочим событиям. Работает на ура. 3. А вот тут надо подумать =) Я ещё функцию скролла карты не реализовал и до сих пор предвкушаю долгие часы неиллюзорного секса с TranslateTransform и прочими радостями ![]() |
|||
|
||||
gambit |
|
|||
![]() Эксперт ![]() ![]() ![]() Награды: 1 Профиль Группа: Комодератор Сообщений: 1359 Регистрация: 25.6.2006 Где: я? Репутация: 3 Всего: 40 |
Может конечно не поможет, но что если использовать двойную буферизацию??? Он тогда вроде как тогда использует особый метод отрисовки, что то типа отрисовывает изменившейся объект, а все остальное нет. Так решается проблема с мерцанием, но может и с нагрузкой ЦПУ, что ниб решится?
|
|||
|
||||
Enteropoly |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 50 Регистрация: 17.6.2009 Репутация: нет Всего: нет |
Двойная буферизация ессно включена =)
|
|||
|
||||
gambit |
|
|||
![]() Эксперт ![]() ![]() ![]() Награды: 1 Профиль Группа: Комодератор Сообщений: 1359 Регистрация: 25.6.2006 Где: я? Репутация: 3 Всего: 40 |
Создай класс шестиугольника, загони все объекты в массив, отрисуй их все, в mouse_move повесь процедуру определения, к какому объекту принадлежат данные координаты, если координаты наехали на другой объект, то только тогда перерисовывай форму.
|
|||
|
||||
gambit |
|
|||
![]() Эксперт ![]() ![]() ![]() Награды: 1 Профиль Группа: Комодератор Сообщений: 1359 Регистрация: 25.6.2006 Где: я? Репутация: 3 Всего: 40 |
Криво, но общий смысл понятен.
Присоединённый файл ( Кол-во скачиваний: 18 ) ![]() |
|||
|
||||
gambit |
|
|||
![]() Эксперт ![]() ![]() ![]() Награды: 1 Профиль Группа: Комодератор Сообщений: 1359 Регистрация: 25.6.2006 Где: я? Репутация: 3 Всего: 40 |
До меня уже после дошло, в mouse move в начале можно вставить проверку с текущего ли объекта не ушла ли мышь, тогда он еще и цикл поиска гнать не будет, еще больше разгрузишь проц. А если ушла, то уже цикл поиска.
Это сообщение отредактировал(а) gambit - 30.6.2009, 10:15 |
|||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | .NET для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |