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

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
#1

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

02.01.2014, 12:39. Просмотров 1126. Ответов 11
Метки нет (Все метки)

Здравствуйте.Я на этом форуме новенький.Это мое первое сообщение,так что если формат формулировки не совсем правильный,попрошу меня извинить.Так вот суть проблемы: У меня есть два прямоугольника я хочу одним толкать другой,но проблема в следующем...толкать-то он толкает,только вот помимо толкания он также и тащит его за собой.
Алгоритм следующий:

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 (Программирование Android):

Не получается вызвать метод onDraw(); - Программирование Android
Здравствуйте! Я новичок в разработке приложений под android и сегодня безрезультатно провел день, т.к. не знаю решения моей проблемы....

Портирование с одной версии на другую - Программирование Android
Добрый вечер, хотелось бы узнать как портировать приложения с версии 4.3 или 4.1 или 4.4 на 5.1.1 андроид. А то у Sony есть хороший плеер...

Передать параметр из одной в другую - Программирование Android
Добрый вечер. Тут небольшая проблема. Как передать (ID) - С одной AppCompatActivity в Fragment. Ну принцип такой же как на...

Неуправляемый onDraw в отдельном View компоненте - Программирование Android
Здравствуйте, у меня такая проблема -&gt; не контролируемый onDraw (я убрал invalidate со всех функций), везде читал об этом, уже потерял все...

Перевод из одной системы счисления в другую - Программирование Android
Есть скрипт на javascript &lt;script language=&quot;JavaScript&quot;&gt; b= eval(prompt(&quot;число&quot;)); d=eval(prompt(&quot;из какой сс&quot;)); s=eval(prompt(&quot;в...

Передать параметр из одной активити в другую - Программирование Android
Всем привет, дорогие форумчане! Прошлый раз мне любезно помогли здесь, мне понравилось. Так что снова обращаюсь за помощью.:D Есть...

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

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

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

Правильнее сделать обработку в event.ACTION_MOVE. Тогда получите плавное движение, а не скачками на стадии отпускании пальца. Я не вижу Ваш проект, но если Вы начнете толкать внизу экрана, а отпустите только вверху, то позиции изменятся только в самом верху - "вдруг" Ваши "кирпичи" перепрыгнут массово с низу в верх...
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
02.01.2014, 22:50  [ТС] #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
396 / 357 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
02.01.2014, 23:09 #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  [ТС] #7
Tester64, Спасибо огромное за советы,но мне все-таки нужно фиксировать шаг фигуры,а не перемещать ее настолько насколько преместил курсор.Я собственно для этого и использовал эти 50,я в принципе доволен результатом шага,все ок,но нужно бы определить этот шаг где-нибудь как Cell,Или разбить экран на сколько то Cell - ов,и шагать по ним.
Tester64
396 / 357 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
03.01.2014, 09:52 #8
Понятно... Ну если надо... Я бы на Вашем месте переделал логику движений!
1) научитесь ПЛАВНО двигать кирпичи через начальную позицию кирпича и пальца
2) округляйте позицию кирпича до нужного что-бы попась в линию/ячейку сетки
Тогда размеры сетки можно вынести в глобальную переменную и по желанию ее менять одной цифрой. А сетку можно сделать даже с разными ячейками и вычислять принадлежность ячейке и позицию в ней по формулам.

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

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

Добавлено через 2 минуты
Задайте нечто вроде int step= 50; и переберите код! Не правильно каждый раз записывать шаг числом. Если какие изменения или надо перенести логику в другой проект, прийдется массово перебирать а не изменить число (возможно даже программно в зависимости от разрешения монитора).
yuraavakyan
0 / 0 / 0
Регистрация: 02.01.2014
Сообщений: 7
03.01.2014, 13:40  [ТС] #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
396 / 357 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
03.01.2014, 17:51 #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  [ТС] #11
Насчет ООП разобрался,теперь я сделал так что первый класс использует методы класса Move,только вот одна проблема,когда я задаю размер шага step = getWidth()/9, a потом к координатам прибавляю step прямоугольник не рисуется вообще когда я задаю начальные координаты прямоугольнику он не рисуется но как только я меняю переменную на числа все рисуется...не знаю что делать...

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

Добавлено через 2 часа 10 минут
вроде все ок,только вот одна проблема: onDraw не рисует ничего если я меняю цифры 50 на переменную в которой храниться значение getWidth/8.Поменя на константу рисует,и рисует вроде точно нигде ничего не вылезает все по размеру но все-таки лучше былои бы если точно.
Tester64
396 / 357 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
04.01.2014, 20:17 #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;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2014, 20:17
Привет! Вот еще темы с ответами:

Данные не передаются из одной активности в другую - Программирование Android
Данные не передаются в другую активность... Вот код: Из: Intent inttt = new Intent(hhhhh.this, list.class); inttt.putExtra(&quot;vgh&quot;,...

Доступ к элементам управления одной активности через другую - Программирование Android
Имеется две активности. Когда запускаю вторую активность, первую не выгружаю (не удаляю). Можно ли сделать так, чтобы вторая активность...

можно ли в с++ вызвать переменную из одной функции в другую т.е. мы переменну задали в одной функции а использовали в другой... и как это реализовать? - C++
можно ли в с++ вызвать переменную из одной функции в другую т.е. мы переменну задали в одной функции а использовали в другой... и как это...

Нужно чтобы введённый студент в методе in вывелся на экран как в методе out - C++
#include&lt;conio.h&gt; #include&lt;stdio.h&gt; #include&lt;iostream.h&gt; #include&lt;windows.h&gt; #include&lt;cstring.h&gt; // это просто для русских...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
04.01.2014, 20:17
Ответ Создать тему
Опции темы

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