Блог Александра Божко
Архивы
Рубрики

Firemonkey на практике

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

Цитирую Ярослава Бровина:

Главные отличия TListView от TListBox в:

  1. TListBoxItem - контрол, TListViewItem - нет
  2. В TListBoxItem можно добавлять любые контролы, используя Parent. В TListVIewItem - нет.
  3. TListVIewItem хранит только данные для отображения
  4. TListVIewItem сам выполняет отрисовку хранимых данных через метод Render
  5. За счет собственно ручной отрисовки в TListVIewItem достигается прирост скорости и малое потребление памяти (хранение только актуальных данных)
  6. Чтобы создать свой вариант TListViewItem, нужно создать свой класс итема, в нем реализовать требуемые данные (например время) и создать in-place редактор для редактирования времени, зарегистрировать его и т. д.

 

Сам по себе факт повышения производительности и уменьшения потребления памяти – веский аргумент в пользу использования TListView. Но есть и еще кое что.

Во многих Android приложениях мне приходилось наблюдать следующую реализацию списков. При нажатии на элемент списка (Item, если придерживаться выбранной терминологии), производится определенное действие. Обычно вызывается новая форма для редактирования данных. Но при нажатии с удерживанием (Long Tap) производится совершенно другое действие. И эти события не пересекаются. Иными словами Android приложения умеют четко различать “длинное нажатие” от “обычного”. Более того, ни одно из этих событий не срабатывает при скроллинге списка. Наглядный пример – список писем в Яндекс Почта.

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

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

“…какими свойствами определяются координаты поверхностей и условно центра фигуры после загрузки произвольного объекта DAE в Model3D во время исполнения программы? Т.к. даже центр объекта далеко не всегда совпадает с центром модели…”

Собственно, данный вопрос давно интересовал меня самого. Использование моделей, созданных во внешних 3D редакторах – мощный инструмент. Но для того, что бы он стал действительно полезным, нам необходимо правильно расположить модель на форме. Это не всегда просто сделать даже в режиме проектирования, не говоря уже о RunTime.

Google SketchUp 8

Google SketchUp 8

И, для того, чтобы  разобраться с данным вопросом, я решил провести несколько экспериментов. Для создания модели я использовал Google SketchUp 8, основное преимущество которого – бесплатность. Я  уже упоминал об этом редакторе ранее. Читать далее

В преддверии Чемпионата Европы по футболу я решил реанимировать свою экспериментальное приложение, моделирующее полёт мяча на футбольном поле. Более того, появилось желание придать этому приложению некоторую осмысленность. На идею создания миниигры меня натолкнул конкурс в  футбольной телепередаче. Суть проста. Журналист берет сумку с футболками и едет на тренировочную базу футбольной команды. Игроки команды с центра поля пытаются попасть в перекладину. Попавшему вручается футболка с надписью “Я попал!”.

Естественно, никто не попадает… Журналист забирает футболки и уезжает. Зато на память остается масса позитива…

Даже самому захотелось попинать мячик. А кто мешает? К тому же заготовка футбольного поля и летающий мяч уже есть. Осталось сделать систему управления, внешний антураж и, пожалуй, самое сложное – определить попадание мяча в перекладину. За основу я взял более точную модель, работающую с помощью таймера.

Управление

Для того, чтобы задать параметры удара нам необходимо обозначить силу удара и его направление. Направление задается углами по осям X и Y. Конечно, проще всего было бы реализовать, например, с помощью TComboTrackBar. Но такой вариант имеет серьезный недостаток – достаточно выставить параметры удара один раз, и после этого продолжать бить с теми же параметрами. Решение для организации более интересного геймплея я подсмотрел в рекламных банерах. Все очень просто.

Два компонента TPie динамически изменяют свои значения (реализовано с помощью таймера). За силу удара отвечает TProgressBar. Обработчик таймера выглядит приерно так:

procedure TMy3DForm.tmAngleYTimer(Sender: TObject);
begin
if UD then
PieYAngle.StartAngle:= PieYAngle.StartAngle+1
else
PieYAngle.StartAngle:= PieYAngle.StartAngle-1;

if (PieYAngle.StartAngle=0) OR (PieYAngle.StartAngle=-90) then
UD:= not UD;
end;

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

Реализовав все это, я обнаружил, что попасть в перекладину не легче чем настоящим мячем на настоящем поле.

Попадание.

