Страницы

Поиск по вопросам

среда, 22 января 2020 г.

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

#java #android #coordinates


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

Она прописана в 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 определяется
вообще по всему экрану.

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


Ответы

Ответ 1



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

Комментариев нет:

Отправить комментарий