Как перекрашивать в Panel Smooth в форме окна

Как мне перекрасить панель в гладкую?

Я использую таймер, который аннулирует панель (panel1.Invalidate();) каждые 300 мс, а затем с событием panel1_Paint я добавляю изображения на эту панель, проблема в том, что похоже, что она прыгает, и мне нужно перемещать по ней одно изображение так быстро как могу.

Это ссылка на проблему с отображением экрана: http://screencast.com/t/HdtIV99YN

 private void panel1_Paint(object sender, PaintEventArgs e)
            {
                PaintMapObstacles(e);
                PaintMapStartAndGoal(e);

                if (trayectoryIndex < 1000)
                {
                   MapPoint point =  GetTrayectoryPoint(0, trayectoryIndex);
                   e.Graphics.DrawImage(new Bitmap("robot.jpg"), point.X*squareSize, point.Y*squareSize, 60, 60);
                   trayectoryIndex++;
               }
            }
     private void PaintMapStartAndGoal(PaintEventArgs e)
            {
                MapPoint start = new MapPoint { X = 0, Y = 0 };
                MapPoint goal = new MapPoint { X = 7, Y = 8 };
                   // e.Graphics.DrawImage(new Bitmap("start.jpg"), start.X * squareSize, start.Y * squareSize, 60, 60);
                    e.Graphics.DrawImage(new Bitmap("goal.jpg"), goal.X * squareSize, goal.Y * squareSize, 60, 60);
                    isFirstRun = true;
            }


        private void PaintMapObstacles(PaintEventArgs e)
            {

                foreach (MapPoint mpoint in obstacles.Obstacles)
                {
                    e.Graphics.DrawImage(new Bitmap("obstacle.png"), mpoint.X * squareSize, mpoint.Y * squareSize, 60, 60);  
                }
            }

         private void PanelTimer_Tick(object sender, EventArgs e)
            {

                panel1.Invalidate();
            }

person Devsined    schedule 05.03.2014    source источник
comment
чувак, серьезно, winforms не подходит для игр (ни чего другого, что я могу придумать в 2014 году). Если вам нужен фреймворк для игр, используйте XNA или MonoGame. В противном случае для простых настольных 2D-игр вы можете использовать WPF.   -  person Federico Berasategui    schedule 06.03.2014
comment
@HighCore, вы совершенно правы. Однако главная идея этого проекта - не симуляция. Я использую ИИ с A * и различными методами обучения с подкреплением, и я не хочу тратить слишком много времени на визуализацию результатов. Я немного знаю винфомеров из своего прошлого.   -  person Devsined    schedule 06.03.2014
comment
если вы don't want to spend to much time doing the visualization, вам действительно следует использовать соответствующие технологии. Принуждение устаревшей технологии к чему-то, для чего она действительно не подходит, приведет к потере ужасного количества времени. Не говоря уже о том, что подход winforms, использующий слишком много кода для всего, сам по себе уже гораздо более громоздкий, чем использование правильного DataBinding и тому подобного.   -  person Federico Berasategui    schedule 06.03.2014


Ответы (1)


Это называется «мерцание» - артефакт, который всегда присутствует, когда вы перерисовываете окно с нуля. Это особенно заметно в вашей программе, потому что ваш код рисования очень неэффективен. Вы видите, как прорисовывается фон окна, стирая старую картину. Затем медленно возвращаем растровые изображения обратно на фон. Шаг стирания виден невооруженным глазом и выглядит как мерцание.

Общее лекарство от мерцания - это двойная буферизация, при которой содержимое окна сначала преобразуется в растровое изображение, а затем быстро переносится растровое изображение на экран. Это встроенная функция для Winforms, свойство DoubleBuffered включает ее. Двойная буферизация не включена по умолчанию для класса Panel, он был разработан как контейнерный элемент управления, который не выполняет рисование самостоятельно, кроме рисования фона. PictureBox будет работать и в вашем случае, у него по умолчанию включена двойная буферизация. Или вы можете включить двойную буферизацию для класса Panel, показан здесь.

Вы действительно хотите в конечном итоге решить проблемы с кодом рисования, помимо того, что он очень медленный, он может привести к сбою вашей программы с OutOfMemoryException. Проблема, вызванная тем, как вы используете класс Bitmap, должна быть устранена после того, как вы ее использовали. Всегда используйте оператор using для объектов System.Drawing.

Вы сделаете это намного быстрее, создав растровые изображения всего один раз, конструктор формы - лучшее место. Вы делаете это действительно быстро, предварительно масштабируя растровые изображения до размеров сетки и обращая внимание на формат пикселей. PixelFormat.Format32bppPArgb напрямую совместим с форматом буфера кадра практически любого современного видеоадаптера, растровое изображение можно напрямую скопировать в буфер кадра без преобразования. В десять раз быстрее, чем все остальные форматы. Код преобразования находится здесь.

person Hans Passant    schedule 05.03.2014