Форум программистов, компьютерный форум CyberForum.ru

Как толкнуть одной фигурой другую в методе onDraw - Android

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
02.01.2014, 12:39     Как толкнуть одной фигурой другую в методе onDraw #1
Здравствуйте.Я на этом форуме новенький.Это мое первое сообщение,так что если формат формулировки не совсем правильный,попрошу меня извинить.Так вот суть проблемы: У меня есть два прямоугольника я хочу одним толкать другой,но проблема в следующем...толкать-то он толкает,только вот помимо толкания он также и тащит его за собой.
Алгоритм следующий:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public  boolean onTouchEvent(MotionEvent event){
        
        
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchX = event.getX();
            touchY = event.getY();          
        case MotionEvent.ACTION_UP:
            dx = touchX - event.getX();
            dy = touchY - event.getY();            
            if(Math.abs(dy) > Math.abs(dx)){ 
                
                if(dy > 0){   //Direction UP   
                    
                    
                    
                    manFirstY = manFirstY - 50;
                    manSecondY = manSecondY - 50;                    
                    if(manFirstY < targetSecondY && manFirstX == targetFirstX){                     
                        targetFirstY = targetFirstY - 50;
                        targetSecondY = targetSecondY - 50;
                        
                    }
                    
                }
 
                else if(dy < 0){    //Direction DOWN                                   
                    manFirstY = manFirstY + 50;
                    manSecondY = manSecondY + 50;                    
                    if(manSecondY > targetFirstY && manFirstX == targetFirstX){                 
                        targetFirstY = targetFirstY + 50;
                        targetSecondY = targetSecondY + 50;
                    }
   
                }
            }
            else{
                if(dx > 0){     //Direction LEFT                 
                    manFirstX = manFirstX - 50;
                    manSecondX = manSecondX - 50;                  
                    if(manFirstX < targetSecondX && manFirstY == targetFirstY){
                        targetFirstX = targetFirstX - 50;
                        targetSecondX = targetSecondX - 50;
                    }
            
                }
                else if(dx < 0){     //Direction RIGHT                    
                    manFirstX = manFirstX + 50;
                    manSecondX = manSecondX + 50;                 
                    if(manSecondX > targetFirstX && manFirstY == targetFirstY){
                        targetFirstX = targetFirstX +50;
                        targetSecondX = targetSecondX +50;
                    }   
                }
            }          
    }
        
    return true;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.01.2014, 12:39     Как толкнуть одной фигурой другую в методе onDraw
Посмотрите здесь:

Неуправляемый onDraw в отдельном View компоненте Android
Ошибка в методе onBackPressed Android
Android Как правильно присвоить переменным данные для использования с другом методе?
Android Перевод из одной системы счисления в другую
Android Передать параметр из одной активити в другую
Не получается вызвать метод onDraw(); Android
Android Доступ к элементам управления одной активности через другую
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
02.01.2014, 12:53     Как толкнуть одной фигурой другую в методе onDraw #2
Код читать немного не удобно... но мне кажется или Вы всю логику положили в ОТЖАТИЕ пальца, а не на СМЕЩЕНИЕ? Что такое 50? Привязка к некой сетке?
Возможно по бортику толкаемого стоит сделать зону "отторжения". Что-бы не было приклеивания через случайное наложение?
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
02.01.2014, 20:21  [ТС]     Как толкнуть одной фигурой другую в методе onDraw #3
Tester64Ну,то что логика в ACTION_UP вроде как мне не мешает(наверное) просто я новичок,с задачей справился,но я видел нормальные проекты состоят из нескольких java файлов,но у меня все в одном,я пытался создать нечто вроде java класса Move и потом в условиях использовать его методы но как-то не получилось может подскажете как создать этот файл,буду очень признателен,а с этой задачей я справился.Спасибо.И если можно еще скажите нужно ли здесь использовать case event.ACTION_MOVE?
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
02.01.2014, 21:22     Как толкнуть одной фигурой другую в методе onDraw #4
Цитата Сообщение от yuraavakyan Посмотреть сообщение
я пытался создать нечто вроде java класса Move
Почитайте про ООП в яве. Я его сам недавно понял, поэтому обьяснить еще могу с трудом... И тема тяжелая - в двух словах не обьяснить.

Если кратко, вариантов может быть несколько. Но это самый "частый".
Создается класс в котором хранится полная математика движения каждого обьекта (прямоугольника) И его отрисовка. Создаете несклько классов для Ваших прямоугольников. Каждый своего размера, цвета и со своей позицией. И обрабатывате в цикле воздействие на каждый прямоугольник движением захваченого. Там делается своя функция проверки на столкновение и обработка если это случилось.

