Delphi XE5: впечатления от разработки под Android
Отправил свою программу на конкурс. Саму программу показывать пока не хочу. А хочу поделиться своими впечатлениями от использования Delphi XE5 и Firemonkey. Сразу оговорюсь
Отправил свою программу на конкурс. Саму программу показывать пока не хочу. А хочу поделиться своими впечатлениями от использования Delphi XE5 и Firemonkey. Сразу оговорюсь
Отправил свою программу на конкурс. Саму программу показывать пока не хочу. А хочу поделиться своими впечатлениями от использования Delphi XE5 и Firemonkey.
Сразу оговорюсь Это мой первый проект на Firemonkey и первый опыт разработки для Android. Я использовал Delphi XE5 + Update 1 + все хотфиксы для Update 1. Тестировал только на телефоне GSmart Aku A1 (480 x 854 pixels, 4.5 inches (~218 ppi). Эмуляторы не использовал. Часто компилировал и запускал на Win32 в режиме Mobile Preview (об этом ниже). В этом проекте решил опробовать подход «как-мне-кажется-это-делают-в-java», когда и для каждого класса создавал отдельный .pas файл. В результате получилась куча юнитов и чтобы в них не запутаться пришлось раскидать их по папкам и пространствам имён….
[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Попробуем разобраться.
Изначально в условии задачи уточнялось — OnPaint не используем.
Правильно это или нет — за условиями задачи, цель была прояснить, понимает ли собеседник поведение VCL в данном
Запустите на выполнение Delphi XE3. Создайте новый проект, выбрав в меню File | New | VCL Forms Application — Delphi. Появится форма нового проекта. Щелкните мышью по новой пустой форме.
Запустите на выполнение пустую форму, щелкнув по кнопке или нажав клавиши Shift+Ctrl+F9. На экране появится пустая форма, содержащая только заголовочную строку. Закройте форму, щелкнув мышью по кнопке закрытия в заголовке формы , щелкнув правой кнопкой мыши по заголовку формы и выбрав в появившемся контекстном меню строку Закрытьили нажав клавиши Alt+F4.
В окне Object Inspector отображаются свойства и события формы.
Terminate
()
объекта Application
:
Свойство Iconпозволяет задать для формы конкретную пиктограмму, помещаемую в левый верхний угол заголовка формы. Если это свойство не задано, то у формы присутствует иконка по умолчанию.
Эта заметка является продолжением предыдущих: Tap#1, Tap#2, Tap#3, Tap#4. И в ней я хочу завершить.
Итак, игра на логическое мышление. Я решил сделать аналог игры Flip-Flop компании Gamos. На всякий случай, оговорюсь – я не ставлю перед собой цель создать коммерческий продукт. Цель другая – попробовать, покрутить, поучаствовать.
Ну и поскольку, у меня нет опыта в написании игр, не думаю, что мой аналог будет таким атмосферным, как оригинал. Однако я поэкспериментирую с размером игрового поля (не только 4 на 4), “поиграю” с векторной анимацией и масштабированием, порадую близких и коллег мобильным аналогом уже подзабытой игры.
В предыдущих заметках я рассказал о базовой фрейме TNPC. Так получилось, что эта фрейма у меня стала базовой для всех фрейм в проекте. А фрейм получилось несколько – я решил раздробить части игры именно по фреймам и в главной форме уже наладить взаимодействие между фреймами.
У меня получились:
uAni, // моя попытка сделать работу с анимацией более удобной frMain {frmMain}, // главная форма приложения uNPC {NPC: TFrame}, // базовый фрейм fraDroid {frameDroid: TFrame}, // фрейм с персонажем-роботом fraHello {frameHello: TFrame}, // фрейм с интро (оно же получилось титрами) fraDesk {frameDesk: TFrame}, // фрейм с игровым полем fraMenu {frameMenu: TFrame}, // фрейм с меню fraHelp {frameHelp: TFrame}, // фрейм с описанием как играть fraOptions {frameOptions: TFrame}, // фрейм с настройками fraScore {frameScore: TFrame}; // фрейм с рекордом и очками игрока
Всё вместе это выглядит так:
Взаимодействие между фреймами я сделал очень простым, оно происходит через главную форму. Т.е. на экземпляр главной формы ссылается глобальная переменная. При этом главная форма содержит методы:
public procedure ShowIntro; procedure StartNewGame; procedure StopGame; procedure ShowOptions; procedure ShowHelp; procedure ShowCredits; procedure RegClick; procedure RegWin;
Эти методы, теоретически, может “дёрнуть” любая фрейма – что не есть хорошо. Но для такой простой программы – вполне приемлемо.
О настройках и рекордах
Всё это хранится в обычном ini-файле, делается так:
uses .. System.IniFiles .. .. private FOptions: TMemIniFile; .. const sIniFileName = 'TapTap.ini'; .. FOptions := TMemIniFile.Create(TPath.GetHomePath + TPath.DirectorySeparatorChar + sIniFileName); .. // save options to file: FOptions.UpdateFile;
И ещё несколько слов об анимации
Мне показалось, что настройка анимации через компоненты типа TFloatAnimation в Design-Time (конкретно для задачи анимирования персонажа) не очень удобна. Потому что один TFloatAnimation-объект модифицирует всего одно свойство. (А ещё, при большом количестве объектов анимации может произойти рассинхронизация.) Поэтому, я пошёл немного другим путём.
Идея такая: анимацию сложного (составного) объекта помещаем в одну процедуру с входным параметром AProgress: Single, значения которого варьируются от 0 до 1. Задача процедуры – установить положение объекта на момент времени AProgress. При этом, в теле одной процедуры могут меняться и координаты и размеры разных составляющих объекта. Пример такой процедуры был в предыдущей заметке – см. метод ProcessOpenCloseAnimation).
Забота за вызов такой процедуры перекладывается на другой объект, который, по сути, состоит из TFloatAnimation. Если же надо вызвать последовательно несколько процедур, то их можно поместить в список. Так у меня “родился” модуль uAni.pas – ещё черновой, но уже рабочий.
Такой подход дал мне возможность всего одним TFloatAnimation-объектом анимировать смену состояний сразу у нескольких персонажей.
Вместо заключения
На текущий момент, игра оставляет впечатление недоделанности. Тут, конечно, есть что доводить до ума. У меня было ещё несколько идей и с уровнями сложности, и с анимацией, и с выбором персонажей, и с озвучкой (этого, кстати, вообще нет), и с рекордами (в плане внешнего оформления – тут я откровенно схалтурил). Но, надо понимать, что всё это требует времени. (Кстати, на написание заметок в блог порой уходит больше времени, чем на программирование.)
С другой стороны, игра получилась вполне “играбельной”. В общем, я вполне удовлетворён результатом и надеюсь, что и вы не останетесь равнодушными.
Скачать: исходники (zip-архив, 93.4 КБ), Win32-exe (zip-архив, 2.47 МБ), Android-apk (zip-архив, 6.33 МБ).
Это уже достаточно старая задача, лет семь (если не отказала память) живет в моих тестах на профпригодность, выдаваемых кандидатам при собеседовании.
В отличии от прошлой задачи,
Откуда вообще появляются такие вот непонятные куски кода в которых различные авторы предлагают искать ошибки? Вопрос по сути философский — народное творчество 🙂
Благодаря народному творчеству
Свойство
|
Описание
|
ActiveControl
|
Содержит имя одного из объектов на форме, который в настоящий момент имеет фокус. Имя элемента на этапе проектирования выбирается из выпадающего списка. Этот элемент получит фокус при первом отображении формы.
|
Align
|
Задает выравнивание формы на экране монитора. Значениями являются:
· alNone (значение по умолчанию) — выравнивание формы производиться не будет,
· alBottom — форма выравнивается по нижней части экрана,
· alClient — форма выравнивается по всей поверхности экрана,
· alCustom — у формы будут все элементы управления, заданные другими свойствами формы, размер формы нельзя изменять во время выполнения,
· alLeft — форма выравнивается по левой части экрана,
· alRight — форма выравнивается по правой части экрана,
· alTop — форма выравнивается по верхней части экрана.
|
AlphaBlend
|
Определяет, может ли окно быть прозрачным (true) или нет (false). Свойство AlphaBlendValue задает степень прозрачности окна.
|
AlphaBlendValue
|
Определяет степень прозрачности окна: 0 — окно совершенно прозрачно, 255 — непрозрачно. Свойство AlphaBlend должно быть установлено в значение true.
|
AutoScroll
|
Определяет, будут ли в окне автоматически появляться полосы прокрутки, если при изменении пользователем размеров окна будут скрыты визуальные элементы (true) или нет (false). При этом свойство AutoSize должно быть установлено в значение false.
|
AutoSize
|
Указывает, может ли пользователь изменять размеры окна таким образом, чтобы скрывались визуальные элементы, расположенные на окне (значение по умолчанию false), или возможно только такое изменение размеров, при котором остаются видимыми все элементы (значение true).
|
BorderIcon
|
Определяет наличие кнопок в заголовке формы. Подсвойствами, принимающими значение true или false, являются:
· biSystemMenu — наличие системного меню,
· biMinimize — наличие кнопки минимизации,
· biMaximize — наличие кнопки максимизации,
· biHelp — наличие кнопки помощи.
|
BorderStyle
|
Указывает вид и поведение ограничивающей рамки у формы. Значениями являются:
· bsNone — форма не будет иметь текста заголовка, системного меню, кнопок минимизации, максимизации и закрытия,
· bsDialog — у формы будут присутствовать только системное меню и кнопка закрытия, размер формы нельзя изменять во время выполнения,
· bsSingle — у формы будут присутствовать все элементы управления, заданные другими свойствами формы, размер формы нельзя изменять во время выполнения,
· bsSizable — размеры формы можно изменять во время выполнения (значение по умолчанию),
· bsToolWindow — размеры формы нельзя изменять во время выполнения программы, форма имеет тонкую границу, у формы присутствует только кнопка закрытия. Системное меню отсутствует. Заголовок формы имеет высоту меньше обычного,
· bsSizeToolWin — вариант похож на задание bsToolWindow, при этом размер формы можно изменять.
|
Caption
|
Текст в заголовке окна.
|
ClientHeight
|
Высота клиентской части окна в пикселах.
|
ClientWidth
|
Ширина клиентской части окна в пикселах.
|
Color
|
Задает цвет фона формы. Значение выбирается из выпадающего списка.
|
Constraints
|
Задает ограничения на размер формы в пикселах. Подсвойствами являются:
· MaxHeight — максимальная высота формы, если указан ноль, размер не ограничивается,
· MaxWidth — максимальная ширина формы, если указан ноль, размер не ограничивается,
· MinHeight — минимальная высота формы, если указан ноль, размер не ограничивается,
· MinWidth — минимальная ширина формы, если указан ноль, размер не ограничивается.
|
Cursor
|
Задает вид курсора мыши, который появляется при наведении мыши на форму. Выбирается из выпадающего списка.
|
Enabled
|
Указывает, может ли форма принимать действия пользователя — щелчки мышью по кнопкам и элементам меню, ввод данных в поля Edit (значение по умолчанию true). Если задано false, то все диалоговые элементы формы блокируются.
|
Font
|
Задает характеристики шрифта для формы по умолчанию. Эти характеристики будут копироваться для всех компонентов, помещаемых на форму.
|
Height
|
Высота окна в пикселах.
|
Icon
|
Задает иконку, помещаемую в заголовок формы. При загрузке иконки вызывается обычное диалоговое окно выбора рисунка.
|
KeyPreview
|
Определяет, будут ли события нажатия пользователем клавиш перехватываться соответствующими событиями формы (значение true) или нет (значение по умолчанию false).
|
Left
|
Определяет положение на экране левого верхнего края окна в пикселах при старте формы по горизонтали.
|
Name
|
Имя формы. Создается при проектировании, не может изменяться во время выполнения программы.
|
Position
|
Задает положение и размер формы при ее первом выводе на экран. Может принимать следующие значения:
· poDefault — начальное положение и размер формы будут определяться операционной системой,
· poDefaultPosOnly — начальное положение формы будет определяться операционной системой,
· poDefaultSizeOnly — размер формы будет определяться операционной системой,
· poDesigned — начальное положение и размер формы будут такими же, как они были установлены при проектировании формы,
· poDesktopCenter и poScreenCenter — форма располагается в центре экрана,
· poMainFormCenter — форма располагается в центре главной формы,
· poOwnerFormCenter — форма располагается в центре родительской формы.
|
Top
|
Определяет положение на экране левого верхнего края окна в пикселах при старте формы по вертикали.
|
Visible
|
Задает, видима ли форма во время выполнения (значение true) или нет (false).
|
Width
|
Ширина окна в пикселах.
|
WindowState
|
Указывает, будет ли форма при начальном появлении на экране минимизированной, максимизированной или у нее будет размер, заданный при проектировании. Принимает следующие значения:
· Normal — форма имеет размер, заданный при проектировании,
· Minimized — форма будет минимизированной,
· Maximized — форма будет максимизированной, развернутой на весь экран.
|
Метод
|
Описание
|
Show
|
Вызывает на выполнение указанную форму. Таким методом можно вызвать произвольное количество экземпляров одной формы. В процессе выполнения программы можно переключаться между различными экземплярами формы.
|
ShowModal
|
Вызывает на выполнение форму в диалоговом, или в так называемом модальном, режиме. Переключиться на другую форму данного приложения невозможно, пока не будет закрыта модальная форма.
|
Close
|
Закрывает указанную форму. Если форма является главной в приложении, то завершается работа всего приложения.
|
Основную идею задачек я подсмотрел у Александра Алексеева (более известного как GUNSMOKER), и подумал — а почему бы и мне не открыть такой подраздел, ибо
Надоело мне, что Delphi предлагает каждый новый проект сохранить в папке My documents. И задался я вопросом, а как бы эту папку изменить. Оказалось –