46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,814
1
.NET 2.x

Компонент SEGA палитры

07.07.2018, 19:52. Показов 1857. Ответов 27
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Нужна помощь в создании компонента SEGA палитры на основе PictureBox и таблицы

Нужно сделать отрисовку палитры и при этом сделать также выделение цвета в палитре и при выборе цвета чтобы он также подсвечивался рамочкой. Пока что у меня сделано в виде обычного PictureBox и говнокода
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
Bitmap SetSEGAPalette()
        {
            //Переменная палитры SEGA по цветам RGB
            var col = new double[8];
 
            col[0] = 0.0;
            col[1] = 2.0;
            col[2] = 4.0;
            col[3] = 6.0;
            col[4] = 8.0;
            col[5] = 10.0;
            col[6] = 12.0;
            col[7] = 14.0;
 
            var x = 0;
            var y = 0;
 
            Bitmap CDH_PaleteBuf = new Bitmap(pb_SEGAPalette.Width, pb_SEGAPalette.Height);
            Graphics g = Graphics.FromImage(CDH_PaleteBuf);
 
            for (int i = 0; i < 8; i++)
            {
 
                y = (i / 4) * (128);
                x = (i % 4) * (128);
 
                for (int l = 0; l < 8; l++)
                {
                    for (int k = 0; k < 8; k++)
                    {
 
                        SolidBrush br = new SolidBrush(Color.FromArgb(255, (int)(col[k] * 255 / 14), (int)(col[l] * 255 / 14), (int)(col[i] * 255 / 14)));
 
                        g.FillRectangle(br, x, y, 16, 16);
 
                        y += 16;
                    }
 
                    y -= 128;
                    x += 16;
                }
            }
 
            pb_SEGAPalette.Image = CDH_PaleteBuf;
            return CDH_PaleteBuf;
        }
 
        void SetRectSEGAPalete(int x, int y)
        {
            var xi = (int)(x / 16);
            var yi = (int)(y / 16);
 
            Bitmap CDH_PaleteBuf = SetSEGAPalette();
            Graphics g = Graphics.FromImage(CDH_PaleteBuf);
 
            if (xi < 4 || yi < 4)
            {
                g.DrawRectangle(new Pen(Color.White, 2), (xi * 16), (yi * 16), 16, 16);
            }
            else
            {
                g.DrawRectangle(new Pen(Color.Black, 2), (xi * 16), (yi * 16), 16, 16);
            }
        }
И то это только 2 вещи. А именно рамка при выборе цвета и сама палитра. И при двежении мышки по pictureBox вызывается вот это:
SetRectSEGAPalete()
что каждый раз делает перерисовку палитры и рамки и не эфективно это.
Лучше для этого сделать свой компонент.

Подскажите с чего начать?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.07.2018, 19:52
Ответы с готовыми решениями:

Создание SEGA палитры на PictureBox
Здравствуйте. Есть код на языке PureBasic ;{ создание глобальной палитры Global Dim...

Тема. Создание программ с использованием объектов Палитры компонент Standart и Additional
вариант 1 1. Напишите программу, которая выведет в центре экрана следующий текст: &quot;To be or not...

Sega: нет изображения
подключаю всё вроде правильно включаю а изображения нет что делать?

Windows xp + naomi 2 sega
Добрый вечер. Имеется данная приставка с сгоревшим gd rom. Написал скрипт на питоне для запуска...

27
8940 / 4852 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 19:35 21
Author24 — интернет-сервис помощи студентам
Alexandr_7, в моём примере не компонент, а контрол. Это разные классы.
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,814
09.07.2018, 20:00  [ТС] 22
Цитата Сообщение от ViterAlex Посмотреть сообщение
Чтобы не мерцало, обновлять нужно только то место, где находится курсор + пару пикселей. Получение цвета из координат вынести в отдельный метод, так же и инверсию цвета:
Я имел в виду мерцающая рамка при выборе цвета . Ну а вообще немного мерцающая рамка при наведении мышкой тоже хорошо.

Добавлено через 24 минуты
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace SegaPalette.Controls
{
    [DefaultProperty("SelectedColor")]
    [DefaultEvent("SelectedColorChanged")]
    public class SegaPalette : Control
    {
        private Color[,] _colors;
        private Rectangle _hoverRect = Rectangle.Empty;
        private Rectangle _hoverSelRect = Rectangle.Empty;
        private Color _selectedColor;
        private Color _hoverColor;
        private Color _hoverSelColor;
 
        private Timer _animateHoverRect = new Timer { Interval = 100 };
 
        private Timer _animateHoverSelRect = new Timer { Interval = 200 };
 
        public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;
        /// <summary>
        /// Выбранный цвет
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
            protected set
            {
                if (_selectedColor != value)
                {
                    var oldColor = _selectedColor;
                    _selectedColor = value;
                    OnSelectedColorChanged(new SelectedColorChangedEventArgs { NewColor = _selectedColor, OldColor = oldColor });
                }
            }
        }
 
        protected virtual void OnSelectedColorChanged(SelectedColorChangedEventArgs e)
        {
            SelectedColorChanged?.Invoke(this, e);
        }
 
        private int _side;
        /// <summary>
        /// Размер квадрата одного цвета
        /// </summary>
        protected virtual int Side
        {
            get => _side; set
            {
                _side = value;
                _hoverRect.Width = _side;
                _hoverRect.Height = _side;
            }
        }
 
        public SegaPalette()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            SetColors();
            Side = 8;
 
            SelectedColor = Color.Black;
 
            _animateHoverRect.Tick += _animateHoverRect_Tick;
            _animateHoverRect.Start();
 
            _animateHoverSelRect.Tick += _animateHoverSelRect_Tick;
            _animateHoverSelRect.Start();
        }
 
        private void _animateHoverRect_Tick(object sender, EventArgs e)
        {
            var inc = _hoverColor.A >= 224 ? -45 : 45;
            _hoverColor = Color.FromArgb((_hoverColor.A + inc) % 255, _hoverColor);
            var rect = _hoverRect;
            rect.Inflate(2, 2);
            Invalidate(rect);
        }
 
        private void _animateHoverSelRect_Tick(object sender, EventArgs e)
        {
            var inc = _hoverSelColor.A >= 224 ? -50 : 50;
            _hoverSelColor = Color.FromArgb((_hoverSelColor.A + inc) % 255, _hoverSelColor);
            var rect = _hoverSelRect;
            rect.Inflate(2, 2);
            Invalidate(rect);
        }
 
        //Определение цветов палитры
        private void SetColors()
        {
            _colors = new Color[8, 64];
            var col = new double[8] { 0, 2, 4, 6, 8, 10, 12, 14 };
            var norm = new Func<double, int>((val) => (int)(val * 255 / 14));
 
            for (int i = 0; i < 8; i++)
                for (int l = 0; l < 8; l++)
                    for (int k = 0; k < 8; k++)
                        _colors[l, k + 8 * i] = Color.FromArgb(255, norm(col[l]), norm(col[k]), norm(col[i]));
        }
        private Color Inverse(Color color)
        {
            return Color.FromArgb(color.A, 255 - color.R, 255 - color.G, 255 - color.B);
        }
 
        private Color GetColor(int x, int y)
        {
            var i = _hoverRect.X / _side;
            var j = _hoverRect.Y / _side;
            i += 32 * (j / 8);
            j %= 8;
            return _colors[j, i];
        }
 
        //Прорисовка контрола
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
            
            //Прямоугольник выделения
            using (var pen = new Pen(Inverse(_hoverColor), 2) { Alignment = PenAlignment.Inset })
            {
                e.Graphics.DrawRectangle(pen, _hoverRect);
            }
 
            //Прямоугольник выбранного
            using (var pen = new Pen(Inverse(_hoverSelColor), 2) { Alignment = PenAlignment.Inset })
            {
                e.Graphics.DrawRectangle(pen, _hoverSelRect);
            }
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //Положение выделения
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverRect.Location)
            {
                _hoverRect.Location = pt;
                _hoverColor = Color.FromArgb(_hoverColor.A, GetColor(e.X, e.Y));
                Invalidate();
            }
        }
 
        //Смена выбранного цвета
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
 
            //Положение выбранного
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverSelRect.Location)
            {
                _hoverSelRect.Location = pt;
                _hoverSelColor = Color.FromArgb(_hoverSelColor.A, GetColor(e.X, e.Y));
                Invalidate();
            }
 
            SelectedColor = GetColor(e.X, e.Y);
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //Размер формы в пропорции 2:1
            Width = (Width / 32) * 32;
            Height = Width / 2;
            Side = Width / 32;
        }
 
        protected override Cursor DefaultCursor => Cursors.Hand;
 
        protected override Size DefaultSize => new Size(256, 128);
    }
 
    public class SelectedColorChangedEventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
}
Не могу понять почему не работает 2 рамочка. Рамочка выбранного цвета
0
8940 / 4852 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 20:13 23
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Не могу понять почему не работает
Потому что ты вслепую скопировал условие из OnMouseMove в OnMouseClick. В OnMouseMove условие нужно, чтобы перерисовывать только тогда, когда курсор переместится на другой цветной квадрат. Очевидно, что в OnMouseClick это делать не нужно
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,814
09.07.2018, 20:19  [ТС] 24
Цитата Сообщение от ViterAlex Посмотреть сообщение
Потому что ты вслепую скопировал условие из OnMouseMove в OnMouseClick. В OnMouseMove условие нужно, чтобы перерисовывать только тогда, когда курсор переместится на другой цветной квадрат. Очевидно, что в OnMouseClick это делать не нужно
Нет потомучто я размер 2 рамки не указал. Вот так вот работает как нужно. Рече об 2х рамок. Первая которая происходит при выделении ну движении мышки. 2 при выборе цвета по умолчанию на нули на черном

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace SegaPalette.Controls
{
    [DefaultProperty("SelectedColor")]
    [DefaultEvent("SelectedColorChanged")]
    public class SegaPalette : Control
    {
        private Color[,] _colors;
        private Rectangle _hoverRect = Rectangle.Empty;
        private Rectangle _hoverSelRect = Rectangle.Empty;
        private Color _selectedColor;
        private Color _hoverColor;
        private Color _hoverSelColor;
 
        private Timer _animateHoverRect = new Timer { Interval = 100 };
 
        private Timer _animateHoverSelRect = new Timer { Interval = 200 };
 
        public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;
        /// <summary>
        /// Выбранный цвет
        /// </summary>
        public Color SelectedColor
        {
            get { return _selectedColor; }
            protected set
            {
                if (_selectedColor != value)
                {
                    var oldColor = _selectedColor;
                    _selectedColor = value;
                    OnSelectedColorChanged(new SelectedColorChangedEventArgs { NewColor = _selectedColor, OldColor = oldColor });
                }
            }
        }
 
        protected virtual void OnSelectedColorChanged(SelectedColorChangedEventArgs e)
        {
            SelectedColorChanged?.Invoke(this, e);
        }
 
        private int _side;
        /// <summary>
        /// Размер квадрата одного цвета
        /// </summary>
        protected virtual int Side
        {
            get => _side; set
            {
                _side = value;
                _hoverRect.Width = _side;
                _hoverRect.Height = _side;
                _hoverSelRect.Width = _side;
                _hoverSelRect.Height = _side;
            }
        }
 
        public SegaPalette()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
            SetColors();
            Side = 8;
 
            SelectedColor = Color.Black;
 
            _animateHoverRect.Tick += _animateHoverRect_Tick;
            _animateHoverRect.Start();
 
            _animateHoverSelRect.Tick += _animateHoverSelRect_Tick;
            _animateHoverSelRect.Start();
        }
 
        private void _animateHoverRect_Tick(object sender, EventArgs e)
        {
            var inc = _hoverColor.A >= 224 ? -50 : 50;
            _hoverColor = Color.FromArgb((_hoverColor.A + inc) % 255, _hoverColor);
            var rect = _hoverRect;
            rect.Inflate(2, 2);
            Invalidate(rect);
        }
 
        private void _animateHoverSelRect_Tick(object sender, EventArgs e)
        {
            var inc = _hoverSelColor.A >= 224 ? -150 : 150;
            _hoverSelColor = Color.FromArgb((_hoverSelColor.A + inc) % 255, _hoverSelColor);
            var rect = _hoverSelRect;
            rect.Inflate(2, 2);
            Invalidate(rect);
        }
 
        //Определение цветов палитры
        private void SetColors()
        {
            _colors = new Color[8, 64];
            var col = new double[8] { 0, 2, 4, 6, 8, 10, 12, 14 };
            var norm = new Func<double, int>((val) => (int)(val * 255 / 14));
 
            for (int i = 0; i < 8; i++)
                for (int l = 0; l < 8; l++)
                    for (int k = 0; k < 8; k++)
                        _colors[l, k + 8 * i] = Color.FromArgb(255, norm(col[l]), norm(col[k]), norm(col[i]));
        }
        private Color Inverse(Color color)
        {
            return Color.FromArgb(color.A, 255 - color.R, 255 - color.G, 255 - color.B);
        }
 
        private Color GetColor(int x, int y)
        {
            var i = _hoverRect.X / _side;
            var j = _hoverRect.Y / _side;
            i += 32 * (j / 8);
            j %= 8;
            return _colors[j, i];
        }
 
        //Прорисовка контрола
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            using (var b = new SolidBrush(Color.Empty))
                for (int i = 0; i < 8; i++)
                    for (int j = 0; j < 64; j++)
                    {
                        b.Color = _colors[i, j];
                        var x = _side * (j % 32);
                        var y = i * _side + 8 * _side * (j / 32);
                        e.Graphics.FillRectangle(b, x, y, _side, _side);
                    }
            
            //Прямоугольник выделения
            using (var pen = new Pen(Inverse(_hoverColor), 2) { Alignment = PenAlignment.Inset })
            {
                e.Graphics.DrawRectangle(pen, _hoverRect);
            }
 
            //Прямоугольник выбранного
            using (var pen = new Pen(Inverse(_hoverSelColor), 2) { Alignment = PenAlignment.Inset })
            {
                e.Graphics.DrawRectangle(pen, _hoverSelRect);
            }
        }
 
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //Положение выделения
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverRect.Location)
            {
                _hoverRect.Location = pt;
                _hoverColor = Color.FromArgb(_hoverColor.A, GetColor(e.X, e.Y));
                Invalidate();
            }
        }
 
        //Смена выбранного цвета
        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
 
            //Положение выбранного
            var pt = new Point((e.X / _side) * _side, (e.Y / _side) * _side);
            if (pt != _hoverSelRect.Location)
            {
                _hoverSelRect.Location = pt;
                _hoverSelColor = Color.FromArgb(_hoverSelColor.A, GetColor(e.X, e.Y));
                Invalidate();
            }
 
            SelectedColor = GetColor(e.X, e.Y);
        }
 
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            //Размер формы в пропорции 2:1
            Width = (Width / 32) * 32;
            Height = Width / 2;
            Side = Width / 32;
        }
 
        protected override Cursor DefaultCursor => Cursors.Hand;
 
        protected override Size DefaultSize => new Size(256, 128);
    }
 
    public class SelectedColorChangedEventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
}
0
8940 / 4852 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
09.07.2018, 20:36 25
Тоже верно. А вот два таймера ни к чему
0
46 / 20 / 5
Регистрация: 29.12.2015
Сообщений: 1,814
09.07.2018, 23:04  [ТС] 26
Цитата Сообщение от ViterAlex Посмотреть сообщение
Тоже верно. А вот два таймера ни к чему
А если нужна для каждого разная скорость. И еще. Это что ниже библиотеки NET 4.5 нельзя выбрать. Нужна минимум 3.5 желательно 2.0 Ибо данное приложение не будет совместима с xp а форум в принцыпе ради чего и делаю да там больше половина людей сидят на XP и 7. На 7 то его вообще ставить надо вручную и людям это какбы мягко выразится не по душе.

В принцыпе там проблема только с этой строкой

public event EventHandler<SelectedColorChangedEventArgs> SelectedColorChanged;

Добавлено через 2 часа 22 минуты
Допер как решать:
C#
1
2
3
4
5
public class SelectedColorChangedEventArgs : EventArgs
    {
        public Color OldColor { get; set; }
        public Color NewColor { get; set; }
    }
Очевидно что в NET 4.5 классы по умолчанию наследуют EventArgs
0
8940 / 4852 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
10.07.2018, 00:23 27
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Очевидно что в NET 4.5 классы по умолчанию наследуют EventArgs
Нет, это моя ошибка.
0
Эксперт .NET
6451 / 4053 / 1598
Регистрация: 09.05.2015
Сообщений: 9,480
10.07.2018, 01:27 28
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Очевидно что в NET 4.5 классы по умолчанию наследуют EventArgs
В новых версиях .NET просто не обязательно наследоваться от EventArgs для классов которые используются в качестве аргументов событий, ограничение было убрано...
0
10.07.2018, 01:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.07.2018, 01:27
Помогаю со студенческими работами здесь

Завасает джойстик в эмуляторе Sega
Здравствуйте, установил эмулятор сега, GENS. Подсоединил к нему джойстик DVTech, раньше работал...

Найти стратегию по описанию (SEGA)
На приставке SEGA раньше была малопопулярная пошаговая стратегия, называлась из двух слов...

Sega Genesis - Создание рогалика
Решил создать игру на Sega Genesis/Megadrive, на вооружение взял Assembler. Вопрос следующий:...

Интересует название игры для SEGA
Помню такая странноватая игрушка была мною куплена, её очень расхваливал продавец. Я тогда в ней не...

Приставки Sega, Dandy на нашем компьютере
Популярные приставки детства на компе, кто еще не знает - качаем и вспоминаем беззаботные годы! В...

Sega Genesis - Ничего не выводится на экране эмулятора
Работаю по материалу: https://huguesjohnson.com/programming/genesis/tiles-sprites/ Вот код: ;...


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

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

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