Для двух прямоугольников это делать рано. Обычно это сильно упрощает жизнь на многих фигурах с сильно отличающимися характеристиками. Опять-же выносят функции обычно для 1) частого употребления в разных проектах или местах проекта. 2) упрощение понимания длинного проекта (здесь рисуем, а здесь двигаемся)

Правильнее сделать обработку в event.ACTION_MOVE. Тогда получите плавное движение, а не скачками на стадии отпускании пальца. Я не вижу Ваш проект, но если Вы начнете толкать внизу экрана, а отпустите только вверху, то позиции изменятся только в самом верху - "вдруг" Ваши "кирпичи" перепрыгнут массово с низу в верх...
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
02.01.2014, 22:50  [ТС]     Как толкнуть одной фигурой другую в методе onDraw #5
Tester64, Извините пожалуйста за дерзость,но я не очень понимаю что такое ООП и с чем его едят,если можно я вышлю вам код он небольшой,а когда у вас будет время разделите его на несколько java a? буду очень признателен в случае согласия;пойму - в случае отказа.

Добавлено через 9 минут
Tester64, Насчет скачков,нет я сделал так что при любом движении вверх фигура движется на 50 по Y или по X это тоже не годиться,я знаю что надо как то определить класс Cell или что-то в этом роде,но не могу,у меня в голове не укладывается как это надо сделать.

Добавлено через 3 минуты
Или давайте вот-так вот java файл в котором у меня написана вся логика.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
 package com.example.paint;
 
 
 
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
 
@SuppressLint("DrawAllocation")
public class Draw extends View{ 
    
    int manFirstX = 50;
    int manFirstY = 50;
    int manSecondX = 100;
    int manSecondY = 100;
    int targetFirstX = 200;
    int targetFirstY = 200;
    int targetSecondX = 250;
    int targetSecondY = 250;
    float dx = 0;
    float dy = 0;   
    float touchX = 0;
    float touchY = 0;
    
    
    public Draw(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
    public  boolean onTouchEvent(MotionEvent event){
        
        
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchX = event.getX();
            touchY = event.getY();          
        case MotionEvent.ACTION_UP:
            dx = touchX - event.getX();
            dy = touchY - event.getY();            
        case MotionEvent.ACTION_MOVE:
if(Math.abs(dy) > Math.abs(dx)){ 
                
                if(dy > 0){   //Direction UP   
                    
                    
                    
                    manFirstY = manFirstY - 50;
                    manSecondY = manSecondY - 50;                    
                    if(manFirstY < targetSecondY && manFirstX == targetFirstX){
                        if(manSecondY>=targetSecondY){
                        targetFirstY = targetFirstY - 50;
                        targetSecondY = targetSecondY - 50;
                        }
                        
                    }
                    
                }
 
                else if(dy < 0){    //Direction DOWN                                   
                    manFirstY = manFirstY + 50;
                    manSecondY = manSecondY + 50;                    
                    if(manSecondY > targetFirstY && manFirstX == targetFirstX){    
                        if(manSecondY<=targetSecondY){
                        targetFirstY = targetFirstY + 50;
                        targetSecondY = targetSecondY + 50;
                        }
                    }
   
                }
            }
            else{
                if(dx > 0){     //Direction LEFT                 
                    manFirstX = manFirstX - 50;
                    manSecondX = manSecondX - 50;                  
                    if(manFirstX < targetSecondX && manFirstY == targetFirstY){
                        if(manSecondX>=targetSecondX){
                        targetFirstX = targetFirstX - 50;
                        targetSecondX = targetSecondX - 50;
                        }
                    }
            
                }
                else if(dx < 0){     //Direction RIGHT                    
                    manFirstX = manFirstX + 50;
                    manSecondX = manSecondX + 50;                 
                    if(manSecondX > targetFirstX && manFirstY == targetFirstY){
                        if(manFirstX<=targetFirstX){
                        targetFirstX = targetFirstX +50;
                        targetSecondX = targetSecondX +50;
                        }
                    }   
                }
            }          
    }
        
    return true;
}
 
    @SuppressLint("DrawAllocation")
    public void onDraw(Canvas c){   
        
        Rect man = new Rect();
        
        
        
        
        Rect target = new Rect();
        Rect marginLeft = new Rect();
        Rect marginTop = new Rect();
        Rect marginRight = new Rect();
        Rect marginBottom = new Rect();
        
        marginBottom.set(0,getHeight()-50,getWidth(),getHeight());
        marginRight.set(getWidth()-50,0,getWidth(),getHeight());
        marginTop.set(0,0,getWidth(),50);
        marginLeft.set(0,0,50,getHeight());
        man.set(manFirstX,manFirstY,manSecondX,manSecondY);     
        target.set(targetFirstX,targetFirstY,targetSecondX,targetSecondY);
        Paint p = new Paint();
        p.setStyle(Paint.Style.FILL);
        p.setColor(Color.BLACK);
        c.drawPaint(p);     
        p.setColor(Color.WHITE);
        c.drawRect(man, p);
        p.setColor(Color.GREEN); 
        c.drawRect(target, p);
        c.drawRect(marginLeft,p);
        c.drawRect(marginTop,p);
        c.drawRect(marginRight,p);
        c.drawRect(marginBottom,p);
        
        
        
        invalidate();
        
    
    }
    
    
}
укажите пожалуста на недостатки или советы какие-нибудь.

