В настоящее время современные объектно-ориентированные среды программирования предоставляют пользователю широкий выбор инструментов по разработке проектов различного типа. Программист может создавать как стандартные консольные приложения, проекты на форме, так и достаточно узконаправленные приложения, например, текстовое приложение FCPUnit или программы InstantFPC. В тоже время в независимости от типа проекта каждый из них должен отвечать ряду базовых принципов. Одним из таких важнейших принципов является принцип наглядности, в соответствии с которым информация представленная в проекте должна легко зрительно восприниматься любым пользователем. Особенно это важно в программных продуктах социальной направленности [8] и обучающих программных средствах [9]. Высокая степень зрительного восприятия достигается в программных продуктах за счет графических элементов интерфейса и диалоговых компонентов программных продуктов.
Как известно в объектно-ориентированных средах программирования очень большое внимание уделяется работе с графическими объектами, а также процессу взаимодействия с ними. Большинство современных приложений представляют собой проекты на форме, на которой могут быть одновременно размещены графические объекты различного класса [4]. Например, программист может помещать нужные ему изображения в такие объекты как:
- TBitBtn – кнопка, на которую можно нанести изображение;
- TImage – объект, предназначенный непосредственно для помещения изображения на форму;
- задний фон формы при помощи функции self.canvas.draw (рис. 1).
Рис. 1. Графические элементы в среде Lazarus
Подобного рода объекты существуют в каждой современной объектно-ориентированной среде программирования. Это позволяет разрабатывать приложения с качественным графическим интерфейсом. Для этого можно использовать как более простые, так и более мощные программные среды. От сред программирования MS Visual Studio и Embarcadero Studio до бесплатно распространяемой среды разработок программного обеспечения Lazarus.
В тоже время, несмотря на возможности используемой объектно-ориентированной среды программирования, наличие большого количества объектов на форме может негативно сказаться на производительности приложения. В качестве примера можно привести игровое приложение DX-Ball. Цель компьютерной игры состоит в том, чтобы, управляя движением шарика на поле, разбить им все имеющиеся блоки (рис. 2).
Рис. 2. Схематические изображение DX-Ball
Если размещать каждый блок на форме, как отдельный объект класса Image, то это обернется не только большой нагрузкой на ресурсы компьютера, но и необходимостью прописывать внутри программы избыточно большое количество повторяющегося программного кода. В связи с этим предложим один из вариантов решения данной проблемы, которая возникла при реализации проекта DX-Ball в объектно-ориентированной среде разработок Lazarus.
В начале производится расчет количества блоков, которое может быть помещено на имеющуюся форму по горизонтали и вертикали. В примере на рисунке 3 число блоков по горизонтали равно восемнадцати, а по вертикали равно восьми. Таким образом, с помощью рядов блоков построчно задают изображение (рис. 3).
Рис. 3. Число блоков на экране
На основе данной информации создается двумерный массив, размером восемнадцать на восемь. В дальнейшем эта матрица и будет являться «блоками» на экране. По умолчанию все элементы данной матрицы являются единицы.
При запуске программы соответствующая процедура последовательно «рисует» на форме восемнадцать блоков, начиная с левого верхнего угла. Далее программа переходит на следующий ряд и вызывает процедуру снова. Так повторяется восемь раз. Таким образом, ни один блок не является графическим объектом, по сути это просто задний фон формы.
Возникает логичный вопрос: «Каким образом происходит взаимодействие графического объекта «шарик» с блоками?» Именно с этой целью и был создан двумерный массив восемнадцать на восемь, исходно заполненный одними единицами. Каждый раз когда объект шарика попадает в ту часть формы, в которой могут находиться блоки (расстояние равное восемь умноженное на число рядов блоков пикселей от верха формы) программа начинает определять, на месте какого элемента начальной матрицы сейчас находится шарик. Если на соответствующей позиции в матрице стоит единица, значит, в данный момент происходит процесс столкновения шарика с блоком.
Такое стечение обстоятельств «провоцирует» выполнение следующей части программы. Траектория шарика изменяется, соответствующий элемент матрицы заменяется нулевым значением. На место, где раньше был блок, помещается новое изображение блока соответствующего размера, одного цвета с цветом заднего фона формы. Также общее число оставшихся блоков, которое для удобства игрока всегда отображается на небольшой соседней форме, уменьшается на единицу. Игра заканчивается, когда это число достигнет нуля. Таким образом, существующий объект (шарик) взаимодействует не с подобными себе объектами, а с элементами двумерной матрицы, в прямом взаимодействии с которой находятся изображения на заднем фоне формы.
Приведем алгоритмическое решение описанных действий средствами объектно-ориентированной программной среды Lazarus (рис. 4).
Рис. 4. Часть кода процедуры столкновения шарика с блоком
Безусловно представленное решение рассматриваемой проблемы обладает, как и всякое другое решение, определенными достоинствами, так и недостатками. Главным достоинством программы можно считать упрощенную процедуру написания программного кода. Также к плюсам можно отнести сведение к минимуму количества графических элементов на форме.
К недостаткам, характерным для многих приложений подобного рода, прежде всего, относится некорректное взаимодействие шарика с блоками. Дело в том, что шарик «не видит», с какой частью блока он сталкивается. По законам логики и физики – в случае столкновения с верхней или нижней гранью шарик должен отскакивать в противоположную сторону по горизонтали. В случае же столкновения с одной из боковых сторон, он должен отскакивать в противоположную сторону по вертикали. В данной игре шарик «распознает» сам факт столкновения и всегда отскакивает по горизонтали.
Другой проблемой является процесс обновления блоков. Как уже было описано ранее – все блоки являются не более чем набором цветных пикселей на форме. Из-за этого, когда шарик «проходит» по картинке блока, но не разрушает его, он стирает часть этого блока (рис. 5).
Рис. 5. Пример частичного «стирания» блоков
Последнюю проблему частично удалось решить написанием процедуры, которая каждые несколько секунд перерисовывает не разрушенные блоки (рис. 6).
Рис. 6. Процедура перерисовки не разрушенных блоков
Все перечисленные недостатки могут быть математически, а, следовательно, и программно решены. Так, например, возможно применить в решении методы функционального анализа [3], инварианты теории графов [2] или методы теории экспертных систем [7]. Использование того или иного метода предопределяет общая цель разработки программного средства и требования, которые предъявляются к нему заказчиком. Они, определяют направления для дальнейшего совершенствования программы. Подчеркнем, что программное решение можно осуществить не только средствами объектно-ориентированных сред программирования, но в специализированных системах моделирования, например, UNITY3D [1] или Advanced Tester [5]. Также возможно использование средств сервис-ориентированных систем [6]. Решение, приведенное в данной статье, демонстрирует наличие различных способов взаимодействия с графическими элементами посредством программного кода в объектно-ориентированных средах программирования. В завершение заметим, что для анализа ситуации с графическими объектами на форме проекта можно применить и иные методологии математического моделирования и универсальных программных решений.