Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

КРУГОВОЙ ФРАКТАЛ -ОШИБОЧНАЯ ПРОГРАММА! ПАПА ЗибЕрт
Можешь обяснить подробно что как работает, и почему массу не задаем
Здравствуйте, Ильгиз. Математика - царица наук (Карл Гаусс). Изучение математики начинается с детского сада, когда нас учат считать и выполнять простые арифметические операции. Любой, даже самый простейший алгоритм будет связан с арифметическими...
Я хотел узнать математика это обязательно в программирование. Пять лет назад просто из любопытства я увлекся HTML потом изучил CSS и JvaScript потом изучил PHP и Java. Как то не задумывался и начал смотреть форумы и узнал что без математики не...
Все верно, но так же необходимо зайти в: Компоновщик -> Ввод -> Дополнительные зависимости Здесь необходимо нажать изменить и в Дополнительные зависимости прописать это: SDL2.lib SDL2main.lib SDL2test.lib Без этого не заработает. (MVS 2015)

Счетчики и рейтинг

Яндекс.Метрика Рейтинг@Mail.ru
Среда программирования: 
Android Studio

Создадим полноэкранное приложение, как показано в уроке:
Создание полноэкранного приложения в Android Studio

Наше приложение будет работать по следующему принципу:
На каждом шаге прорисовки (onDraw(Canvas)) получаем переменную curTime, которая будет хранить текущее время. В зависимости от ее значения, объекты, которые мы рисуем, меняют свои положение и свойства. Под конец метода прорисовки вызываем invalidate(), который заставляет MyView вызвать функцию прорисовки заново.

MyView:

package me.graphica.canvasanimation;
 
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
 
public class MyView extends View {
 
    private final int   CIRCLE_COUNT     = 20; //количество окружностей
    private final float CIRCLE_ANIMATION = 0.5f; //величина поворота окружностей на каждый кадр
    private final long  RECT_ANIMATION   = 1_000; //длительность анимации прямоугольника = 1 секунда
    private final long  COLOR_ANIMATION  = 1_000; //длительность анимации смены цветов = 1 секунда
 
    private int mWidth; //ширина view
    private int mHeight; //высота view
 
    private Paint mCirclePaint;
    private Paint mRectPaint;
 
    private ArgbEvaluator mArgbEvaluator; //класс для анимации смены цветов
 
    private long  mStartTime; //время начала анимации
    private float mCircleDegree; //текущий угол поворота окружностей
 
    public MyView(Context context) {
        super(context);
        mCirclePaint = new Paint();
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setColor(Color.WHITE);
        mCirclePaint.setStyle(Paint.Style.FILL);
 
        mRectPaint = new Paint(mCirclePaint);
        mRectPaint.setColor(Color.RED);
 
        mArgbEvaluator = new ArgbEvaluator();
    }
 
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { //вызывается при изменении размера view
        mWidth = w; //запоминаем ширину view
        mHeight = h; //запоминаем высоту view
 
        mStartTime = getTime(); //начинаем отсчет времени
    }
 
    private long getTime() { //возвращает текущее время в миллисекундах
        return System.nanoTime() / 1_000_000;
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        colorAnimation(canvas); //демонстрация анимации цвета
        rotateAnimation(canvas); //демонстрация анимации поворота
        moveAnimation(canvas); //демонстрация анимации движения
        invalidate(); //заставляет перерисовывать view, пока view находится в поле зрения пользователя
    }
 
    private void rotateAnimation(Canvas canvas) {
        canvas.save(); //запоминаем текущее состояние canvas
 
        int centerX = mWidth / 2;
        int centerY = mHeight / 2;
 
        canvas.translate(centerX, centerY); //рисуем окружности вокруг центра view
        mCircleDegree += CIRCLE_ANIMATION; // += 0.5f
        canvas.rotate(mCircleDegree); //устанавливаем угол поворота
 
        int rad = Math.min(mWidth, mHeight) / 4; //расстояние между противоположными окружностями
        int cir_rad = rad / 12; //радиус самих окружностей
 
        for (int i = 0; i < CIRCLE_COUNT; i++) { //вычисляет положение и рисует 20 окружностей
            double t = (2 * Math.PI / CIRCLE_COUNT) * i;
            double x = rad * Math.cos(t);
            double y = rad * Math.sin(t);
 
            canvas.drawCircle((float) x, (float) y, cir_rad, mCirclePaint);
        }
 
        canvas.restore(); //восстанавливаем canvas
    }
 
    private void moveAnimation(Canvas canvas) {
        canvas.save();
 
        float rectWidth = mWidth / 10;
        float rectHeight = mHeight / 10;
 
        long curTime = getTime() - mStartTime; //время с момента начала анимации в мс
        float fraction = (float) (curTime % RECT_ANIMATION) / RECT_ANIMATION; //дробь от 0 до 1, где 0 - начало анимации, 1 - ее завершение
 
        if ((curTime / RECT_ANIMATION) % 2 == 1)
            fraction = 1 - fraction; //делает обратную анимацию, если она завершилась
 
        canvas.translate((mWidth - rectWidth) * fraction, mHeight - rectHeight);
        canvas.drawRect(0, 0, rectWidth, rectHeight, mRectPaint);
 
        canvas.restore();
    }
 
    private void colorAnimation(Canvas canvas) {
        long curTime = getTime() - mStartTime;
        float fraction = (float) (curTime % COLOR_ANIMATION) / COLOR_ANIMATION;
 
        if ((curTime / COLOR_ANIMATION) % 2 == 1)
            fraction = 1 - fraction;
 
        int color = (int) mArgbEvaluator.evaluate(fraction, Color.BLACK, Color.GREEN); //evaluate вычислаяет промежуточный цвет между двумя цветами
                                                                                       //в зависимоти от fraction = [0, 1]
        canvas.drawColor(color);
    }
 
}

Приложение выглядит следующим образом:

Обратите внимание, что размер и положение графических объектов зависят только от ширины (mWidth) и высоты (mHeight) экрана. Таким образом наше приложение будет корректно отображаться на всех Android устройствах.

Меняя следующие строки

    private final int   CIRCLE_COUNT     = 20; //количество окружностей
    private final float CIRCLE_ANIMATION = 0.5f; //величина поворота окружностей на каждый кадр
    private final long  RECT_ANIMATION   = 1_000; //длительность анимации прямоугольника = 1 секунда
    private final long  COLOR_ANIMATION  = 1_000; //длительность анимации смены цветов = 1 секунда

мы можем легко изменить поведение нашего приложения.

Например,

    private final int   CIRCLE_COUNT     = 10; //количество окружностей
    private final float CIRCLE_ANIMATION = 1f; //величина поворота окружностей на каждый кадр
    private final long  RECT_ANIMATION   = 1_000; //длительность анимации прямоугольника = 1 секунда
    private final long  COLOR_ANIMATION  = 500; //длительность анимации смены цветов = 0,5 секунды