Главная страница
Навигация по странице:

  • 1. Кадровая анимация ( fli , avi , mov и т.д.). Клипы.

  • 2. Спрайтовая анимация. Спрайт

  • Методы анимации. 1. Общий метод.

  • 2 . Отсечение фона маской спрайта.

  • 3. Простая

  • Общий недостаток анимации ‑ мерцание.

  • 2. Синхронизация с растровой разверткой.

  • 3 . Промежуточный буфер в ОЗУ

  • 4 . Работа с несколькими страницами видеопамяти

  • Canvas

  • Brush

  • Additional

  • TBitMap

  • TColor

  • $000000FF .Для вывода текста (шрифтом Font

  • Отчёт по лабораторной работе ВК. L3-спрайтовая анимация. Лекция спрайтовая анимация


    Скачать 171.5 Kb.
    НазваниеЛекция спрайтовая анимация
    АнкорОтчёт по лабораторной работе ВК
    Дата14.05.2022
    Размер171.5 Kb.
    Формат файлаdoc
    Имя файлаL3-спрайтовая анимация.doc
    ТипЛекция
    #528642

    Лекция 3. СПРАЙТОВАЯ АНИМАЦИЯ



    Основной недостаток графической системы недалекого прошлого: невозможность получения динамического изменения реалистичного изображения в реальном времени. В зависимости от реалистичности и мощности техники требуется от нескольких минут до нескольких часов на рендеринг (как процесс получения 2D-картинки из 3D-описания) одного изображения-кадра (и до сих пор в Голливуде для идеальной реалистичности).

    П роблему решили следующим образом:

    1. подготовка кадров заранее (фреймов).

    2. прокрутка подготовленных кадров – анимация.


    1. Кадровая анимация
    (
    fli, avi, mov и т.д.). Клипы.

    Изображение развернуто в растр, плавность и динамичность изображения (min 15 кадров/с).

    Недостатки:

    1. 1920х1080х3байта = 6Мб, 5 сек, 75*6Мб > 450Мб – требуется много памяти

    2. медленный вывод на экран, т.к. обновляется весь кадр.
    2. Спрайтовая анимация.

    Спрайт – изображение только динамически изменяющегося объекта в одной из фаз движения на однородном фоне (черном или белом или прозрачном).

    Фон – неизменная при смене кадров часть всего изображения.

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

    На каждом шаге необходимо:
    1. восстановить фон на старом месте спрайта;
    2. рассчитать новое место спрайта и сохранить фон;
    3. вывести спрайт в рассчитанное место.

    При подготовке спрайтов решаются следующие вопросы:

    1. Сколько всего необходимо спрайтов?

    2. Как часто нужно выводить спрайты?

    3. В какие места экрана выводить?

    4. Методика анимации.

    П редварительные расчеты



    N ‑ min 2 спрайта, но лучше 4..8

    спр – частота вывода спрайтов
    (>=15 к/сек для плавности
    отображения)

    t – общее время перемещения

    t*спр – число позиций вывода

    X = Xк – Xo => шаг X = X/( t*спр)

    Y = Yк – Yo => шаг Y = Y/( t*спр)

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

    В каждом цикле координаты рассчитываются по следующим формулам:

    Xi+1 = Xi + шаг X

    Yi+1 = Yi + шаг Y

    Фазы движения спрайта (n mod N)+1 должны охватывать элементарное действие:

    Tф – промежуток времени от начальной фазы движения до конечной.

    спрTф – число фаз движения (могут циклически повторяться).
    Методы анимации.

    1. Общий метод.

    В каждой позиции:

    1. Восстанавливаем общий фон под спрайтом на старом месте.

    2. Рассчитываем новое место спрайта и запоминаем общий фон.

    3. Выводим спрайта на новое место (только пикселы изображения спрайта).

    Ф он самого спрайта должен быть прозрачным. Для этого цвет фона выбирают такой, которого нет на самом спрайте, иначе неизбежны "дырки" в изображении. Обычно используют цвет с нулевым кодом (черный). При выводе проверяем наличие пикселя-нуля, если есть – не выводим. Процедура вывода получается сложная и медленная (нет аппаратной поддержки в видеоадаптере сравнения).

    2 . Отсечение фона маской спрайта.

    О тдельно подготавливается (рисуется в граф. редакторе) спрайт и отдельно маска. И спрайт и маска должны иметь одинаковый размер. Маска (черная тень изображения на белом фоне) нужна для того, чтобы при выводе спрайта не затирался общий фон и можно было использовать в спрайте все цвета. Спрайт обязательно должен быть на черном (прозрачном) фоне. Процедура вывода использует аппаратную поддержку блочных функций AND и XOR и получается проще и быстрее.

    Этапы:

    1. Восстанавливаем общий фон на старое место под спрайтом.

    2. Рассчитываем новое место спрайта и запоминаем фон.

    3. Накладываем на новое место маску спрайта (операция AND).

    4. Н акладываем на новое место сам спрайт (операция XOR).


    3. Простая XOR-анимация.

    Свойство обратимости:

    Свойство прозрачности 0:

    Этапы:

    1. Восстанавливаем общий фона XOR-выводом спрайта на старое место.

    2. Рассчитываем новое место спрайта и XOR-выводим спрайт.

    Если фон черный (код 0), то спрайт отображается нормально, если сложный, то происходит наложение цветов ‑ сквозь спрайт просвечивается цветоинверсный фон.
    Общий недостаток анимации ‑ мерцание.

    Мерцание изображения – это общий недостаток вышеперечисленных методов анимации, когда часть времени изображение спрайта на экране отсутствует (между 1 и 3 этапами): восстанавливается общий фон под спрайтом ‑ tнет.



    М етоды подавления мерцания (tнет.->0):

    1. Перекрытие спрайтов.

    2. Синхронизация с растровой разверткой.

    3. Промежуточный буфер в ОЗУ.

    4. Работа с несколькими страницами.


    1. Перекрытие спрайтов.

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

    Недостаток: число спрайтов должно быть равно числу мест вывода для сохранения общего фона.

    Алгоритм сводится к одному действию:

    1. Рассчитываем новое место спрайта и выводим его, одновременно этим затирая спрайт на старом месте фоном, НО требуется предварительная подготовка спрайтов с актуальным фоном.


    Ожидание конца обратного
    хода луча по кадру:

    Mov dx, 3DAh

    Wait_end:

    In al, dx

    Test al, 8

    Jnz Wait_end

    Ожидание начала обратного
    хода луча по кадру:

    Wait_begin:

    In al, dx

    Test al, 8

    Jz Wait_begin
    На Pascal

    While (port[$3DA]
    and 8)<>0 do ;

    While (port[$3DA]
    and 8)=0 do ;




    2. Синхронизация с растровой разверткой.

    О братный ход кадровой развертки. При отображении картинки на мониторе луч в ЭЛТ последовательно пробегает по всем строчкам сверху вниз, а затем выключается и возвращается в начало экрана. Данный процесс и называется обратным ходом кадровой развертки; он происходит периодически (70-100 раз/сек с паузой 20% на обратный ход). В это время изображение на дисплее не формируется, и потому в видеопамяти можно делать изменения, не опасаясь, что они приведут к появлению помех на экране.

    1/100*0.2*3ГГц=6МГц (млн. команд ЦП на цикл)
    3 . Промежуточный буфер в ОЗУ

    1. Копирование общего блока (старое место + новое место спрайта) из видеобуфера в ОЗУ.

    2. Восстановление фона на старое место (копирование ОЗУ-ОЗУ).

    3. Взятие копии фона из нового места (копирование ОЗУ-ОЗУ).

    4. Наложение маски в ОЗУ.

    5. Наложение спрайта в ОЗУ.

    6. Вывод общего блока из ОЗУ в видеобуфер.


    0 ВАВА…

    1 АВАВ…
    2

    3

    4 . Работа с несколькими страницами видеопамяти

    Обычно используют две страницы видеопамяти. Одна является видимой (В) и отображается на экране монитора, другая – активная страница (А), в ней производится отрисовка следующего кадра.

    Как только следующий кадр подготовлен, страницы меняются местами (это осуществляется аппаратно за один такт), т.е. активная (с новым кадром) становится видимой, а видимая – активной и теперь в ней можно формировать новый кадр.

    Графическая библиотека BGI+ среды Delphi


    Работа с графикой в Delphi (или С++Builder) предполагает обращение к канве - свойству Canvas компонентов. Canvas Delphi это холст, который позволяет программисту иметь доступ к каждой своей точке (пикселу), и словно художнику отображать то, что требуется (BGI+ как надстройка над GDI+ Windows).

       В работе с графикой в Delphi в распоряжении программиста находятся не только канва (холст, полотно - свойство Canvas Delphi компонентов), но и карандаш (свойство Pen), и кисть (свойство Brush) того компонента или объекта, на котором предполагается рисовать. У карандаша Pen и кисти Brush можно менять цвет (свойство Color) и стиль (свойство Style), а у карандаша еще и толщину (Width) и т.п. Доступ к шрифтам предоставляет свойство канвы Font. Эти инструменты позволяют отображать как текст, так и достаточно сложные графики математического и инженерного содержания, а также рисунки. Кроме этого, работа с графикой позволяет использовать в Delphi такие ресурсы Windows как графические и видеофайлы.

       Конечно, не все компоненты в Delphi имеют эти свойства. На вкладке Additional расположен специализированный компонент TImage, специально предназначенный для рисования, но также свойство Canvas имеют, например, такие компоненты как ListBox, ComboBox, StringGrid, а также и сама Форма, которая размещает наши компоненты! Кроме этого «рисовать» можно на TPaintBox и на невидимом объекте TBitMap – контейнере (буфере в ОЗУ) рисунков.

       Основное свойство такого объекта как Canvas Delphi - Pixels[i, j] типа TColor, то есть это двумерный массив точек (пикселов), задаваемых своим цветом. Рисование на канве происходит в момент присвоения какой-либо точке канвы заданного цвета. Каждому пикселу может быть присвоен любой доступный для Windows цвет. Например, выполнение оператора

       Image1.Canvas.Pixels[100, 200]:=clRed;

    приведёт к рисованию красной точки с координатами [100, 200]. Узнать цвет пиксела можно обратным присвоением:

       Color:=Image1.Canvas.Pixels[100, 200];

       Тип TColor определён как длинное целое (LongInt). Его четыре байта содержат информацию о долях синего (B), зелёного (G), и красного (R) цветов. В 16-ричной системе это выглядит так: $00BBGGRR. Доля каждого цвета может меняться от 0 до 255. Поэтому, например, чтобы отобразить максимально красную точку, ей нужно присвоить цвет $000000FF.

    Для вывода текста (шрифтом Font) используется метод:

    TextOut(X, Y: Integer; const Text: WideString); ‑ производит вывод строки Text начиная с (X, Y) - левого верхнего пиксела текста.

    Сперва необходимо чётко уяснить, что координата (0,0) это верхний левый угол экрана. То есть значения по оси y увеличиваются вниз экрана. Соответственно, координата (0, 50) означает, что мы просто отступили на 50 пикселей от верха экрана.

    Самое главное, что надо знать при рисовании линий и фигур, это различие между пером (Pen) и кистью (Brush). Всё очень просто: перо (Pen) используется при рисовании линий или рамок, а кисть (Brush) для заполнения фигуры.

    Ниже приведены две функции, которые используются для рисования линий и обе принадлежат TCanvas:

    Имя

    Описание

    Пример

    MoveTo

    Перемещает точку начала рисования линии в указанные координаты x и y

    Canvas.MoveTo(50, 100);

    LineTo

    Рисует линию начиная с текущей позиции (см. MoveTo) до указанных координат x и y.

    Canvas.LineTo(50, 100);

    Эффект перемещения точки начала рисования линии так же достигается при помощи установки своства PenPos в канвасе... например, "Canvas.PenPos.x := 20;", "Canvas.PenPos.y := 50", или "Canvas.PenPos := Point(20,50);".

    По умолчанию, точка начала рисования установлена в (0,0), то есть, если сразу вызвать "Canvas.LineTo(100,100);" то будет нарисована линия из точки (0,0) в точку (100, 100). Точка начала рисования автоматически переместится в (100, 100), то есть, если выполнить команду "Canvas.LineTo(200, 100);", то следующая линия будет нарисована из точки (100, 100) в (200, 100). Поэтому, если мы хотим рисовать линии несоединённые друг с другом, то придётся воспользоваться методом MoveTo.

    Линия, нарисованная при помощи LineTo использует текущее перо канваса (типа TPen). Основные свойства пера, это ширина - "Canvas.Pen.Width := 4;" (при помощи которого можно задавать различную ширину линий), и цвет "Canvas.Pen.Color := clLime;".

    Для рисования фигур, в TCanvas предусмотрены, например, следующие функции:

    ИМЯ

    ОПИСАНИЕ

    ПРИМЕР

    Ellipse

    Рисует элипс, вписанный в невидимый квадрат с координатами верхнего левого угла и правого нижнего. Если координаты х и y у углов будут совпадать, то получится круг.

    Canvas.Ellipse(0,0,50,50);

    FillRect

    Заполняет прямоугольник цветом текущей кисти (brush), но никак не за пределами него.

    Canvas.FillRect( Bounds(0,0,100,100));

    FloodFill

    Заполняет данную область цветом текущей кисти, до тех пор пока не будет достигнут край.

    Canvas.FloodFill(10, 10, clBlack, fsBorder);

    Rectangle

    Рисует прямоугольник (или квадрат), заполненный цветом текущей кисти и обрамлённый цветом текущего пера

    Canvas.Rectangle( Bounds(20, 20, 50, 50));

    RoundRect

    Тоже, что и Rectangle, но с загруглёнными углами.

    Canvas.RoundRect( 20, 20, 50, 50, 3, 3);


    { Пример на Delphi 7.0 }
    unit Unit1;
    interface
    uses

    Windows, Messages,
    SysUtils, Variants,
    Classes, Graphics,
    Controls, Forms,

    Dialogs, ExtCtrls,
    StdCtrls;
    type

    TForm1 = class(TForm)



    Image1: TImage;

    CheckBox1: TCheckBox;

    Timer1: TTimer;

    procedure CheckBox1Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);

    procedure Timer1Timer(Sender: TObject);

    private



    { Private declarations }

    public

    { Public declarations }

    end;
    var

    Form1: TForm1;
    implementation
    {$R *.dfm}
    procedure TForm1.CheckBox1Click(Sender: TObject);

    begin

    Timer1.Enabled:=CheckBox1.Checked;

    end;
    VAR TB: TBitMap;

    xx,yy,dx,sn,c35 :integer;
    procedure TForm1.FormCreate(Sender: TObject);

    begin TB:=TBitmap.create;

    TB.LoadFromFile('runner.bmp'); //10 по 35х35 пикселей

    TB.Transparent:=true;

    xx:=0; dx:=1; yy:=100; sn:=0; c35:=35;

    end;
    procedure TForm1.Timer1Timer(Sender: TObject);

    var i,j :integer; cc:tcolor;

    begin //отрисовка

    Image1.Picture.LoadFromFile('fon.bmp'); //320x200

    //Image1.Canvas.Draw(xx,yy,TB); //альтернативные функции

    //Image1.Canvas.BrushCopy(Rect(xx,yy,xx+35,yy+35),TB,Rect(0,Sn,35,Sn+35),clWhite);

    for j:=Sn to Sn+c35-1 do

    for i:=0 to TB.Width-1 do begin

    if dx<0 then cc:=TB.Canvas.Pixels[c35-1-i,j] else cc:=TB.Canvas.Pixels[i,j];

    if cc<>TB.Canvas.Pixels[0,0] then

    Image1.Canvas.Pixels[xx+i,yy+j-Sn]:=cc; end;{}

    xx:=xx+dx; if (xx<0)or(xx>320-c35) then dx:=-dx;

    yy:=yy+Round(sin(xx/20)*dx);

    Sn:=Sn+c35; if Sn>= TB.Height then Sn:=0;

    end;
    end.

    Графическая библиотека FrameWork.NET MS Visual Studio



    В среде С++/С# поддерживается множественное наследование (в отличие от Delphi, где холст+карандаш+кисть+шрифт+художник – это один объект) и поэтому объекты для поддержания растровой и векторной графики не объединены изначально и требуют явных ссылок друг на друга, т.е. нужно отдельно создавать объект карандаш-Pen и кисть-Brush и художника-Graphics и связать его с холстом (например, PictureBox). Идеология FrameWork.NET описана в п.2.

    В языках С++/C# существует целая библиотека для создания графики "System.Drawing". Она автоматически подключается при создании проекта.

    Самое главное изменение, которое может ввести в тупик новичка, ‑ это кодировка цвета: здесь для него используется 4 байта ARGB, т.е. введен альфа-канал (прозрачность) и, самое непонятное, он должен быть 255 (больше 0), чтобы пиксель рисовался! Если у вас не рисуется пиксель делайте: Pix |= 0xFF000000; может и поможет.

    Прямой доступ к пикселям есть в классе BitMap через методы

    Status GetPixel(INT x, INT y, Color* color);

    Status SetPixel(INT x, INT y, const Color& color);

    Эти методы очень медленные, можно использовать групповые методы:

    Status LockBits(IN const Rect* recx, IN UINT flags, IN PixelFormat format, OUT BitmapData* lockedBitmapData)

    Status UnlockBits();

    Прозрачность цвета при копировании делается методом:

    MakeTransparent(const Color& color);

    Пример, где по нажатию кнопки на форме файл «music.bmp» отображается в PictureBox1 только красной компонентой цвета RGB:

    private void Button1_Click(System.Object sender, System.EventArgs e)

    { try { // Retrieve the image.

    image1 = new Bitmap(@"C:\My Music\music.bmp", true);

    int x, y; // Loop through the images pixels to reset color.

    for(x=0; x

    { for(y=0; y

    { Color pixelColor = image1.GetPixel(x, y);

    Color newColor = Color.FromArgb(pixelColor.R, 0, 0);

    image1.SetPixel(x, y, newColor);

    } }

    // Set the PictureBox to display the image.

    PictureBox1.Image = image1;

    // Display the pixel format in Label1.

    Label1.Text = "Pixel format: "+image1.PixelFormat.ToString();

    } catch(ArgumentException)

    { MessageBox.Show("File not found.");

    } }


    написать администратору сайта