| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Разработка Windows Forms > движение квадрата |
| Автор: sasha11 10.12.2006, 20:19 |
| изучаю С# !!! дошел доглавы про GDI+, но так и не пойму как сделать так что-бы двигался прямоугольник(и.т.д.) к примеру по событию таймера !!! типа как в тетрисе !!! |
| Автор: VisualProgrammerNET 10.12.2006, 22:37 |
| суть: - Прямоугольник в данном случае должен быть представлен классом с полями, символизирующими его координаты - В классе "Прямоугольник" должен быть метод его отрисовки (с параметром типа Graphics), зависящий от координат - На таймер ставишь перерисовку формы и шаг движения прямоугольника (перерисовка: метод Invalidate) - Перекрываешь метод отрисовки (OnPaint). В новом методе вызываешь функцию отрисовки прямоугольника |
| Автор: sasha11 11.12.2006, 16:48 |
| есть метод DrawRectangle - e.Graphics.DrawRectangle(new pen(Color.Red),10,10,100,100); как мне сделать что-бы этот созданый прямоугольник, двигался ??? желательно на примере. а то как я не пробовалу меня не получается. |
| Автор: ivashkanet 11.12.2006, 16:56 | ||
| sasha11, лови. Но тут все сырое. Накидано за 5 минут
|
| Автор: sasha11 11.12.2006, 17:39 |
| >>Rectangle rec = new Rectangle(a, 100, 100, 100); вот строчка - _rectangleXPosition, ПАСИбо то что надо было !!! а то я знаю как вызвать метод DrawRectangle, а тупил не мог создать обЪект Rectangle, ПАСИБО БОЛЬШОЕ. просто я недавно занимаюсь С# и никак не мог понять,как двигать изображение!!! |
| Автор: Oxana 23.11.2007, 12:01 |
| У меня ситуация не много иная. Нужно так же передвигать фигуру, но фигура должна быть создана кистями(ну типа DrawElipse). Подскажите пожалуйста как я могу передвигать фигуру(можно пример). |
| Автор: VisualProgrammerNET 23.11.2007, 14:36 |
| ну, пример приводить не буду =) попробую немного рассказать о том, как это всё делается в принципе. Мой дебют в качестве учителя, так что не особо уж придирайтесь ДИНАМИЧЕСКОЕ РИСОВАНИЕ С ПОМОЩЬЮ GDI+ ДЛЯ ЧАЙНИКОВ Рассматривать движение некоего объекта нужно с точки зрения мультипликации. Мультфильм - это последовательность неких статических кадров, которые при быстрой смене друг друга заставляют некие объекты двигаться. Принцип рисования в C# такой же. Сперва определимся с частотой смены кадров (Frames per second, FPS). как и в любых компьютерных играх, FPS влияет на то, насколько плавно изменяется картинка на экране. Если сделать FPS слишком маленьким, то будут заметны рывки, с которыми движутся объекты. В большинстве случаев этого нам не надо. Но и большой FPS - палка о двух концах. При плавном изменении картинки мы сильнее загружаем процессор, а если в нашем "мультфильме" участвует большое количество объектов, то и сильно замусоривается оперативная память. Конечно, тут многое упирается в производительность компьютера, останавливаться на этом не будем. Определившись с частотой смены кадров (допустим, 50 в секунду), надо это запрограммировать, поэтому первым делом мы кинем на форму таймер с интервалом равным 20 (Interval = 1000/FPS). Сразу не забудем установить свойство формы DoubleBuffered в true, чтобы она не моргала при частой перерисовке. Теперь мы должны сказать программе, чтобы она через каждые 20 тиков рисовала новый "кадр", поэтому по событию Timer_Tick() мы будем нашу форму перерисовывать (form.Invalidate()). Здесь и далее для наглядности можно смотреть на пример ivashkanet выше. Следующим делом будет дело творческое - мы будем придумывать сюжет и рисовать кадр за кадром. Допустим, мы создаём высокобюджетный экшн "Движение закрашенного эллипса". По сюжету, эллипс движется слева направо по экрану и при достижении его края, возвращается к другому краю, продолжая движение. С сюжетом определились, пора придумывать героев. В данном случае он один - эллипс. Создаём класс CartoonHero, в котором опишем героя. У нашего героя должны быть минимум два параметра - координата Х и координата Y, плюс он должен уметь перемещать себя и рисовать себя на экране. Отсюда мы получаем два приватных поля типа int и два метода: MoveMe() и DrawMe(Graphics g), к примеру. Так как по сюжету эллипс движется горизонтально по экрану, то в методе MoveMe мы должны менять координату Х на некоторое число (X += некоторое число, зависящее от того, с какой скоростью вы хотите двигать эллипс). Плюс по сюжету герой должен возвращаться к левому краю экрана, когда достигнет правого, так что мы изменим метод MoveMe на MoveMe(int border), где в качестве border будем передавать ширину формы. Соответственно, добавляем простую проверку на X. Ну а метод отрисовки DrawMe - это просто рисование нашего героя-эллипса (g.FillEllipse...) с его текущими координатами. На этом этапе мы закончили создание всех героев и можно приступать к реализации мультфильма. Как мы помним, по таймеру мы рисуем новый кадр. А каждым новым кадром по сюжету является эллипс, передвинутый на некоторое расстояние вперёд. Изменим событие Timer_Tick так, чтобы перед рисованием нового кадра герой мог передвинуться (само-собой нужно создать хотя бы одного героя перед этим (CartoonHero ch = new CartoonHero()). Перед строчкой this.Invalidate() мы будем вызывать метод MoveMe героя. Завершающий штрих - сказать программе, как она должна отрисовывать каждый кадр. Для этого перегрузим метод OnPaint формы. В него достаточно добавить лишь метод DrawMe, в который в качестве параметра передаваться будет e.Graphics. Теперь можно запускать программу и наслаждаться захватывающим творением собственного гения, на которое было потрачено столько сил и средств |
| Автор: thomas 23.11.2007, 15:02 |
| VisualProgrammerNET, +1 жжешь Такой талант пропадает. Мне б такого учителя по информатике в школу. Толково так все обьяснил на простеньком сюжете. Главное сразу понятно о чём речь. |
| Автор: VisualProgrammerNET 23.11.2007, 15:12 |
| Благодарю =))) |
| Автор: Oxana 25.11.2007, 03:29 |
| VisualProgrammerNET, Извини пожалуйста, не мог бы ты подсказать как передвигать фигуру при помощи мышки. С готовыми объектами все просто, есть обработчик событий, а что делать с фигурами которые нарисованы кистями? П.С. За вышеприведенный урок БОЛЬШОЕ пасиба. |
| Автор: Experimenter 25.11.2007, 18:42 |
| Oxana, тебя перерисовка фигуры интересует или как фигуру мышью захватить? |
| Автор: Oxana 25.11.2007, 22:45 |
| Experimenter, Как фигуру мышью захватить. |
| Автор: Experimenter 26.11.2007, 08:27 | ||
Oxana,
|
| Автор: Experimenter 26.11.2007, 09:00 | ||
Oxana, смотри, но учти, что это всего лишь набросок.
|
| Автор: Oxana 27.11.2007, 08:24 |
| Большое ПАСИБА |
| Автор: rolandxl 27.11.2007, 14:54 |
| Ответьте пожалуйста на такой вопрос : возможно ли коректно передвигать фигуры без использования таймера (с циклом for)? Просто проблема вот в чем, я создал цикл просчёта движения и отрисовки фигуры, на каждом шаге цикла в конце стоит функция Invalidate, однако фигура оставляет за собой шлейф, который пропадает только после завершения всего цикла. Как вариант хотел закрашивать прямоугольник с фигурой на каждом шаге фоновым фрагментом, но реализовать не удалось. Кто знает помогите пожалуйста, а то курсовик скоро сдавать надо |
| Автор: ivashkanet 27.11.2007, 14:58 |
| rolandxl, при перетаскивании вообще не нужен таймер! Где ты его нашел в коде Experimenter-? Таймер нужен если ты программируешь движение без участия человека (типа мультик). P.S. Но в любом случае тебе поможет выставить у формы DoubleBuffering = true |
| Автор: Experimenter 27.11.2007, 15:07 |
| rolandxl, иногда помогает graphics.Clear(this.BackColor); перед новой прорисовкой |
| Автор: rolandxl 27.11.2007, 19:54 |
| Experimenter graphics.clear(backcolor) поможет только если фон одноцветный |
| Автор: Experimenter 27.11.2007, 19:56 |
| rolandxl, что тебе сказать? тащи свой код. |
| Автор: rolandxl 27.11.2007, 21:38 | ||
|
| Автор: Experimenter 28.11.2007, 07:47 | ||
При первом взгляде на код создается впечатление, что он должен работать корректно, а шлейф возникает из-за того, что возможности системы не безграничны, слишком часто перерисовку делать приходится. Попробуй в начале цикла выставить
|
| Автор: rolandxl 28.11.2007, 21:36 | ||||
не, это моя личная инициатива сделать без таймера (слишком тяжело связать его с выполнением всей проги, когда 3 класса обмениваются между собой данными ). Насчёт
хорошая фишка, пригодиться для замедления анимации. Но мою проблему не решает: даже когда чел очень медленно идёт, всё равно обновления не происходит + через некоторое время прога падает на строчке
с сообщением Object reference not set to an instance of an object." видимо форма перестает быть активной |
| Автор: Experimenter 29.11.2007, 10:25 | ||
rolandxl, нарыл в МСДН:
|
| Автор: rolandxl 29.11.2007, 16:18 | ||
Мне препод вот что предлагал: прежде чем рисовать человечка, копировать область фона, в которой мы хотим его рисовать, и после отрисовки закрывать ею его(вот как раз это у меня не получается сделать, обычный
Experimenter, что по этому поводу думешь? |
| Автор: Experimenter 29.11.2007, 18:00 |
| rolandxl, препод хорошую идею подсказал, но как это осуществить технически? Щас почешем репу... |
| Автор: Experimenter 29.11.2007, 18:36 | ||
Чесание репы привело к такому варианту:
Можно еще попробовать BufferedGraphics конечно, как http://forum.vingrad.ru/forum/topic-180804.html, отпиши, что вышло. |
| Автор: rolandxl 29.11.2007, 23:30 | ||||
Всё класс, код нормально покатил, спасибо, моргания хоть и есть но уже не такие ощутимые как были у меня. В строчке
Из куба пробовал способ, но особо разбираться и экспериментировать времени не было. Вышло следующее: Все построения и просчеты происходят, но вывода графики нет. вот код
|
| Автор: Experimenter 30.11.2007, 07:17 | ||||
|
| Автор: rolandxl 30.11.2007, 16:54 | ||
| Удалось прикрепить таки твой метод к моему коду, и по моему человечек остался таким же бессовестным. (один момент, в строке bg.Render(e.Graphics); насколькоя понимаю e.Graphics - это ведь просто событие вывода графики на форму? и необязательно передавать в рендеринг именно мой Graphics объект?). Сдаётся мне, что придется таки присобачивать таймер к проге для моментов вывода графики. Или довольствоваться тем что получилось. Experimenter спасибо за посильную помощь, ты мне очень помог.
Да нет, зачем мне было его ставить. Может просто форма обновляется при движении со всеми последствиями? С этим буду бороться самостоятельно) |