Анимация фигур Android

98
04 октября 2021, 09:50

Необходимо отобразить анимацию фигур, находящихся на View.

Фигуры - прямоугольник и круг.

Типы анимации:

  • перемещение к точки за time
  • вращение на angle за time
  • увеличение фигуры на destScale за time миллисекунд

Одновременно может быть несколько анимаций

Сейчас я написал метод move() для первой анимации для объекта figure, изменяя его координаты и добавил поток в список потоков.

А затем просто запускаю все потоки. Но думаю такой подход неправильный, думаю нужно как-то по-другому делать. Не подскажите как?

public class MainActivity extends AppCompatActivity {
    int canvasWidth, canvasHeight;
    int figuresCount;
    ArrayList<Figure> mFigures = new ArrayList<>();
    ArrayList<Thread> threads = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        loadFile();
        setContentView(new Panel(this, canvasWidth, canvasHeight, mFigures));
        for(Thread thread : threads){
            thread.start();
        }
    }
    private MyColor getColor(String text) {
        MyColor color = null;
        switch (text) {
            case "black":
                color = MyColor.BLACK;
                break;
            case "red":
                color =  MyColor.RED;
                break;
            case "white":
                color =  MyColor.WHITE;
                break;
            case "yellow":
                color = MyColor.YELLOW;
                break;
            default:
                break;
        }
        return color;
    }
    private void loadFile() {
        AssetManager am = getAssets();
        Scanner scanner = null;
        try {
            scanner = new Scanner(am.open("0.txt"));
            String[] firstLine = scanner.nextLine().split(" ");
            canvasWidth = Integer.parseInt(firstLine[0]);
            canvasHeight = Integer.parseInt(firstLine[1]);
            figuresCount = Integer.parseInt(scanner.nextLine());
            for (int i = 0; i < figuresCount; i++) {
                String[] line = scanner.nextLine().split(" ");
                Figure figure = null;
                if (line[0].equals("rectangle")) {
                    figure = new Rectangle(Float.parseFloat(line[1]), Float.parseFloat(line[2]), Float.parseFloat(line[3]), Float.parseFloat(line[4]), Float.parseFloat(line[5]), getColor(line[6]));
                } else if (line[0].equals("circle")) {
                    figure = new Circle(Float.parseFloat(line[1]), Float.parseFloat(line[2]), Float.parseFloat(line[3]), getColor(line[4]));
                }
                mFigures.add(figure);
                int countAnimation = Integer.parseInt(scanner.nextLine());
                for(int j = 0; j< countAnimation; j++){
                    String[] text = scanner.nextLine().split(" ");
                    if(text[0].equals("move")){
                        move(figure, Float.parseFloat(text[1]), Float.parseFloat(text[2]), Integer.parseInt(text[3]), true);
                    }
                }
            }
            Toast toast = Toast.makeText(this, String.valueOf(mFigures.size()), Toast.LENGTH_LONG);
            toast.show();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

public void move(final Figure figure, final float dectX, final float dectY, int time, final Boolean isCycle){
        final int seconds = 100;
        final int timeAnimation = time;
Thread thread = new Thread(new Runnable() {
            float firstDx = figure.centerX;
            float firstDy = figure.centerY;
            boolean cycle = isCycle;
            Figure currentFigure = figure;
            float dx = (figure.centerX - dectX) / (timeAnimation / seconds);
            float dy = (figure.centerY - dectY) / (timeAnimation / seconds);
            int currentTime = 0;
            @Override
            public void run() {
                while(true) {
                    while (currentTime < timeAnimation) {
                        firstDx = firstDx + dx;
                        currentFigure.centerX = firstDx;
                        firstDy = firstDy + dy;
                        currentFigure.centerY = firstDy;

                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        currentTime = currentTime + 100;
                    }
                    //в обратную сторону
                    if(cycle){
                        cycle = false;
                        currentTime = 0;
                        dx = dx * -1;
                        dy = dy * -1;
                    }
                    else{
                        break;
                    }
                }
            }
        });
        threads.add(thread);
    }
}
class Panel extends View {
    private Float canvasWidth, canvasHeight;
    private ArrayList<Figure> mFigures;
    public Panel(Context context, float canvasWidth, float canvasHeight, ArrayList<Figure> figures) {
        super(context);
        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;
        mFigures = figures;
    }
    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mFigures.size(); i++) {
            Figure figure = mFigures.get(i);
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            switch (figure.mColor) {
                case BLACK:
                    paint.setColor(android.graphics.Color.rgb(0, 0, 0));
                    break;
                case WHITE:
                    paint.setColor(android.graphics.Color.rgb(255, 255, 255));
                    break;
                case YELLOW:
                    paint.setColor(android.graphics.Color.rgb(255, 255, 0));
                    break;
                case RED:
                    paint.setColor(android.graphics.Color.rgb(255, 0, 0));
                    break;
            }
            if (figure instanceof Rectangle) {
                Rectangle rectangle = (Rectangle) figure;
                canvas.drawRect(rectangle.centerX - rectangle.width / 2,
                        rectangle.centerY - rectangle.height / 2,
                        rectangle.centerX + rectangle.width / 2,
                        rectangle.centerY + rectangle.width / 2,
                        paint);
            }
            else if(figure instanceof Circle){
                Circle circle = (Circle) figure;
                canvas.drawCircle(circle.centerX, circle.centerY, circle.radius, paint);
            }
        }
        invalidate(); // перерисовка объектов
    }
}


class Figure{
    float centerX;
    float centerY;
    MyColor mColor;
    public Figure(float centerX, float centerY, MyColor color) {
        this.centerX = centerX;
        this.centerY = centerY;
        this.mColor = color;
    }
}
class Rectangle extends Figure{
    float width;
    float height;
    float angle;
    public Rectangle(float centerX, float centerY, float width, float height, float angle, MyColor color) {
        super(centerX, centerY, color);
        this.width = width;
        this.height = height;
        this.angle = angle;
    }
}
class Circle extends Figure{
    float radius;
    public Circle(float centerX, float centerY, float radius, MyColor color) {
        super(centerX, centerY, color);
        this.radius = radius;
    }
}
enum MyColor{
    BLACK,
    RED,
    WHITE,
    YELLOW
}

Входные данные:

400 400
10
rectangle 69.000 280.000 24.000 24.000 0.000 black
1
move 251.000 72.000 10000 cycle
rectangle 256.000 188.000 24.000 48.000 0.000 black
0
rectangle 232.000 152.000 72.000 24.000 0.000 black
0
rectangle 35.000 400.000 24.000 24.000 0.000 black
1
move 285.000 -96.000 10000 cycle
rectangle 244.000 248.000 48.000 24.000 0.000 black
0
rectangle 300.000 117.000 24.000 48.000 0.000 black
1
move 112.000 164.000 5000
rectangle 136.000 200.000 72.000 24.000 0.000 black
0
rectangle 160.000 236.000 24.000 48.000 0.000 black
0
rectangle 208.000 224.000 24.000 72.000 44.797 black
1
rotate -44.797 5000
rectangle 232.000 200.000 24.000 24.000 0.000 black
0
READ ALSO
java.lang.StringIndexOutOfBoundsException: String index out of range: -4

java.lang.StringIndexOutOfBoundsException: String index out of range: -4

Всем привет сложилась ситуация что получил я следующий exception:

325
SearchView в Android

SearchView в Android

Есть проблема, связанная с элементом SearchViewКогда я нажимаю на иконку лупы, то SearchView не сразу переходит в режим ввода текста

75
Как передать переменную enum в тело запроса Post Spring

Как передать переменную enum в тело запроса Post Spring

Есть enam и контроллер как правильно передать enum через json?

190