Добавлено через 11 минут
Блин забыл вставить коментарии
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
02.01.2014, 23:09     Как толкнуть одной фигурой другую в методе onDraw #6
Вычитывать чужой код - неблагодарное занятие... Скучное... У меня своего кода хватает - сюда заглядываю чтоб отвлечься или получить ответы на теоретические вопросы...

1) Никаких дополнительных класов определять не надо. И избавьтесь от 50! Вы еще не доросли до работы с "сеткой" и автоматического "приклеивания"/"выравнивания" координат кирпичей/прямоугольников по сетке. Пока просто запоминаете координаты пальца и ведущего/нажатого пямоугольника при нажатии и вычисляете смещение в ACTION_MOVE при каждом движении. Разницу используете для изменения координаты Вашего ведущего прямоугольника. А от координат ведущего получаете координаты ведомого.

2) ООП - это огромный кусок программирования. Причем 99% андроида его использует. Если хотите кодить под андроид это надо выучить ОБЯЗАТЕЛЬНО! Например здесь http://developer.alexanderklimov.ru/.../java/java.php и здесь http://developer.alexanderklimov.ru/...java/class.php
Я когда вступил в яву уже знал основы ООП и статья помогла. Возможно поможет и Вам...
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
02.01.2014, 23:28  [ТС]     Как толкнуть одной фигурой другую в методе onDraw #7
Tester64, Спасибо огромное за советы,но мне все-таки нужно фиксировать шаг фигуры,а не перемещать ее настолько насколько преместил курсор.Я собственно для этого и использовал эти 50,я в принципе доволен результатом шага,все ок,но нужно бы определить этот шаг где-нибудь как Cell,Или разбить экран на сколько то Cell - ов,и шагать по ним.
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
03.01.2014, 09:52     Как толкнуть одной фигурой другую в методе onDraw #8
Понятно... Ну если надо... Я бы на Вашем месте переделал логику движений!
1) научитесь ПЛАВНО двигать кирпичи через начальную позицию кирпича и пальца
2) округляйте позицию кирпича до нужного что-бы попась в линию/ячейку сетки
Тогда размеры сетки можно вынести в глобальную переменную и по желанию ее менять одной цифрой. А сетку можно сделать даже с разными ячейками и вычислять принадлежность ячейке и позицию в ней по формулам.

Мне показалось по Вашему коду (не особо вчитывался, но...), что прыжки получатся не всегда правильными... Скачками что-ли... По направлению пальца, но не всегда под ним...

Добавлено через 9 минут
...Похоже что возможна ситуация когда палец над одной ячейкой, а кирпич на несколько ячеек в сторону...
А почему Вы не вывели 50 в переменну наверх кода? Тогда одним махом меняя на 10 или 100 можно было заметить ошибки...

Добавлено через 2 минуты
Задайте нечто вроде int step= 50; и переберите код! Не правильно каждый раз записывать шаг числом. Если какие изменения или надо перенести логику в другой проект, прийдется массово перебирать а не изменить число (возможно даже программно в зависимости от разрешения монитора).
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
03.01.2014, 13:40  [ТС]     Как толкнуть одной фигурой другую в методе onDraw #9
Да вы правы ,уже изменил эти 50 на переменную,но как мне разбить сетку на ячейки,чтобы еще прорисовать бортики экрану,и чтобы ящики не уходили за них?

Я перенес логику в класс Move но не могу использовать его методы.

Может надо его от кого либо наследовать...или на знаю короче,если не трудно помогите:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.example.paint;
 
import android.content.Context;
 
 
 
 
public class Move extends MainActivity{
    public Move(Context context) {
        super();
        
        // TODO Auto-generated constructor stub
    }
    int manFirstX = 50;
    int manFirstY = 50;
    int manSecondX = 100;
    int manSecondY = 100;
    int targetFirstX = 150;
    int targetFirstY = 50;
    int targetSecondX = 200;
    int targetSecondY = 100;
    
 
    
    final public boolean moveDown(){
        
         manFirstY = manFirstY + 50;
         manSecondY = manSecondY + 50;                    
         if(manSecondY > targetFirstY && manFirstX == targetFirstX){                 
            targetFirstY = targetFirstY + 50;
            targetSecondY = targetSecondY + 50;
            
        
         }
        return true;
    }
    public boolean moveUp(){
 
        manFirstY = manFirstY - 50;
        manSecondY = manSecondY - 50;                    
        if(manFirstY < targetSecondY && manFirstX == targetFirstX){                     
            targetFirstY = targetFirstY - 50;
            targetSecondY = targetSecondY - 50;
            
        }
        return true;
    }
    public boolean moveLeft(){
         manFirstX = manFirstX - 50;
         manSecondX = manSecondX - 50;                  
         if(manFirstX < targetSecondX && manFirstY == targetFirstY){
            targetFirstX = targetFirstX - 50;
            targetSecondX = targetSecondX - 50;
         }
        return true;
    }
    public boolean moveRight(){
        manFirstX = manFirstX + 50;
        manSecondX = manSecondX + 50;                 
        if(manSecondX > targetFirstX && manFirstY == targetFirstY){
            targetFirstX = targetFirstX +50;
            targetSecondX = targetSecondX +50;
        }
        return true;   
    }
 
    
}
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
03.01.2014, 17:51     Как толкнуть одной фигурой другую в методе onDraw #10
1) возможно Вы не определили свой класс мув. Делается это примерно так Move mymove=new Move(); а потом пользуетесь mymove.moveLeft()
2) процедуры и переменные можно сделать static. тогда не надо создавать каждый раз, но и один класс с одними значениями на все формы, а не в каждой форме свой класс.

Сетку нарисовать не тяжело. Пока ячеек не очень много. Делите длину/ширину на кво ячеек и округляеете результат к меньшему. Следите что бы за пределы не лезло. Прийдется слегка менять размеры кирпичей в крайней ячейке. Например с 50 на 49 или 51.
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
04.01.2014, 20:02  [ТС]     Как толкнуть одной фигурой другую в методе onDraw #11
Насчет ООП разобрался,теперь я сделал так что первый класс использует методы класса Move,только вот одна проблема,когда я задаю размер шага step = getWidth()/9, a потом к координатам прибавляю step прямоугольник не рисуется вообще когда я задаю начальные координаты прямоугольнику он не рисуется но как только я меняю переменную на числа все рисуется...не знаю что делать...

Добавлено через 1 минуту
А в самом классе Move не разрешается использовать getWidth.подчеркивается красным и предлагает создать этот метод.Ну как я понял,что этот метод можно использовать только если класс наследовался от View но как получить число в классе из View и передать его в Move?

Добавлено через 2 часа 10 минут
вроде все ок,только вот одна проблема: onDraw не рисует ничего если я меняю цифры 50 на переменную в которой храниться значение getWidth/8.Поменя на константу рисует,и рисует вроде точно нигде ничего не вылезает все по размеру но все-таки лучше былои бы если точно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2014, 20:17     Как толкнуть одной фигурой другую в методе onDraw
Еще ссылки по теме:

Портирование с одной версии на другую Android
Android Как вызвать другой результат try-catch в методе?
Android Передать параметр из одной в другую
Данные не передаются из одной активности в другую Android
Android Ошибка в методе именования файлов

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,488
04.01.2014, 20:17     Как толкнуть одной фигурой другую в методе onDraw #12
Следующий этап Вашего развития - LogCat
Это специальная утилита встроенная в среду и показывающая сообщения выданные Вашей программой
Перед отрисовкой программа должна отправить Вам значение getWidth. Сильно подозреваю что оно получено не корректно и =0.
Делается это примерно так: Log.d("Kirpich", "getWidth="+getWidth);
Для удобства просмотра логов, советую в просмотщике (встроенном в ЛЮБОЙ редактор андроид-кода) поставить фильтр на "Kirpich" (название можно менять)

Добавлено через 7 минут
Попробуйте забить в переменную getWidth/8 значение 50. Возможно она не правильно обрабатыватеся.
Цитата Сообщение от yuraavakyan Посмотреть сообщение
А в самом классе Move не разрешается использовать getWidth.подчеркивается красным и предлагает создать этот метод
Сильно подозреваю что getWidth выдает не правильное значение. Это ширина обьекта в котором Вы работает. но... Можно создавать ГЛОБАЛЬНЫЕ переменные!!! Пример: public static int width = 500; Они принадлежат классов в котором созданы (например mainactivity), но могут быть использованы из других классов mainactivity.width = 40;
Yandex
Объявления
04.01.2014, 20:17     Как толкнуть одной фигурой другую в методе onDraw
Ответ Создать тему
Опции темы

Текущее время: 20:12. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru