Суть такова.

Имеется игровое поле подобное шахматной доске, однако без деления клеток на черные и белые. Размер поля может быть произвольным, однако играть на поле меньше, чем 2х3 не имеет особого смысла. Мне нравится играть на поле 10х10.

Количество игроков может произвольным, однако на мой взгляд интереснее играть вдвоем или вчетвером. Если играть втроем на прямоугольном поле, то возникает дисбаланс, поскольку один из игроков будет отдален от «пустого» угла. Если играть компанией больше, чем 4 человека, то сложно воплощать свою стратегию.

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

Пара картинок для пояснения сути.

Пустое поле 4х4 с указанием критической массы для каждой ячейки.

Игровая ситуация после третьего хода.

Игровая ситуация после четвертого хода (первыми ходят синие). Видно, что в верхнем левом углу скопилось критическое количество атомов.

Бах! Они разлетелись, захватив 2 синих атома в ячейке [0][1]. И в этой ячейке [0][1] теперь тоже критическое количество. Цепная реакция!

Ситуация после разлета. Конец четвертого хода. Синие сейчас совершат пятый ход.

Реализация. Графическая часть.

Приступим к реализации. Создадим производный от View класс.

Здесь я допустил немного говнокода кода плохого качества, а именно захардкордил в коде цвет линий, разделяющих ячейки игрового поля и размер вьюхи считается равным 300 dp. Этот размер можно получить из объекта attrs класса AttributeSet, однако не будем загромождать код.

Также сразу набросаем Activity, дабы убедиться, что все рисуется красиво.

И разметка main.xml

Теперь добавим возможность изменять масштаб игрового поля, поскольку возможны промахи мимо нужной ячейки по причине их малого размера. Для этого переопределяем нужные нам методы реализации ScaleGestureDetector.SimpleOnScaleGestureListener интерфейса OnScaleGestureListener в нашем классе GameView.

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

этого берем ближайшее значение из промежутка [0, canvasSize -viewSize] для предотвращения скролла за пределы игрового поля.

Теперь напишем обработку скролла, одиночного тапа и двойного тапа (двойной тап будет возвращать к исходному масштабу игрового поля).

При одиночном тапе мы рассчитываем координаты ячейки, по которой тапнули, например верхняя левая ячейка будет иметь координаты 0,0.

Напишем метод рисования атомов drawAtoms. параметры метода — координаты ячейки, в которой рисуем атомы, цвет и количество атомов.

На данный момент метод имеет недоработку в виде абсолютных значений размеров атомов и расстояний между ними. К чему это может привести? При размере поля меньше, чем 10х10 атомы будут смотреться мелкими, а при большем размере поля могут не влезть в ячейку.

Осталось добавить скроллбары. Этот процесс хорошо описан здесь habrahabr.ru/post/120931/.

Прежде чем приступить к описанию игровой логики добавим глобальную переменную типа GameLogic (наш класс, описывающий логику) с именем logic и добавим в метод обработки одиночного тапа onSingleTapConfirmed

вызов будущего метода логической обработки добавления нового атома.

logic.addAtom(cellX, cellY);

Также необходим сеттер для этой переменной.

Реализация. Игровая логика.

Создадим класс GameLogic, описывающий логику игры. Также нам понадобится внутренний класс Cell, хранящий параметры ячейки игрового поля.

Сам класс GameLogic

Здесь мы видим конструктор, который создает двумерный массив объектов Cell и метод addAtom, вызываемый из вьюхи по одиночному тапу и из себя при условии что ячейка наполнена атомами под завязку.

Теперь можно добавлять атомы в ячейки, а при накоплении в ячейке критического количества атомов они разлетятся в стороны через секунду. Однако сейчас во время этой секунды можно добавлять атомы. Избавимся от этого, добавив переменную-флаг isLock и методы isLock(), lock() и unlock() в класс GameView.

Также необходимо добавить смену игрока после хода, подсчет очков и обработку конца игры (когда все атомы принадлежат одному игроку и каждый игрок совершил как минимум 1 ход).

Добавим в конец метода addAtom() следующий код

Осталось написать реализацию методов

Это будет домашним заданием. Тут все тривиально.

После сборки обработать напильником

Далее требуется небольшое допиливание получившегося приложения в виде создания Activity для настройки игры (размер игрового поля, количество игроков, цвет атомов и имена игроков, однако это не тема данной статьи. Итоговый код можно посмотреть на гитхабе. получившуюся игру попробовать на Google Play

Прошу большими камнями не кидаться. Осознаю низкое качество кода и обещаю стремиться избегать говнокода. Спасибо за внимание.

P.S. Это моя первая статья на хабре.

Источник: habrahabr.ru

Категория: Выбор и покупка

Похожие статьи: