Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.09.2014, 01:29   #1
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Восклицание Perfect Canvas, графический движок


Perfect Canvas - это простой по своему устройству, но достаточно функциональный графический движок, распространяемый с открытым исходным кодом. Изначально движок был разработан в качестве одного из проектов серии 'Открытый исходный код' команды Perfect Light для помощи в обучении начинающим программистам, но проект показался мне интересным, и было решено по мере сил развивать его. Разумеется, рассчитывать на то, что впоследствии с использованием Perfect Canvas можно будет разрабатывать 3D-игры, не стоит, - движок создан, прежде всего, в обучающих целях. Это еще одна причина, по которой в нем полностью отсутствует низкоуровневый код с использованием ассемблерных вставок - код движка удобен и понятен для новичков.

ВНИМАНИЕ! При использовании данного движка в своих проектах желательно указывать в проекте разработчиков движка (Perfect Light), а также, не лишним было бы сообщить нам о новом проекте с использованием Perfect Canvas - нам было бы приятно узнать, что движок кому-то пригодился.

Обо всех замечаниях, связанных с работой движка, а также, о найденных ошибках или важных предложениях по его улучшению, лучше всего сообщать в официальную тему, посвященную ему на форуме нашей команды, так как это единственная официальная тема для обсуждения Perfect Canvas на просторах интернета. Вы можете по своему усмотрению менять и дорабатывать движок, но, несмотря на это, важно помнить о том, что его официальные обновления всегда будут распространяться только с нашего форума!

P.S. В представленной тестовой программе основное изображение разбито на несколько частей - перемещая их при помощи левой кнопки мышки можно собрать исходное изображение (тест возможности разбиения изображения на кадры). Правой кнопкой мышки производится плавное перемещение камеры (pSlide), при этом все объекты кроме текста вверху подвластны ее изменениям. Нажатие кнопки 'S' на клавиатуре заставляет камеру дрожать.


Последний раз редактировалось SaiLight; 10.09.2014 в 01:45.
SaiLight вне форума Ответить с цитированием
Старый 10.09.2014, 01:32   #2
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Лампочка

Perfect Canvas - довольно простой по своей структуре движок, что нисколько не мешает ему иметь широкий функционал и подходить одновременно для задач начинающих и более опытных программистов. И если новичок может обучиться с его помощью методам вывода графики при помощи Canvas в Delphi, а также, ознакомиться с предлагаемой структурой графического движка, то более продвинутый пользователь увидит в Perfect Canvas возможность значительно ускорить свою разработку графических приложений. Не секрет, что вопрос вывода графики средствами Canvas сегодня встает довольно часто, и речь идет не только о компьютерных играх.

Perfect Canvas обладает широким функционалом, обеспечивающим не только удобную возможность вывода графики на экран, но и ее загрузки, за что отвечает Хранилище графики, встроенное непосредственно в движок. С ним вы получите возможность загружать файлы таких форматов как '.bmp' и '.jpg', а также, избежать повторных загрузок одного и того же файла, что, к слову, является одной из наиболее распространенных ошибок, допускаемых новичками.

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

Скачивая исходный код данного движка, вы можете заметить в архиве два модуля - это сам файл движка ('PerfectCanvas.pas') и файл вспомогательных функций ('PCanvas.Routine.pas'), на данный момент практически пустой. Основной модуль движка содержит в себе 3 класса и несколько вспомогательных типов:

Код:
//Простое событие
TEvent = Procedure();
Код:
//Структура, хранящая данные о текстуре
  TImageBlock = Record
    Image: TJPEGBitmap;//Изображение
    FrameSize: Integer;//Размер кадра
    FramesCount: Integer;//Количество кадров
    Name: String;//Имя файла текстуры
  end;
В Perfect Canvas встроена интересная возможность работы с кадрами анимации. Если при загрузке очередного изображения указать размер кадра, то, используя специальную функцию вывода (с передачей номера кадра), можно попросить движок автоматически вывести один из имеющихся кадров в изображении. В тестовой программе демонстрируется эта возможность, когда одно загруженное изображение программно разделяется на 9 составных. Причем, кадры могут храниться в текстуре как в одну линию (горизонтально), так и в несколько, и единственным ограничением на данный момент является необходимость поддержки квадратных кадров.

Теперь немного о классах, встроенных в Perfect Canvas...
SaiLight вне форума Ответить с цитированием
Старый 10.09.2014, 01:36   #3
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Лампочка

TJPEGBitmap

Самый простой и короткий класс, входящий в состав движка, является лишь дополнением к реализованному в Delphi классу TBitmap, с возможностью загрузки jpg-изображений. Вот как это реализовано:


Код:
Procedure TJPEGBitmap.LoadFromFile(const FileName: String);
var
  vFileExt: String;
  vJPEG: TJPEGImage;
begin
  if (NOT(FileExists(FileName))) then Exit;
  vFileExt := LowerCase(ExtractFileExt(FileName));
//Открытие файлов с расширением '.jpg'
  if (vFileExt = '.jpg') or (vFileExt = '.jpeg') then begin
    vJPEG := TJPEGImage.Create();
    vJPEG.LoadFromFile(FileName);
    Assign(vJPEG);
    vJPEG.Free();
  end;
//Открытие файлов с расширением '.bmp'
  if (vFileExt = '.bmp') then Inherited LoadFromFile(FileName);
end;

TCamera

Данный класс реализует камеру, входящую в состав движка Perfect Canvas и обладающую некоторыми довольно интересными свойствами. Камера может как мгновенно или плавно (с заданной скоростью) перемещаться в указанную точку, так и дрожать с заданными силой и количеством рывков. Все объекты, выводимые движком на экран, подвластны действию камеры, то есть, рисуются с заданным ею смещением (которое можно узнать, обратившись к определенным свойствам камеры), но, при необходимости, воздействие камеры на некоторые объекты можно отключать - так реализуются статичные объекты на экране (например, некоторые элементы интерфейса). Ниже будут перечислены все открытые (public) свойства класса:
  • PosX, PosY (Integer) - Смещение камеры по каждой из осей
  • Speed (Integer) - Скорость движения при вызове плавного перемещения
  • Rect (TRect) - Границы перемещения - при достижении границ камера останавливается
А также, 3 public-метода:
Код:
//Мгновенное перемещение камеры в указанную точку
Procedure pMove(X, Y: Integer);
//Плавное перемещение с заданной скоростью
Procedure pSlide(X, Y: Integer);
//Тряска камеры с заданными силой и количеством рывков
Procedure pShake(vStrength, vSteps: Integer);
Данный класс создан с учетом дальнейшей доработки, и любые ваши предложения по его усовершенствованию будут весьма кстати.

Последний раз редактировалось SaiLight; 10.09.2014 в 01:54.
SaiLight вне форума Ответить с цитированием
Старый 10.09.2014, 01:38   #4
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Лампочка

TPerfectCanvas

Основной класс движка. Ниже будут представлены все его public-свойства и методы:
  • onDraw (TEvent) - Событие, реагирующее на начало нового вывода
  • Ticks (Integer) - Количество шагов, прожитых таймером
  • Texture[Index: Integer] (TImageBlock) - Любая текстура из массива текстур
  • ScreenWidth, ScreenHeight (Integer) - Ширина и высота области вывода
  • TimerInterval (Integer) - Интервал, заданный для работы таймера
  • TransparentColor (TColor) - Стандартный цвет прозрачности для загружаемых текстур
  • BackgroundColor (TColor) - Фоновый цвет при перерисовке кадра
  • IsStretchScreen (Boolean) - Растягивается ли изображение при масштабировании области вывода?
  • IsUseCamera (Boolean) - Использовать ли камеру для последующих выводов?
Необходимо, также, сообщить, что свойство 'IsStretchScreen' на данный момент нуждается в некоей доработке. А ниже будут перечислены все public-методы класса:

Код:
//Загрузка текстуры с возвращением ее номера в массиве
Function fLoadTexture(vFileName: String; vFrameSize: Integer = 0): Integer;
//Масштабирование области вывода
Procedure pResizeScreen(vWidth, vHeight: Integer);
//Задание текущих настроек шрифта для всех последующих выводов
Procedure pBindFont(vName: String; vColor: TColor);
//Вывод текста с индивидуальными для каждого текста настройками
Procedure pTextOut(vText: String; X, Y: Integer; vSize: Integer);
//Вывод текстуры с использованием ее номера в массиве и возможностью масштабирования
Procedure pDrawTexture(vTexNum, X, Y, vWidth, vHeight: Integer);
//Вывод определенного кадра анимации (если размер кадров был передан при загрузке)
Procedure pDrawFrame(vTexNum, vFrameNum, X, Y, vWidth, vHeight: Integer);
//Вывод линии по двум точкам с заданными толщиной и цветом
Procedure pDrawLine(X1, Y1, X2, Y2, vWidth: Integer; vColor: TColor);
//Вывод многоугольника по переданным координатам, радиусу и углу поворота
Procedure pDrawPolygon(X, Y, R, vCount: Integer; vAngle: Integer = 0; vColor: TColor = clWhite);
Полезно заметить и о еще двух функциях, реализованных в движке, казалось бы, простых, но на деле часто вызывающих у новичков определенные проблемы. Это или забывается вовсе, или дается с трудом и не с первой попытки. Речь идет о встроенных проверке попадания объекта на экран при рисовании (с учетом смещения камеры, разумеется) и о двойной буферизации, исключающей мерцание объектов при рисовании.

При всем многообразии имеющихся в движке функций, процесс его подключения и использования максимально упрощен. Для подключения Perfect Canvas к работе необходимо выполнить всего 3 действия. Ниже приведен пример быстрого подключения движка:

Код:
//Событие вывода на экран
Procedure pOnDraw();
begin

end;
//Создание формы
procedure TfrmMain.FormCreate(Sender: TObject);
  vEngine := TPerfectCanvas.Create(Handle, ClientWidth, ClientHeight);
  vEngine.onDraw := pOnDraw;//Переназначение события вывода на экран
end;
//Уничтожение формы
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  vEngine.Free();
end;
Вот, вроде, и все, что в данный момент мне хотелось рассказать о графическом движке Perfect Canvas. Еще раз напомню, что любые вопросы по его функционированию, а также, идеи по дальнейшему совершенствованию только приветствуются! Самую новую из официальных версий движка вы всегда можете скачать на нашем форуме.

Среди планов на ближайшее будущее:
  • Совершенствование работы со свойством 'IsStretchScreen'
  • Исправление некоторых ошибок, связанных с масштабированием текстур
  • Возможность отвязки движка от стандартных форм в Delphi

Спасибо за внимание!
SaiLight вне форума Ответить с цитированием
Старый 10.09.2014, 21:41   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Это всё замечательно. И на форуме Вашем всё поперечитал и попересмотрел.

Однако, у меня вопрос: зачем этот движок ? Если новичкам, то им сподручнее и эффективнее в учебных целях написать самим что-то такое. Продвинутым обычно уже не надо, они уходят в более серьёзные технологии, либо у них уже свои подобные написаны.
И если честно, движком пока назвать сложно. Так, набор утилит.
Т.е. я перспектив не особо вижу, чтобы оным заниматься, кроме разве что одной - в будущем Вы будете сами его под какой-то проект использовать. В этом случае, правда, надо ещё поработать.
Если думаете продолжать работы, то можем даже скооперироваться.
phomm на форуме Ответить с цитированием
Старый 10.09.2014, 22:20   #6
apromix
PHP, Delphi
Форумчанин
 
Аватар для apromix
 
Регистрация: 07.05.2008
Сообщений: 388
По умолчанию

Кстати если TJPEGBitmap переименовать в TBitmap, то будет неплохое расширение обычного битмапа. Если закинуть в отдельный модуль, то можно использовать в своем проекте просто добавив название модуля в uses. А так это действительно не движок, а набор утилит. Но мне понравилось копаться к коде
Мыши плакали, кололись, но продолжали жрать кактус...
мои проекты
apromix вне форума Ответить с цитированием
Старый 10.09.2014, 22:54   #7
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Сообщение

phomm, написать что-то подобное в учебных целях, возможно, и эффективнее, но по своему же опыту помню, насколько это бывает трудным занятием - разобраться в том, с чем вообще никогда не сталкивался. В данном случае начинаешь искать похожие примеры в интернете, но из них - половина написана криво (потому как писалась теми же новичками), а остальную приходится собирать по частям из разных примеров. В Perfect Canvas же собрано все, что может потребоваться для вывода графики в простой 2D-игре (за основу брался опыт, полученный при разработке Galaxy Boom). То есть, даже разбираясь в этом самостоятельно, они могли бы получить определенное количество полезных знаний, имея перед собой понятный и структурированный код движка (все же, буду называть его так, если никто не против).

Чем же он полезен для более серьезных проектов? Ну, во-первых, переплюнуть OpenGL, DirectX с их Asphyre, Quad, GLScene (...) он, разумеется, не сможет - это и есть те самые 'более серьезные технологии', о которых вы говорите. Но множество проектов, в которых необходимо выводить на экран графику (в том числе и игр) не настолько широки, чтобы использовать в них подобные серьезные технологии. Например, для себя, уже сейчас вижу вполне серьезную возможность использования данного движка в этом проекте (если бы он еще не был завершен), так как его возможности позволяют подобное использование и сделали бы процесс написания игры намного более быстрым (в том числе и возможность выбора области на изображении, что в свое время было реализовано при помощи компонента Image). Согласитесь, использование OpenGL для подобного проекта недопустимо.

В итоге, как и во всех остальных проектах с открытым исходным кодом: для новичков - новые знания и готовый, 'на блюдечке' код, который приятно читать, а для более серьезных проектов - возможность сэкономить время. При этом, ни в коем случае, не утверждаю, что мною было сделано что-то из ряда вон выходящее: проект был создан за пару вечеров в свободное от остальной работы время и рассчитан, прежде всего, на новичков. Впрочем, изначально Perfect Canvas писался больше для себя - не то, чтобы я возлагал на него огромные надежды, просто хотел посмотреть, что же из этого выйдет (так как для более серьезных проектов, насколько вы знаете, у нас уже есть Система Perfect Particle, которую, также, еще нужно тестировать). Но впоследствии подумал, что лучше выложу наработки в интернет, нежели позволю им просто так лежать на моем компьютере. Разумеется, обернул все это в красивый фантик, чтобы возможные пользователи не прошли мимо.

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

Цитата:
Если думаете продолжать работы, то можем даже скооперироваться.
Почел бы за честь, если у вас будут идеи по дальнейшему развитию движка, в какой-то мере сотрудничать с вами.

Цитата:
Но мне понравилось копаться к коде
apromix, если кому-то нравится копаться в моем коде, значит, мой код стоит того, чтобы в нем покопаться, и это радует. Все же, есть определенная польза и от написания простых проектов с открытым кодом (на более сложные пока времени не хватает) - чувствуется ответственность за то, что ты написал; проверяешь каждую строчку по несколько раз, оцениваешь структуру, что-то исправляешь... В общем, хорошая мотивация для написания правильного кода.

Последний раз редактировалось SaiLight; 10.09.2014 в 22:57.
SaiLight вне форума Ответить с цитированием
Старый 11.09.2014, 08:34   #8
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Цитата:
Цитата:
Если думаете продолжать работы, то можем даже скооперироваться.
Почел бы за честь, если у вас будут идеи по дальнейшему развитию движка, в какой-то мере сотрудничать с вами.
Да у меня просто свой полудвижок есть (с GDI рендерером), когда-то пришлось его заморозить, и заниматься другими проектами, но я ещё не оставляю надежды его реанимировать.
Один из первых пунктов в планах по рефакторингу как раз абстрагирование кишок движка от вызовов канваса и gdi-операции в некий класс, который потом можно было бы даже отнаследовать и реализовать другие рендереры, например опенгл. Поэтому Ваш движок в какой-то мере близок по смыслу к направлению, которое я предполагал для сотрудничества. Но, по смыслу это как раз некий вспомогательный инструмент (рендерер) для реального движка, который выполняет несколько другую работу - берёт пачку настроечных данных от программиста (без единого системного вызова, только рабочие "требования") и формирует картинку, управляет временем жизни всего, и контролирует все аспекты автоматически, с возможностью опять же настройки.

Я в коде, в отличие от Apromix'a почти не копался, только прочитал по диагонали, но мне всегда приятно открыть код и увидеть там подробные комменты, кроме случаев капитанства, конечно. По содержанию и качеству самого кода могу сказать немного.
Например, не нравится глобалка для пёфектканваса. Не нравится FCamera.Destroy(); вместо Free или употребляемого там же FreeAndNil. Не нравятся префиксы p и f у методов, хотя это на вкус, конечно. Заглавные буквы у слов процедура, функция, контруктор и т.д. из той же оперы. Где-то использован префикс v у параметров, где-то нет, неприятно немного, лучше либо везде, либо нигде, я предпочёл использовать стиль Борланда - параметры без префиксов, кроме случая коллизии имён, тогда префикс А.
Режет глаз функция проверки попадания прямоугольника в экран, но она в названии использует не слово прямоугольник, а Square
Есть косячок и в матаппарате. Функция проверки попадания окружности в область вывода робит некорректно, учитывая углы описывающего квадрата, а может быть так, что угол попадает, но само скругление за экраном.

Вот, то, что бросилось на первый взгляд.
Да, это ещё не пристальный взгляд

Последний раз редактировалось phomm; 11.09.2014 в 08:56.
phomm на форуме Ответить с цитированием
Старый 11.09.2014, 11:00   #9
SaiLight
Форумчанин
 
Аватар для SaiLight
 
Регистрация: 10.01.2009
Сообщений: 132
Сообщение

Цитата:
Да у меня просто свой полудвижок есть (с GDI рендерером), когда-то пришлось его заморозить, и заниматься другими проектами, но я ещё не оставляю надежды его реанимировать.
Спасибо, я думаю, со временем будет видно, стоит ли вообще этим заниматься, и тогда придет понимание направлений, в которых мог бы развиваться движок (в некоей зависимости от требований предполагаемых пользователей, конечно).

Спасибо за детальный разбор кода. Насчет префиксов немного поясню (возможно, подобный подход и не является оптимальным с некоторых точек зрения). Перед именами процедур ставлю 'p', перед именами функций - 'f', это удобно, в том числе, и при просмотре методов класса во всплывающем окне - введя 'p', можно получить список всех процедур класса, и иногда это помогает быстрее найти нужный метод.

Префикс 'v' ставится перед именами всех переменных, за исключением полей и свойств класса - это визуально отличает имя переменной от константы (перед именем константы ставится префикс 'c', и пока отказаться от этого я не смог) или объекта ('tmr' перед объектом TTimer, 'btn' перед объектом TButton и т.д., хотя и это, также, переменные). Перед полями класса ставится префикс 'F', перед свойствами не ставится ничего.

Цитата:
Например, не нравится глобалка для пёфектканваса.
Скорее всего, вы имели в виду это:

Код:
vObject: TPerfectCanvas = NIL;
Единственный способ, которым удалось решить проблему с программным таймером, ведь его процедуру нельзя сделать методом своего класса. Мне данный подход тоже не нравится, и он - один из первых претендентов на возможное устранение (исправление) в будущем. Насчет же 'FCamera.Destroy' - это, скорее, была опечатка.

Остальное - с попаданием на экран и математическими недочетами - спасибо, будем постепенно исправлять. Так или иначе, буду благодарен за любую помощь по усовершенствованию кода.
SaiLight вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Надо выбрать графический движок (С++) Juffin Gamedev - cоздание игр: Unity, OpenGL, DirectX 12 11.09.2012 23:08
Графический движок OGRE 3D Blade Gamedev - cоздание игр: Unity, OpenGL, DirectX 1 16.04.2009 16:15
Помогитеу становить движок на сайт. Движок Joomla acmilan WordPress и другие CMS 2 01.04.2009 11:26