Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135

Перемещение GraphicsPath плавно в нужные координаты

13.03.2018, 02:12. Показов 1828. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго дня.
Возможно, я все делаю не так, потому прошу подсказки, ибо застрял.

Есть объект Player с координатами и GraphicsPath'ом, которые рисуются в одной форме. В другой форме есть четыре поля для ввода и две кнопки: два поля и кнопка из них - телепортация в какие-то опеределенные координаты, а вторые два с другой кнопкой - для плавного перемещения из любых текущих координат в заданные. Проблема в том, что не могу плавно переместить GraphicsPath, да и координаты меняются как-то странно.
Закидайте насмерть помидорами, если очень страшную хрень написал.

Заранее спасибо откликнувшимся.

Player.cs
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
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
 
namespace football_player
{
    public class Player : ICloneable
    {
        public GraphicsPath path; // Графика для точки игрока
        public int x, y; // Положение игрока в пространстве
 
        public Player(int x, int y)
        {
            this.x = x;
            this.y = y;
            this.path = new GraphicsPath();
            this.path.AddEllipse(Rectangle.FromLTRB(x, y, x + 16, y + 16));
        }
        
        public object Clone()
        {
            Player p = new Player(this.x, this.y);
            p.path = this.path.Clone() as GraphicsPath;
            return p;
        }
    }
}
Program.cs
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
using System;
using System.Collections.Generic;
using System.Windows.Forms;
 
namespace football_player
{
 
    static class Data
    {
        static public List<Player> list = new List<Player>();
    }
 
    static class Program
    {
        public static Form1 Form1;
        public static Form2 Form2;
 
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Program.Form1 = new Form1();
            Program.Form2 = new Form2();
            Program.Form2.Show();
            Application.Run(Program.Form1);
        }
    }
}
Form1.cs
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
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace football_player
{
    public partial class Form1 : Form
    {
        Bitmap bmp;
        public static int finalx;
        public static int finaly;
 
        public Form1()
        {
            InitializeComponent();
 
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            Init();
            RefreshBitmap();
            this.DoubleBuffered = true;
            this.Paint += Form1_Paint;
        }
 
        void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (bmp == null) return;
            RefreshBitmap();
            e.Graphics.DrawImage(bmp, 0, 0);
        }
 
        public void RefreshBitmap()
        {
            if (bmp != null) bmp.Dispose();
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                foreach (Player po in Data.list)
                {
                    g.DrawPath(new Pen(Color.Black), po.path);
                }
            }
        }
 
        public void AllMove(int finalxt, int finalyt)
        {
            finalx = finalxt;
            finaly = finalyt;
            timer1.Enabled = true;
        }
 
        void Init()
        {
            Player po;
            po = new Player(this.ClientSize.Width / 2 - 5, this.ClientSize.Height / 2 - 5);
            Data.list.Add(po);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            var deltaX = (finalx - Data.list[0].x) / 10;
            var deltaY = (finaly - Data.list[0].y) / 10;
            Data.list[0].x += deltaX;
            Data.list[0].y += deltaY;
            Data.list[0].path.Transform(new Matrix(1, 0, 0, 1, deltaX, deltaY));
            RefreshBitmap();
            if ((Math.Abs(finalx - Data.list[0].x) < 1) && (Math.Abs(finaly - Data.list[0].y) < 1)) {
                timer1.Enabled = false;
            }
        }
 
        private void Form1_Activated(object sender, EventArgs e)
        {
            RefreshBitmap();
        }
    }
}
Form2.cs
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
using System;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace football_player
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            var deltaX = Convert.ToInt16(x1.Text) - Data.list[0].x;
            var deltaY = Convert.ToInt16(y1.Text) - Data.list[0].y;
            Data.list[0].x = Convert.ToInt16(x1.Text);
            Data.list[0].y = Convert.ToInt16(y1.Text);
            Data.list[0].path.Transform(new Matrix(1, 0, 0, 1, deltaX, deltaY));
            Program.Form1.Invalidate();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            var finalx = Convert.ToInt16(x2.Text);
            var finaly = Convert.ToInt16(y2.Text);
            Program.Form1.Activate();
            Program.Form1.AllMove(finalx, finaly);
            x1.Text = Convert.ToString(Data.list[0].x);
            y1.Text = Convert.ToString(Data.list[0].y);
        }
    }
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.03.2018, 02:12
Ответы с готовыми решениями:

Перемещение фигуры GraphicsPath
Доброго времени суток! Прошу помощи по реализации осмысленного перемещения фигуры по форме. Задумка такая: нажимаем на кнопу необходимого...

Перемещение файлов в нужные папки и их переименование
Есть 1000 пустых папок, в них нужно переместить определенные jpg файлы из других папок и переименовать в 1. Чтобы получилось что в этих...

Есть ли способ плавно вывести бордер при наведении, ну и плавно скрыть
Необходимо плавно вывести границу при наведении, и плавно чтобы скрывалась если убрать курсор. Что можете посоветовать?

2
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
13.03.2018, 10:24
Syrax,
Движение странное, потому, что вы считаете deltaX и deltaY каждый раз в таймере, вместо того, что бы посчитать их один раз (например в методе AllMove). Из-за того, что вы их пересчитываете, движение получается неравномерным, ведь расстояние между объектом и целью меняется, и меняется delta.
Ну и кроме того, лучше перейти к векторам, все упростится. Ну и игровой цикл нужно вместо таймера. Ну и еще там куча всякого ненужного.
0
 Аватар для Syrax
28 / 19 / 16
Регистрация: 09.12.2009
Сообщений: 135
13.03.2018, 11:02  [ТС]
Спасибо за ответ, Storm23, но я не могу пояснить, почему именно так. Я плохой программист.

Не по теме:

Как сделать нормальное упоминание на этом форуме?


Спасибо за идею сделать "игровой цикл", похоже, все перепишу. Только котелок варит очень плохо.

Объясню момент с вычислением дельты в таймере. Из-за моей криворукости при вычислении этой дельты вне таймера получалось странное: окружность проходила мимо, а иногда сильно мимо, координат, куда должна была. И уходила в бесконечность. По координатам, естественно. Визуально она либо оставалась на месте, либо спустя несколько секунд исчезала с экрана, видимо, в ту самую бесконечность.

Ответ на свой же вопрос: я в таймере забыл поставить Form.Refresh().

А еще слегка поправил код передвижения, теперь он еще хуже, чем был ранее, но главное, что попадает точно в цель. Все изменения в методе AllMove и таймере, в общем-то.
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
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace football_player
{
    public partial class Form1 : Form
    {
        Bitmap bmp;
        public static int finalx;
        public static int finaly;
        public static double vecx;
        public static double vecy;
        int k;
 
        public Form1()
        {
            InitializeComponent();
 
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            Init();
            RefreshBitmap();
            this.DoubleBuffered = true;
            this.Paint += Form1_Paint;
        }
 
        void Form1_Paint(object sender, PaintEventArgs e)
        {
            if (bmp == null) return;
            RefreshBitmap();
            e.Graphics.DrawImage(bmp, 0, 0);
        }
 
        public void RefreshBitmap()
        {
            if (bmp != null) bmp.Dispose();
            bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                foreach (Player po in Data.list)
                {
                    g.DrawPath(new Pen(Color.Black), po.path);
                }
            }
        }
 
        public void AllMove(int finalxt, int finalyt)
        {
            finalx = finalxt;
            finaly = finalyt;
            k = 50;
            timer1.Enabled = true;
        }
 
        void Init()
        {
            Player po;
            po = new Player(this.ClientSize.Width / 2 - 5, this.ClientSize.Height / 2 - 5);
            Data.list.Add(po);
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            float deltaX = (finalx - Data.list[0].x) / k;
            float deltaY = (finaly - Data.list[0].y) / k;
            Data.list[0].x += (int)deltaX;
            Data.list[0].y += (int)deltaY;
            k -= 1;
            Data.list[0].path.Transform(new Matrix(1, 0, 0, 1, (int)deltaX, (int)deltaY));
            RefreshBitmap();
            if ((Math.Abs(finalx - Data.list[0].x) <= 1) && (Math.Abs(finaly - Data.list[0].y) <= 1)) {
                timer1.Enabled = false;
            }
            Program.Form1.Refresh();
        }
 
        private void Form1_Activated(object sender, EventArgs e)
        {
            RefreshBitmap();
        }
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
13.03.2018, 11:02
Помогаю со студенческими работами здесь

JScrollPane координаты и перемещение
Всем привет. Стоит задача написать приложуху, которая открывает текстовые файлы, что то вроде блокнота. Но каждый файл должен открываться...

Перемещение координаты точки на плоскости
Добрый день, уважаемые форумчане! Прошу помощи в решении, казалось бы несложной геометрической задачки. На холсте есть 2 детали,...

Перемещение каретки в указанные координаты
Доброе время суток, Подскажите как сдвинуть каретку в консоле на заданные координаты

Перемещение элемента в координаты клика мышки
Здравствуйте. Моя задача переместить элемент в координаты клика мышки. Т.е. пользователь кликает и элемент (div, например)...

Рандомное перемещение точки на соседние координаты
Сабж, интересует как сие можно реализовать... Пока смог перемещать только рандомно по всему полю... #include &lt;GL/glut.h&gt; #include...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru