Продолжаем написание нашего простенького игрового движка для Android. В первой части мы создали проект и написали код, для реализации примитивов — точек и линий. Но на точках и линиях далеко не уедешь. Поэтому продолжим писать наш небольшой графический движок для android. Итак, сегодня займемся ломаными линиями, прямоугольниками и кругами. Ломаная линия — это некоторое количество точек, соединенных отрезками в определенном порядке. И так для того чтобы ее описать нам понадобится массив точек и массив линий (благо такие классы у нас уже есть) . Ну что же, вроде бы все просто. Вот код класса, который мы по сложившейся привычке унаследовали от mBasic.
package ru.davidmd.myengine; import android.graphics.Canvas; import android.graphics.Paint; /** * @author davidmd * @version 0.1 Класс для работы с полилиниями унаследован от {@link mBasic} */ public class mPolyLine extends mBasic { private mPoint[] Points; private int size = 0; private mLine[] Lines; /** * Конструктор {@link mPolyLine} * * @param size * количество точек в полилинии * @param data * - массив типа {@link mPoint} содержащий информацию о точках */ public mPolyLine(int size, mPoint[] data) { Points = data; this.size = size; this.refreshLines(); this.type = mBasic.TYPE_POLYLINE; } /** * Конструктор {@link mPolyLine} * * @param data * - массив типа {@link mPoint} содержащий информацию о точках. * количество вершин полилинии определяется из длины массива * точек. */ public mPolyLine(mPoint[] data) { Points = data; this.size = data.length; this.refreshLines(); this.type = mBasic.TYPE_POLYLINE; } /** * Конструктор {@link mPolyLine} * * @param dataXY * - массив пар координат точек первая точка в паре координата по * x вторая по y */ public mPolyLine(int[] dataXY) { this.size = dataXY.length / 2; Points = new mPoint[this.size]; for (int i = 0; i < this.size; i++) { Points[i] = new mPoint(dataXY[i * 2], dataXY[i * 2 + 1]); } this.refreshLines(); this.type = mBasic.TYPE_POLYLINE; } /** * @return возвращает массив точек - вершин полилинии */ public mPoint[] getPoints() { return Points; } /** * @return возвращает количество вершин в полилинии */ public int getSize() { return size; } /** * Обновляет линии в полилинии если изменились точки */ public void refreshLines() { Lines = new mLine[this.size - 1]; for (int i = 0; i < this.size - 1; i++) { Lines[i] = new mLine(Points[i], Points[i + 1]); } } /** * @return Возвращает массив отрезков из которых состоит полилиния */ public mLine[] getLines() { return Lines; } @Override void update() { for (mPoint a : Points) { a.update(); } this.refreshLines(); } @Override boolean isSelected(float x, float y) { // TODO Auto-generated method stub return false; } @Override void draw(Canvas c, Paint p) { for (mLine l :Lines) { l.draw(c, p); } } }
Итак, что же мы здесь имеем? А ничего особо сложного! Points — это у нас и есть тот самый массив точек, в котором мы храним вершины нашей ломаной, Lines — соответственно массив линий. Различные конструкторы принимают различные параметры и приводят все это безобразие к одинаковому виду. Т. е. мы сможем создать ломаную задав массив объектов mPoint (как например в этом конструкторе public mPolyLine(mPoint[] data) ) или задав массив чисел, каждая пара которых есть координата одной из вершин нашей ломаной (как например здесь public mPolyLine(int[] dataXY)). Если мы передаем массив координат, то он преобразуется к массиву точек mPoint[]. Ах да, чуть не забыл, метод refreshLines() — пересоздает массив линий исходя из массива точек. Вот собственно и все. Отрисовку возлагаем на каждый отрезок полилинии. Код класса целиком можно взять вот тут mPolyLine.
Примерно так же работает и класс mRect. Только там все еще на много проще. Ну а про класс mCircle и говорить не стоит. Там и есть всего что радиус и точка. 🙂
На самом деле не знаю, понадобятся ли мне когданить эти классы, однако на всякий случай я их реализовал. Вдруг захочется чегонить такое отрисовать.
Ну, думаю хватит на сегодня. Если есть вопросы или комменты, пишите, постараюсь ответить.
Продолжение смотреть тут.
Уведомление: Пишем движок игры под Android – tutorial часть 3 (спрайты) | Программирование и разработка, android, java – с самых первых шагов
Автор молодец к успеху идешь :BRAVO:
Спасибо!
Я, честно говоря, в смятении…
У нас для точки есть скорость и ускорение. ОДНАКО, при создании линии -точки создаются стоячие. И нет методов для установки значений скорости и ускорения. И соответственно пока что функция апдейта ничего не делает, потому что координаты не меняются.
Про полилинию. Непонятно зачем хранить 2 дублируйщих массива — линий и точек. Мы же для линии храним только точки. Значит можно и для полилинии хранить только точки. Или только линии.
Подозреваю, что если заменить extends mBasic на extends mPoint, то это быстро решит проблему отсутствия методов, о которых я говорил. Они будут унаследованы от класса точки. Правильно?
Что означает комментарий?:
// TODO Auto-generated method stub
К прямоугольнику и кругу — те же претензии что и к линиям и полилиниям. Нет методов для движения. Более того, работа с прямоугольником, вычисление двух неосновных углов по двум основным — основана на предположении, что прямоугольник не поворачивается. А если каким-либо образом у точек окажутся разные скорости\ускорения — прямоуголник разъедется в бесформенный 4-угольный полигон.
Круг. Во-первых по сути это не круг, а дуга. И класс надо было бы называть иначально дугой. Или оставить кругом и убрать из класса начало и конец дуги. В комментариях к конструкторам путаница. В одном месте есть переменная arclen. Видимо хотелось создать конструктор, принимающий начальную точку и длину дуги в радианах. Но потом она используется как конец дуги. Вообще там порядка нету :(.
Конструкторов полной окружности — аж целых три. Для разных входных данных. Однако при этом конструктор для дуги — всего один. только для одного типа данных. Надо бы определиться. Либо мы делаем много-много конструкторов для любых входных данных, либо мы договариваемся о том, какие именно входные данные мы будем использовать сверху.
Если создается полная окружность — надо бы обнулять параметры начала и конца дуги. Вернее старт — в нуле, а конец в 2*PI. (Естественно я предполагаю. что мы используем радианы.)
Функция отрисовки рисует именно круг и ей пофиг на начало и конец дуги.
ПРЕДЛАГАЮ отказаться от дуги. А в случае необходимости — выродить ее из окружности.
Добрый день. Возникла проблема, как мне кажется, с передачей параметров paint методу draw. Я пишу
p7 = new mPoint (100, 300);
cr = new mCircle (p7, 40);
this.dp1 = new Paint();
this.dp1.setAntiAlias(true);
this.dp1.setColor(Color.RED);
cr.setPaint(this.dp1);
scene.addItem(cr);
p8 = new mPoint(25, 250);
p9 = new mPoint(200, 380);
re = new mRect(p8, p9);
this.dp2 = new Paint();
this.dp2.setAntiAlias(true);
this.dp1.setColor(Color.YELLOW);
pl.setPaint(this.dp2);
scene.addItem(re);
Cинтаксически вроде бы все верно. Фигуры отрисовываются, но напрочь не видят параметров paint, как будто я их вообще не задавал. С линиями и полилиниями проблем не было. Не подскажете в чем причина и как с этим бороться?