Определение попадания мяча в перекладину интересная с академической точки зрения задача. В FireMonkey нет никаких встроенных механизмов обнаружения коллизий, поэтому сам факт попадания пришлось рассчитывать. Вычисления я делал последовательно по плоскостям. Т.е., если мяч попадает в плоскость, ворот, то считаем может-ли он пересечься с перекладиной по высоте, а затем и по ширине (т.е. не пролетел-ли он левее или правее перекладины). При этом учитываются толщина перекладины и радиус мяча.

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

Что дальше?

В добавок к сделаному я хотел бы еще оснастить футбольное поле несоклькими 3D модалями, для большей зрелищности процесса. Как только приложение будет протестировано, я планирую опубликовать его здесь с иходным кодом. Надеюсь до начала Евро 2012 я успею это сделать.

А до начала Чемпионата не пропустите конференцию “Кросс-платформа 2012″!

Другие статьи серии:

Firemonkey на практике #0
Firemonkey на практике #1
Firemonkey на практике #2. Освещение и материал поверхности 3D объектов
Firemonkey на практике #2. Движение 3D объектов
Firemonkey на практике #3. Использование 3D моделей
Firemonkey на практике #5.

Прежде чем приступить к написанию этого поста хочу напомнить, что скоро заканчивается срок действия специального предложения от Embarcadero, согласно которому обновиться до XE2 могут владельцы любой версии Delphi, C++ Builder или Rad Studio. Одновременно заканчивается и акция “Купите один продукт – второй получите бесплатно!”.

Вы еще можете успеть воспользоваться акционным предложением и купить Delphi, C++ Builder или Rad Studio on-line.  А резиденты Украины могут воспользоваться акционным предложением на сайте “Delphi в Украине”.

Несколько слов про четвертый апдейт. По части 3D в FireMonkey поменялось довольно много. Кое что из написанного мной в предыдущих постах утратило актуальность. Вероятно прийдется произвести ревизию текста и кода.

Ну а теперь, непосредственно к теме повествования.

В FireMonkey приложениях можно успешно использовать 3D модели. Об этом я говорил в предыдущих постах. Для того, что бы отобразить модель на форме используется компонент TModel3D. В настоящий момент поддерживаются три формата моделей (*.ase, *.dae и *.obj). За выбор модели отвечает свойство MeshCollection. Проблема же заключается в том, что разные 3D редакторы поддерживают эти форматы по разному. И некоторые модели способны “повесить” IDE при загрузке. Сегодня существует достаточно много редакторов, но большинство из них платные. Да и создание моделей требуют определенных навыков. Готовые же модели также стоят приличных денег. Тем не менее, бесплатные решения бывают хорошими, особенно если их создает Google.

Рекомендую Google SketchUp. Легкий бесплатный 3D редактор. Но самое ценное то, что существует огромная коллекция бесплатных моделей для этого редактора. И эти модели абсолютно корректно открываются в Delphi (следует выполнить экспорт в формат *.dae).

Нашлась даже модель родного ОСК “Металлист”, где уже через три месяца пройдут игры Евро 2012. Как видно на ролике, эта довольно сложная модель прекрасно отображается в FireMonkey программе.

В принципе, работа с моделями не представляет из себя ничего сложного. В приведеном выше примере модель размещена в центре формы. Там же помещен объект TDummy, к которому привязана камера. Вращение TDummy создает иллюзию вращения камеры вокруг стадиона.

Код приложения приводить не буду, при желании вы сами сможете установить Google SketchUp и совершить экскурсию по стадионам, принимающим Евро 2012 с помощью FireMonkey.

Если вы знаете другие бесплатные редакторы и коллекции моделей – буду признателен за ссылку.

И в заключение – небольшой анонс. В ближайшее время на DelphiFeeds.ru будет объявлен новый конкурс. Следите за новостями.

Другие статьи серии:

Firemonkey на практике #0
Firemonkey на практике #1
Firemonkey на практике #2. Освещение и материал поверхности 3D объектов
Firemonkey на практике #2. Движение 3D объектов
Firemonkey на практике #4. Ты попал!
Firemonkey на практике #5.

Перед тем как почесть этот пост я советую посмотреть ролик Всеволода Леонова, посвященный анимации.

Собственно, существует, как минимум два способа реализовать движение объектов в FireMonkey.

Первый из них – банально менять координаты объекта по таймеру.

Второй – использовать компонент TFloatAnimation.

На видео проиллюстрирована реализация движения тела, брошенного под углом к горизонту обеими способами.

И здесь можно увидеть, что траектории полета мячей немного отличаются. Почему? Давайте попробуем разобраться.

Левый мяч “летит” с помощью таймера. Код примерно такой:

Читать далее

Как и обещал, продолжаю повествование о FireMonkey.

Сегодня несколько слов об освещении 3D сцены и об окраске поверхностей 3D объектов. Не смотря на кажущуюся простоту, тема довольно  интересная.

Представьте себе обычную комнату, с мебелью и другими предметами интерьера, в которой полностью отсутствует освещение. Теперь давайте создадим новую 3D форму, поместим в ней несколько 3D объектов и… покрасим ее в черный цвет. Примерно так:

self.Color:= TAlphaColors.Null;

Фактически, таким образом,  мы получим модель идеальной темной комнаты. В которой, как справедливо заметил Конфуций, очень трудно искать черную кошку. В роли кошек, в нашем случае выступают 3D фигуры. Ни одной фигуры на форме, как вы понимаете, не видно. Вот с этого места, на мой взгляд, и следует рассказывать об освещении и свойстве 3D объектов FireMonkey - Material.

property Material: TMaterial read FMaterial write SetMaterial; Читать далее

К сожалению, как и большинство наших Delphi блоггеров, я страдаю хроническим цейтнотом. И чем ближе к Новому году, тем острее он ощущается.

Тем не менее, как я и обещал, продолжаю серию Firemonkey на практике. Документации по новому фреймворку пока мало, приходится разбираться, что называется “на ощупь”. Поэтому, особо ценными будут ваши комментарии. Помимо, этой рубрики, я взялся за перевод материала Марко Канту Откройте для себя FireMonkey, платформу для создания бизнес-приложений следующего поколения. На праздниках добью, ведь у меня же будут целых два дополнительных выходных! :)

Ad rem! Сегодня мы поговорим о камерах.

Как только мы создали новую FireMonkey 3D форму, мы сразу можем размещать на ней 3D объекты. И эти объекты сразу же становятся видимыми на форме. Если мы разместим, предположим цилиндр (TCylinder) в центре формы (а именно в центр формы новые компоненты постоянно и норовят попасть при размещении на форме), то мы увидим “горизонтально развернутый” цилиндр. Мы можем переместить его в пространстве или развернуть, изменив свойство RotationAngle. Но у нас имеется еще одна замечательная возможность. Мы можем посмотреть на нашу 3D фигуру с другой точки. Для этого разместим на форме компонент TCamera. Значение свойства Position.Z установим -5. Остальные свойства менять не будем. Читать далее

FireMonkey– новая библиотека классов, появившаяся в Delphi и C++ Builder XE2 – имеет два принципиальных отличия от привычной VCL.

Во-первых, она позволяет создавать кроссплатформенные приложения. Во вторых, кроме обычных «плоских» приложений FireMonkey позволяет создавать 3D приложения. Именно с рассмотрения последних, я и начну данный цикл.

newProj

Насколько я понял, единственным отличием FireMonkey 3D Application от FireMonkey HD Application заключается в том, что главная форма наследуется не от класса TForm из модуля FMX.Forms, а от класса TForm3D того же модуля. Я акцентирую внимание на модуле потому, что VCL класс TForm описан в модуле Forms. Использование точки в названии модуля не является аналогией пространства имен .Net. Просто в названии модуля теперь можно использовать точку.

Создадим новый проект FireMonkey 3D Application.  Главная форма проекта будет “трехмерной”. Если мы сейчас попытаемся “положить” на такую форму обычный элемент управления, например кнопку, то отображаться не будет. Тем не менее, в окне Structure мы сможем найти эту кнопку.  И в коде так же будет присутствовать строка

Button1: TButton;

Зато если мы разместим на форме любой компонент из  группы 3D  Shapes (пусть это будет плоскость TPlane), то он сразу же отобразиться на форме. Забегая наперед скажу,  что и «классические» двумерные контролы тоже вполне можно использовать в FireMonkey 3D приложениях. Но об этом чуть позже, а пока вернемся к плоскости.

Попытавшись подвигать только что созданную плоскость Plane1 по форме, можно заметить, что данный контрол не только меняет свое местоположение, но и особым образом видоизменяет форму. При этом создается полная иллюзия объемности. Если «зацепить» объект за специально выделенные точки, то можно менять его размер (ширину, высоту и глубину) и угол поворота в пространстве. Однако с помощью мышки правильно расположить объект довольно не просто. Подобно управлению в трехмерных компьютерных играх, тут нужна определенная сноровка.

Читать далее

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика