Оценка выстрела по мишени (Java, Android)

184
11 июля 2018, 17:10

Пытаюсь реализовать оценку выстрела по мишени. Мишень вот такого типа:

Она прописана в ImageView с прописанным свойством fitCenter в scaleType. Т.е. будет растягиваться под ширину экрана, находясь строго в центре, границами мишени буквально упираясь в границы экрана.

Пользователь касанием устанавливает и перемещает пробоину на мишени, после чего нажатием кнопки "Сохранить" вносит данные и оценку в что-то-типа-БД (SharedPreferences)

Сейчас у меня на оценке висит вот такой код:

public void getTheMarkForShot(float absoluteX, float absoluteY){
        ImageView aimTarget = findViewById(R.id.aimTarget);
        TextView textView = findViewById(R.id.textView2);
        ImageView red_dot = findViewById(R.id.red_dot);
        //Координаты центра - считаются правильно
        float centerX=aimTarget.getX() + aimTarget.getWidth()  / 2;
        float centerY=aimTarget.getY() + aimTarget.getHeight() / 2;
        //Определим расстояние от центра пробоины до центра мишени
        double absoluteDistance = Math.sqrt(Math.pow(absoluteX - centerX, 2) + Math.pow(absoluteY - centerY, 2));
        //Определяем координаты точки на пробоине, ближайшей к центру мишени
        double betterX = absoluteX * ((absoluteDistance - (red_dot.getWidth() / 2)) / absoluteDistance);
        double betterY = absoluteY * ((absoluteDistance - (red_dot.getHeight() / 2)) / absoluteDistance);
        //Определение оценки и вывод результата
        byte finalMark;
        //Если координаты ближайшей точки находятся вне круга (смотрим по его радиусу)
        if ((Math.pow(betterX - centerX, 2) + Math.pow(betterY - centerY, 2)) >
                Math.pow(aimTarget.getWidth()  / 2 , 2)){
            //Оценка равна 0. Выводим результаты на экран.
            finalMark = 0;
            String coordinatesMessage =
                    String.format("Координаты выстрела: (%.2f, %.2f). Оценка: %s",
                            absoluteX - centerX, centerY - absoluteY, finalMark);
            textView.setText(coordinatesMessage);
        }
        //Иначе - определяем в каком из сегментов круга находится пробоина
        else {
            //Разделим ширину круга на части
            for (int i = 10; i > -1; i--) {
                if ((Math.pow(betterX - centerX, 2) + Math.pow(betterY - centerY, 2)) <=
                        Math.pow(aimTarget.getWidth()  / 2 - (i * (aimTarget.getWidth()  / 2/10)), 2)){
                    finalMark = (byte)i;
                    String coordinatesMessage =
                           String.format("Координаты выстрела: (%.2f, %.2f). Оценка: %s",
                                    absoluteX - centerX, centerY - absoluteY, finalMark);
                    break;
                }
            }
        }
    }

На касание на данный момент прописано следующее:

@SuppressLint("ClickableViewAccessibility")
    public void getTouchCoordinates(){
        final ImageView aimTarget = findViewById(R.id.aimTarget);
        final ImageView red_dot = findViewById(R.id.red_dot);
        aimTarget.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                float x;
                float y;
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {
                        break;
                    }
                    case MotionEvent.ACTION_MOVE: {
                        x = event.getX();
                        y = event.getY();
                        red_dot(x, y);
                        getTheMarkForShot(x,y);
                        return true;
                    }
                    case MotionEvent.ACTION_UP: {
                        x = event.getX();
                        y = event.getY();
                        red_dot(x, y);
                        getTheMarkForShot(x,y);
                        return false;
                    }
                }
                return true;
            }
        });
    }

Результат вышеописанного - определяется только оценка 0. В остальных случаях определяются только координаты, без оценки (реализовал в функции red_dot).

Итак, сам вопрос: как в данном случае можно наиболее корректно определить оценку выстрела? Три страницы гугла трижды в день на протяжении трёх дней выдали единственное схожее задание: Задачка по C++ про мишени. Пытался реализовать, в итоге оценка 0 определяется вообще по всему экрану.

Очень прошу помочь, время не то что поджимает - его вообще нет =(

Answer 1

Ты все емного усложнил. Все чо тебе надо было, это найти центр круга, он у тебя есть, найти радиус круга, у тебя половина от ширины экрана, расстояние от центра до точки нажатия, тоже считаешь. И надо только проверить как близко точка находится от центра относительно радиуса. Если больше радиуса - 0, в остальном расстояние/радиус и будет от 0 до 1. Инвертироваь еще, отнять это число от 1, чтобы в центре было большее значени. Умнож на 10 и округли и будет число в которое попал

READ ALSO
Кoрректная работа z-index

Кoрректная работа z-index

Столкнулась с такой проблемой: не могу правильно задать элементам z-index, чтобы всё работало корректноВот тут код

227
JavaScript. Асинхронные функции. Что я делаю не так?

JavaScript. Асинхронные функции. Что я делаю не так?

Почему при сначала срабатывает функция UpdateValueMapBalances, а не ReadValueBalances?!

177
скриншот экрана с html2canvas

скриншот экрана с html2canvas

Проблема в том, что html2canvas делает скриншот всего селектора (в данном случа это body), который указанА как сделать так, чтобы был только скриншот...

197
Переменная имеет разные значения

Переменная имеет разные значения

Имеется код который с каким-то промежутком вызывается по CRON

179