Простая анимация с использованием C # / Windows Forms - PullRequest
52 голосов
/ 09 октября 2008

Мне нужно отключить быструю анимацию в C # / Windows Forms для отображения Хэллоуина. Просто несколько 2D фигур, движущихся на сплошном фоне. Так как это всего лишь быстрый одноразовый проект, я действительно не хочу устанавливать и изучать для этого целый новый набор инструментов. (Наборы разработчика DirectX, Silverlight, Flash и т. Д.) Я также должен установить это на нескольких компьютерах, так что все, кроме базовых .Net framework (2.0), будет проблемой в заднице.

Для инструментов у меня есть VS2k8, 25-летний опыт разработки, тачка, плащ Холокоста и около 2 дней, чтобы его выбить. Я не делал анимацию с тех пор, как использую ассемблер на своем Atari 130XE (ура для перелистывания страниц и графики игрока / ракеты!)

Совет? Вот некоторые вещи, которые я хотел бы знать:

  • Я могу рисовать на любом пустом виджете (например, на панели), манипулируя его обработчиком OnPaint, верно? Вот так я бы нарисовал собственный виджет. Есть ли лучшая техника, чем эта?
  • Есть ли в Windows Forms техника перелистывания страниц для такого рода вещей? Я не рассчитываю на высокую частоту кадров, просто на столько мерцание / рисование, сколько необходимо.

Спасибо.

Post Mortem Edit ... "пару дней спустя"

Ну, проект завершен. Приведенные ниже ссылки пригодились, хотя некоторые из них были 404. (Я бы хотел, чтобы SO позволял пометить более одного ответа как «правильный»). Самая большая проблема, которую мне пришлось преодолеть, - это мерцание и постоянная ошибка, когда я пытался нарисовать форму напрямую.

  • Использование события OnPaint для формы: плохая идея. Я никогда не заставлял это работать; много таинственных ошибок (переполнение стека или ArgumentNullExceptions). Я использовал панель размером для заполнения формы, и она работала нормально.
  • В любом случае использование метода OnPaint медленное. Где-то в Интернете я читал, что создание PaintEventArgs было медленным, и они не шутили. Много мерцания ушло, когда я отказался от этого. Пропустите OnPaint / Invalidate () и просто нарисуйте его самостоятельно.
  • Установка всех параметров «двойной буферизации» в форме все еще оставляла некоторое мерцание, которое необходимо было исправить. (И я нашел противоречивые документы, в которых говорилось «установите их на элементе управления» и «установите их на форме». У элементов управления нет метода .SetStyle ().) Я не тестировал без них, поэтому они могут быть делать что-то (this это форма):

        this.SetStyle(ControlStyles.UserPaint, true);
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    

Итак, рабочая лошадка кода выглядит так (pf - это панель управления):

    void PaintPlayField()
    {
        Bitmap bufl = new Bitmap(pf.Width, pf.Height);
        using (Graphics g = Graphics.FromImage(bufl))
        {
            g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pf.Width, pf.Height));
            DrawItems(g);
            DrawMoreItems(g);
            pf.CreateGraphics().DrawImageUnscaled(bufl, 0, 0);
        }
    }

И я только что вызвал PaintPlayField изнутри цикла Timer. Нет мерцания вообще.

Ответы [ 2 ]

15 голосов
/ 09 октября 2008

Установите таймер на желаемую частоту кадров. При каждом срабатывании таймера внутреннее представление фигур на экране (вашей модели) в соответствии с движением анимации, которое вы хотите достичь, затем вызывает Invalidate(true). Внутри OnPaint просто нарисуйте модель на экране.

Ах да, и вы, вероятно, хотите включить Двойную буферизацию (это похоже на автоматическое перелистывание страниц).

7 голосов
/ 09 октября 2008

2d Game Primer

Анимация по таймеру

Оба они дают хорошие примеры анимации. Код довольно прост. Я использовал их, когда мне нужно было сделать быструю анимацию для моего сына.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...