Эта заметка является продолжением предыдущих: 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 МБ).
7 коммент.:
А также всем участникам конкурса желаю удачи!
Засада :)
http://xmage.ru/?v=taptap.jpg
До этого такую игру не видел - получаю удовольствие.
"Помахивание ручкой" (приветствие) - очень в тему :)
> Засада :)
Угу… решается в 9 тапов)
Всеволод, а будет ли у вас возможность собрать и запустить под iOS и под Mac?
Конечно! :) Первая же моя цель (для доказательства мульти-платформенности Delphi XE5)!
Жена с первого раза построила роботов (она у меня - программист... ведущий программист!).
Чуть раскрывая интригу конкурса - снаряд попал в одну воронку. Еще есть проект-кандидат на эту же самую тему.
Ещё будет просьба - не срочно, чтобы Ваш проект (по-любому один из наиболее достойнейший по красоте и реализации) был локализован на англ. яз. Похвалиться Вашим достижением в англо-говорящем (international) сегменте. Там как у Вас со временем - можно пост в Вашем блоге по-английски с ссылкой на локализованный на англ. проект. Можно просто локализованную версию где-нибудь выложить, чтобы я мог "сослать" англоговорящих.
Исполняемые файлы и исходники в архивах обновлены:
(+) добавил английский язык
(!) мелкие исправления в форме настроек и рекордов
Язык выбирается автоматически (en/ru), но есть возможность указать язык явно в настройках
А почему графика на android c искажениями? Вроде как контролы векторные и все должно быть в порядке. На windows все отлично.
Вот такая она, платформа FMX. На разных ОС выглядит по-разному..
По уму, графика должна быть растровая, а не векторная - оно и выглядеть будет предсказуемо, и тормозить не будет.
Отправить комментарий