2 / 2 / 0
Регистрация: 20.11.2010
Сообщений: 52
1

Следы от эллипса на форме при его движении (как здесь поможет многопоточность?)

14.07.2012, 00:50. Показов 2755. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При движении эллипс оставляет следы на форме. Мне посоветовали использовать два потока.
Цитирую слова:
"Рисовать в основном потоке, а мир действует в другом - специальном. Запускаешь поток паралельно, ставишь ему приоритет High, и в нем пусть бесканецный цикл обходит мир. "

Потоки я вроде разобрал и немного понял. Но вот как сделать то что мне сказали - не могу никак понять.
ОБЪЯСНИТЕ ПОЖАЛУЙСТА.

Мой код:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
 
        private Bitmap myBitmap;
 
        int position_of_ball_x,
            position_of_ball_y,
            move_of_ball_x,
            move_of_ball_y,
            width_of_bitmap_of_ball,
            height_of_bitmap_of_ball;
 
        public Form1()
        {
            InitializeComponent();
    
            timer1.Interval = 5;
 
            timer1.Enabled = true;     
        }
     
        private void timer1_Tick(object sender, EventArgs e)
        {
            Graphics myGraphics = CreateGraphics();
            
            myGraphics.DrawImage(myBitmap, Convert.ToInt32(position_of_ball_x - width_of_bitmap_of_ball / 2),
            Convert.ToInt32(position_of_ball_y - height_of_bitmap_of_ball / 2), width_of_bitmap_of_ball, height_of_bitmap_of_ball);
 
            myGraphics.Dispose();
 
            position_of_ball_x = position_of_ball_x + move_of_ball_x;
 
            //Движение ТУДА-СЮДА (Выбор направления)
            if ((position_of_ball_x == 700) && (move_of_ball_x > 0)) move_of_ball_x = -move_of_ball_x;
            if ((position_of_ball_x == 100) && (move_of_ball_x < 0)) move_of_ball_x = -move_of_ball_x;     
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Graphics myGraphics = CreateGraphics();
 
            myGraphics.Clear(BackColor);
 
            myGraphics.Dispose();
 
            move_of_ball_x = 10;
 
            width_of_bitmap_of_ball =70;
 
            height_of_bitmap_of_ball = 70;
 
            myBitmap = new Bitmap(width_of_bitmap_of_ball, height_of_bitmap_of_ball);
 
            myGraphics = Graphics.FromImage(myBitmap);
 
            myGraphics.Clear(BackColor);
 
            myGraphics.FillEllipse(Brushes.Coral, new Rectangle(5, 5, 60, 60));
 
            myGraphics.Dispose();
 
            position_of_ball_x = 100;
 
            position_of_ball_y = 100;
        }
 
    }
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.07.2012, 00:50
Ответы с готовыми решениями:

Большая нагрузка и тормоза при движении картинки по форме
Пишу небольшую программку, большая часть интерфейса - это картинка с координатной плоскостью. Хотел...

При движении квадрата стирать его из предыдущей позиции
Здравствуйте,нужно поправить код, что бы после движения прошлый квадрат стирался. То есть что бы...

Изменить цвет эллипса при его попадании в квадрат
Очень нужна помощь реализовал движение эллипса но никак не выходит реализовать изменение цвета...

Определить максимальный угол между векторами скорости шарика при его движении.
Шарик брошен вверх под углом 60 к горизонту. Определить максимальный угол между векторами скорости...

11
Почетный модератор
Эксперт .NET
8714 / 3666 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
14.07.2012, 02:21 2
iron-mik, еда к размышлению: проблема в этом - CreateGraphics(); (36 строчка)...

Не по теме:

Откуда ж новички узнают об этом корявом пути, использование CreateGraphics в таймере... :scratch:

0
63 / 63 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
14.07.2012, 04:25 3
Вот тема - Движение окружности по форме - здесь есть ссылка на файл Moving.rar в котором ваша задача решена. Вам осталось только выдернуть её правильно.
0
2 / 2 / 0
Регистрация: 20.11.2010
Сообщений: 52
14.07.2012, 09:48  [ТС] 4
Цитата Сообщение от SSTREGG Посмотреть сообщение
iron-mik, еда к размышлению: проблема в этом - CreateGraphics(); (36 строчка)...
Никак не могу понять в чем здесь проблема... Тут я каждом новом периоде создаю новый Graphics, и потом рисую его с новыми координатами.
Объясните пожалуйста, что вы имели ввиду.

SSTREGG, и еще хотел спросить:
В похожей теме которую предоставил мне уважаемый Mans7, вы говорили что кроме как варианта с потоками, можно использовать вариант с таймером:
Цитата Сообщение от SSTREGG Посмотреть сообщение
Зачем потоки? таймера хватит. )
Предполагаю вариант с таймером - это как у меня?

Добавлено через 2 минуты
Mans7, Спасибо за пример. Вроде разобрался немного как с потоками. Однако заметил что всеравно у некоторых фигур немного остается остаточный след. В чем там может быть проблема?
0
63 / 63 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
14.07.2012, 09:51 5
Цитата Сообщение от iron-mik Посмотреть сообщение
Предполагаю вариант с таймером - это как у меня?
Именно. А в примере с архивом в котором я прислал, там реализована пауза в параллельном потоке. На заметку: если вы будете делать такую же паузу в основном потоке, то программа будет "зависать" на Х миллисекунд. При "подвисании" параллельного потока, вы, будучи в основном, никаких изменений не видите. Потоки просто более функциональные, нежели таймеры.

Цитата Сообщение от iron-mik Посмотреть сообщение
Однако заметил что всеравно у некоторых фигур немного остается остаточный след.
В том примере, что я вам дал, я не увидел таких проблем. Вообще Вам стоит в таком случае почитать про Двойную буферизацию.
Ссылка: MSDN - Двойная буферизация графики
Ссылка: MSDN - Практическое руководство. Уменьшение эффекта дрожания изображения посредством двойной буферизации для форм и элементов управления
Я лично этим не занимался, потому не скажу ничего больше про двойную буферизацию. Вообще такой метод рисования (который вы используете) очень неудобный, как вы, наверняка успели заметить. А если честно - он неграмотный совершенно. Технически вы рисуете круг, заливаете его. Потом стираете всё поле, снова рисуете. По-любому возможна реализация этих же целей более удобно и эффективно. Поищите более современные методы рисования, может быть, какие-нибудь сторонние библиотеки, или, если вы сможете нарисовать то что вам надо в каком-нибудь элементе управления (панель, пикчурбокс), то их можно легко двигать программно. Правда, опять таки, это только в теории, надо пробовать. Кстати я только щас об этом подумал - попробуйте нарисовать вашими методами что-то в Panel, а затем в таймере (или в потоке) двигайте панель изменением свойств Top и Left, или сразу Location. Интересно - будет ли такой же глюк? (при этом все clear и dispose вам уже не нужны будут)
0
2 / 2 / 0
Регистрация: 20.11.2010
Сообщений: 52
14.07.2012, 09:56  [ТС] 6
Mans7, Извиняюсь, кажется я понял - это наверно не следы от объектов. Это просто одинаковая траектория движения и тот же самый цвет скорее всего. Верно?

Добавлено через 1 минуту
Mans7, спасибо за инфу - почитаю.
0
63 / 63 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
14.07.2012, 10:06 7
Пожалуйста. А вот ещё, рекомендую потратить немного времени на ознакомление:
- не обращайте внимание что это для Delphi, в этой теме язык не нужен.
- Тоже для Delphi но понять смысл можно.

Цитата Сообщение от iron-mik Посмотреть сообщение
Извиняюсь, кажется я понял - это наверно не следы от объектов
Не совсем. Почитайте то что я предложил, где-то там четко описывается что это и почему оно возникает.

В общем теперь у Вас должен быть полный арсенал информации. =)
1
Почетный модератор
Эксперт .NET
8714 / 3666 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
14.07.2012, 12:04 8
Какие потоки для такой задачи? (вопрос риторический)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
 
        private Bitmap myBitmap;
 
        int position_of_ball_x,
            position_of_ball_y,
            move_of_ball_x,
            move_of_ball_y,
            width_of_bitmap_of_ball,
            height_of_bitmap_of_ball;
 
        public Form1 ( )
        {
            InitializeComponent();
            this.DoubleBuffered = true;
 
            timer1.Interval = 5;
            timer1.Enabled = true;
        }
 
        private void timer1_Tick ( object sender, EventArgs e )
        {
            // Вызываем перерисовку окна
            this.Invalidate();
 
            position_of_ball_x = position_of_ball_x + move_of_ball_x;
 
            //Движение ТУДА-СЮДА (Выбор направления)
            if ( (position_of_ball_x == 700) && (move_of_ball_x > 0) )
                move_of_ball_x = -move_of_ball_x;
            if ( (position_of_ball_x == 100) && (move_of_ball_x < 0) )
                move_of_ball_x = -move_of_ball_x;
        }
 
        private void Form1_Load ( object sender, EventArgs e )
        {
            move_of_ball_x = 10;
 
            width_of_bitmap_of_ball = 70;
 
            height_of_bitmap_of_ball = 70;
 
            myBitmap = new Bitmap( width_of_bitmap_of_ball, height_of_bitmap_of_ball );
 
            using ( var myGraphics = Graphics.FromImage( myBitmap ) )
            {
                myGraphics.Clear( BackColor );
                myGraphics.FillEllipse( Brushes.Coral, new Rectangle( 5, 5, 60, 60 ) );
            }
 
            position_of_ball_x = 100;
 
            position_of_ball_y = 100;
        }
 
        private void Form1_Paint ( object sender, PaintEventArgs e )
        {
            /* В Paint!!! В событии Paint должна происходить отрисовка.
             * Paint вызывается когда нужно перерисовать окно
             * Не хотите всё в Paint рисовать, рисуйте в буфере, а
             * его уже отрисовывайте здесь, в таймере только форсировано
             * вызываете перерисовку окна, путем вызова Invalidate, Update
             * или Refresh (отличия прочитайте на MSDN)
             */
 
            e.Graphics.DrawImage( 
                myBitmap,
                position_of_ball_x - width_of_bitmap_of_ball / 2 ,
                position_of_ball_y - height_of_bitmap_of_ball / 2 ,
                width_of_bitmap_of_ball, 
                height_of_bitmap_of_ball
                );
        }
    }
}
1
63 / 63 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
14.07.2012, 12:27 9
В этом коде есть только один поток по умолчанию, и он основной. Его не надо нигде прописывать это простой основной поток. Если хотите сделать параллельный, то замените
C#
1
private void timer1_Tick ( object sender, EventArgs e )
на
C#
1
private void Thread_Action()
и допишите где-нибудь (скажем в Form1_Load) следующее:
C#
1
2
3
Thread th = new Thread(new ThreadStart(Thread_Action));
th.Start(); //начать выполнение ф-ии Thread_Action в отдельном потоке
//th.Abort(); //остановить работающий поток
Правда здесь есть одно "НО": возможно, "this.Invalidate();" необходимо будет немного видоизменить (где-то видел пример), потому как возможно из другого потока он может начать ругаться.
0
2 / 2 / 0
Регистрация: 20.11.2010
Сообщений: 52
14.07.2012, 22:58  [ТС] 10
SSTREGG, Все работает, спасибо! ТОлько один вопрос: что дает использование using -
C#
1
using ( var myGraphics = Graphics.FromImage( myBitmap ) ) { myGraphics.Clear( BackColor ); myGraphics.FillEllipse( Brushes.Coral, new Rectangle( 5, 5, 60, 60 ) ); }
Почему без него нельзя?
0
Почетный модератор
Эксперт .NET
8714 / 3666 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
14.07.2012, 22:59 11
iron-mik, почитайте.
0
63 / 63 / 14
Регистрация: 05.08.2011
Сообщений: 323
Записей в блоге: 5
15.07.2012, 00:44 12
Цитата Сообщение от iron-mik Посмотреть сообщение
Почему без него нельзя?
Можно и без него. Ключевое слово Using упрощает работу с объектами которые реализуют интерфейс IDisposable.

Интерфейс IDisposable содержит один метод .Dispose(), который используется для освобождения ресурсов, которые захватил объект. При использовании Using не обязательно явно вызывать .Dispose() для объекта.

То есть он тут используется в целом для контроля памяти, выделяемой на перерисовку (clear) и заливку (fill). А ещё Using блоки делают код более читабельным и компактным.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.07.2012, 00:44
Помогаю со студенческими работами здесь

Как в листе Exel на форме в проекте убрать его меню при активизации?
Всем привет! Ребята, меня интересует такой вопрос. Как в листе Exel на форме в проекте убрать его...

Как создать эллипс на Canvas зная XY середины эллипса и R радиус эллипса
Как создать эллипс на Canvas зная XY середины эллипса и R эллипса

Компонент пользователя и его свойства при размещении его на форме
Есть пользовательский компонент на базе TImage. При размещении его на форме проекта, компонент...

ScreenSaver как изменить цвет и размер эллипса во время его движения?
Здравствуйте, я новичок в c#, решил написать ScreenSaver. Не могу понять как изменить цвет эллипса...

Масса протона при движении и его масса покоя
Всем привет. Заранее прошу прощение за столь глупую тему, однако действительно нуждаюсь в помощи...

Как найти радиус-вектор эллипса для определенного угла отклонения от оси эллипса
Добрый день! Подскажите, как можно найти радиус-вектор эллипса r1 для определенного угла отклонения...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru