Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
#1

Организация структуры объектов - Программирование Android

17.12.2013, 15:53. Просмотров 771. Ответов 15
Метки нет (Все метки)

Всем привет!
Хочу задать вопрос по поводу организации структуры объектов в игре для дальнейшей обработки коллизий:
например есть у меня класс World - уровень
На уровне есть кирпич, игроки и монстры (используются разные классы без унаследований)

Игроки и монстры должны сталкиваться с кирпичом
где необходимо определять коллизию? если я правильно понимаю - то в классе World.
Дальше например один из монстров пересек кирпич, значит нужно определить коллизию для этого объекта.
Каким образом из цикла выделить этот объект и где организовать последующее действие после определения коллизии?

Я так понимаю что в классе каждого объекта нужно создать переменную isCollision и присваивать в эту переменную true.
А дальше у объектов, в которые переменная isCollision = true производить действие.

Но как мне менять значение переменной, если используются разные класс? Писать отдельные методы для каждого класса?
Разъясните этот момент, уже 2й день голову ломаю из-за этих классов...
Пока у меня был только игрок с кирпичами, все было хорошо...был один метод, куда я передавал игрока и там проверял наличие пересечения с кирпичом....а теперь мне нужно написать точно такой же метод, только вместо игрока указывать монстров....но так будет как то не эстетично и больше похоже на быдло-код... надеюсь я правильно передал свою мысль
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2013, 15:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Организация структуры объектов (Программирование Android):

Управление проектами, организация структуры - Программирование Android
Принцип построения проектов взят из c#. На C#: Есть один solution. В нем один главный проект (main_project) и две библиотеки класов...

Организация структуры игровых объектов - DirectX
Первый опыт создания внутриигровой структуры объектов немного провалился :) Решив подчерпнуть информации из сети, наткнулся на данную...

Организация движение объектов по выбору - PascalABC.NET
Не получается организовать движение объектов по выбору , всё время мерещиться readkey но он здесь не работает: При запуске программы...

Динамические структуры данных. Организация данных в списковые структуры - Pascal
Написать программу вставки нового элемента в список за некоторым заданным по- рядковым номером элементом (вставка осуществляется не в...

Динамические структуры данных. Организация данных в списковые структуры - Delphi
Написать программу, формирующую два списка, заполняя их числами из файлов. Объединить оба списка в один, вставляя элементы поочередно то из...

Организация коллекции объектов пользовательского класса - VBA
Есть некий пользовательский класс Mob. И есть класс MobAssistant, существующий для управления коллекцией объектов класса Mob. ...

15
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
17.12.2013, 16:24 #2
Ну, я когда делал игры, обычно в классе родительском описывал метод, который возвращал прямоугольник объекта.

А также были методы движения, стрельбы и т.п.

Все объекты находились в одном массиве, но у каждого класса была своя пометка.

В общем цикле игры я пробегался по своему массиву так:

Java
1
2
3
4
5
6
7
8
for(Class s : listClass) {
      for(Class s2 : listClass) {
              if(s != s2 && s.getRect().intersect(s2.getRect())) {
                     // здесь уже производил действия, например отталкивание или нанесение урона
                     s.lifeDamage(10);
              }
      }
}
0
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
17.12.2013, 16:37  [ТС] #3
GukZiLLA, спасибо за пример...теперь например действие будет - присвоение переменной о наличие коллизии...а сравниваться будут не два класса, а три:
Class s - будет статический объект, т.е. кирпич

Java
1
2
3
4
5
6
7
8
9
10
11
12
for(Class s : listClass) {
      for(Class s2 : listClass) {
              if(s != s2 && s.getRect().intersect(s2.getRect())) {
                     void setreflect(s2);
              }
      }
      for(Class s3 : listClass) {
              if(s != s3 && s.getRect().intersect(s3.getRect())) {
                    void setreflect(s3);
              }
      }
}
это то, чего я хочу добиться....т.е. void setreflect(); - это метод с объемными вычислениями, куда передается класс s2 или s3 для вытягивания оттуда переменных, например координат x и y, сравнение с координатами класса S а далее записи в эти классы(s2 или s3) переменной Reflect = 1.

Два раза один и тот же код писать вроде как не стоит, а по-другому получить значение одноименной переменной от разных классов не получается. Как быть?
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
17.12.2013, 16:42 #4
Не надо два цикла делать, добавляйте только проверку if(...)

Цитата Сообщение от m210 Посмотреть сообщение
это то, чего я хочу добиться....т.е. void setreflect(); - это метод с объемными вычислениями, куда передается класс s2 или s3 для вытягивания оттуда переменных, например координат x и y, сравнение с координатами класса S а далее записи в эти классы(s2 или s3) переменной Reflect = 1.
Два раза один и тот же код писать вроде как не стоит, а по-другому получить значение одноименной переменной от разных классов не получается. Как быть?
Вот здесь я ничего не понял, зачем вытягивать переменные?
Создайте массив классов
0
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
17.12.2013, 16:46  [ТС] #5
Цитата Сообщение от GukZiLLA Посмотреть сообщение
Создайте массив классов
А пример реализации можете показать? Я пока не представляю как потом работать с таким массивом
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
17.12.2013, 16:58 #6
Юзайте наследование, иначе циклов будет куча.
0
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
18.12.2013, 16:57  [ТС] #7
Ладно, спасибо хоть на этом)

Добавлено через 18 часов 44 минуты
GukZiLLA, каким образом вы формируете список объектов?
Допустим у меня есть список кирпичей, который я хочу добавить в общий массив классов (если я правильно понял, то массив классов включает в себя все объекты одного класса?)

Класс кирпичей у меня наследуется от общего класса Block
В конструкторе мира приходится писать вот так:
Java
1
2
3
Block br = new Brick(this, x, y, 700, level.Level[i][1]); //создание кирпича
bricks.add((Brick) br);  //список кирпичей для прорисовки
blockList.add(br); //общий список объектов для коллизии
Как то неудобно...удалять объекты из списков тоже приходится двумя строками...

Ну и все было хорошо, пока мне не потребовался доступ к отдельным дочерним классам.

Под общим классом Block у меня пока два дочерних класса - Player и Brick
В Brick у меня есть метод, который проигрывает анимацию при попадания в него шарика...этот метод есть только в Brick, и он не нужен Playerу.

Java
1
2
3
4
5
public void isCollision(Objects obj) { 
            for(int i = 0; i < blockList.size(); i++) {            
                Block br = blockList.get(i);
((Brick br).setGloss(); //в этом случае происходит вылет программы
}
Что я делаю не так?
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
18.12.2013, 20:14 #8
Ну, массив классов - это массив родительских объектов.
Все остальные объекты мира наследуются всегда от родительского.
В родительском классе описаны самые основные методы и переменные.

Объявите в родительском классе переменную type и у вас будут разные типы объектов по их именам.
У кирпича String type = "brick", у монстра, например, "monster" и т.п.

Если грамотно делать, то расчеты и отрисовка должны происходить в одном цикле.
А чтобы при тормозах отрисовки не возникало замедления - юзайте deltaTime (разница по времени между двумя ближайшими кадрами) - она должна быть равна единице, и все рассчеты умножайте на deltaTime.

Создайте в каком-нибудь из базовых классов метод draw и отрисовывайте персонажей в потомках.
Также у каждого персонажа живого свои методы переопределяются.

Не нужно создавать отдельные массивы для отрисовки. просто в цикле прогона по всем объектам детектите их по типу(type), о котором говорил выше.

Если type == brick, то его можно привести под (Brick) и вытянуть все методы и переменные.


Например вот так:
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
List<Obj> listObj = new ArrayList<Obj>();
    
    class Obj {
        String type;
        
    }
    
    class Brick extends Obj {
 
        int x;
        int y;
        int width;
        int height;
        
        Brick(String name, int x, int y, int width, int height) {
            this.type = name; // parent type
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        
        public void draw(Canvas c) {
            // .........
            Log.i("brick", "draw");
        }
        
        
        
    }
    
    
    class Monster extends Obj {
 
        int x;
        int y;
        int width;
        int height;
        float speed;
        int damage;
        
        Monster(String name, int x, int y, int width, int height, float speed, int damage) {
            this.type = name; // parent type
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.speed = speed;
            this.damage = damage;
        }
        
        public void move(float deltaTime) {
            // .......
            Log.i("monster", "move");
        }
        
        public void draw(Canvas c) {
            // .........
            Log.i("monster", "draw");
        }
        
    }
Проверим, сработает ли))

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// for example
        for(int i = 0; i <= 10; i++) {
            listObj.add(new Brick("brick", i*10, i*10, 100, 100));
            listObj.add(new Monster("monster", i*10, i*10, 20, 40, 5, 10));
        }
        
        // main loop
        for(Obj o : listObj) {
            if(o.type.hashCode() == "brick".hashCode()) {
                Brick b = (Brick) o;
                b.draw(null);
            }
            if(o.type.hashCode() == "monster".hashCode()) {
                Monster m = (Monster) o;
                m.draw(null);
                m.move(1);
            }
        }
На выходе видим:

brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
brick: draw
monster: draw
monster: move
Как-то так. Везде есть нюансы и лучше делать конечно все через движок, например LibGDX.

Добавлено через 12 минут
Вообще для динамического удаления монстров надо будет юзать Iterator

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    Iterator<Obj> iter = listObj.iterator();
        while(iter.hasNext()) {
            Obj o = iter.next();
            if(o.type.hashCode() == "brick".hashCode()) {
                Brick b = (Brick) o;
                b.draw(null);
            }
            if(o.type.hashCode() == "monster".hashCode()) {
                Monster m = (Monster) o;
                m.draw(null);
                m.move(1);
                
                // удаляем монстра
                if(m.life <= 0) {
                    iter.remove();
                }
            }
        }
1
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
18.12.2013, 21:02  [ТС] #9
Вроде пока все понятно, спасибо ) завтра буду пробовать. Кстати а в чем разница итератора от обычного цикла по листу?

Добавлено через 2 минуты
На счет использования движков уже думал...но надо сначало самому все изучить и понять...движки можно будет использовать позже....да и как то свой код роднее и понятнее))))
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
18.12.2013, 21:37 #10
Цитата Сообщение от m210 Посмотреть сообщение
Кстати а в чем разница итератора от обычного цикла по листу?
http://dev64.wordpress.com/2013/03/1...ion-exception/
1
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
19.12.2013, 14:11  [ТС] #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
private void drawWorld(World world) {
 
        g.drawPixmap(world.Background, 0, 0); //Прорисовка фона
        for(int j = 0; j < world.objList.size(); j++) {   
            Obj obj = world.objList.get(j);
            if(obj.type.hashCode() == "brick".hashCode()) {
                Brick br = (Brick) obj;
                br.onDraw(g);
            } else
            if(obj.type.hashCode() == "player".hashCode()) {
                pl = (Player) obj;
                pl.onDraw(g); 
                    
                if(input.isTouched()) {
                    pl.movePlayerTo(input.getTouchX());
                    
                    if(!Shoot && input.getTouchX() > 300 && input.getTouchY() < 20)
                            pl.newBall();
                            Shoot = true; 
                } else Shoot = false;
            } else
            if(obj.type.hashCode() == "ball".hashCode()) {
                Ball bl = (Ball) obj;
                bl.onDraw(g);
                bl.update();
            }
        }

А вот код определения коллизий в public void update(float deltaTime)

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
               for(Obj s : objList) {
            for(Obj s2 : objList) {
                if(s != s2) {
                    if(s.type == "ball") {
                        Ball ball = (Ball) s;
                        //if(s2.type == "brick") {
                            for(int k = 0; k < 4; k++) { 
                                if(FrameMath.CircleIntersect(s.x + 4, s.y + 4, 4, s2.Vortex[k].x,s2.Vortex[k].y, s2.Vortex[k + 1].x, s2.Vortex[k + 1].y)) {
                                    crossx = FrameMath.CircleIntersectX(s.x + 4, s.y + 4, 4, s2.Vortex[k].x,s2.Vortex[k].y, s2.Vortex[k + 1].x, s2.Vortex[k + 1].y);
                                    crossy = FrameMath.CircleIntersectY(s.x + 4, s.y + 4, 4, s2.Vortex[k].x,s2.Vortex[k].y, s2.Vortex[k + 1].x, s2.Vortex[k + 1].y);
 
                                    int N = 0;
                                    double ang = ball.getAngle();
                                    if(k == 2) { N = 270; ball.setPosY((float) (crossy + ball.getSpeed())); }
                                    if(k == 0) { N = 90;  ball.setPosY((float) (crossy - ball.getSpeed() - 8)); }
                                    if(k == 3) { N = 180; ball.setPosX((float) (crossx - ball.getSpeed() - 8)); }
                                    if(k == 1) { N = 0; ball.setPosX((float) (crossx + ball.getSpeed())); }
                                    ball.setAngle(2*N - 180 - ang);
                                    
                                    //if(s2.getExtra() > 0) s2.setExtra(s2.getExtra() - 1);
                                }
                            }
                        //}
                    }       
                }
            }
        }
Столновение с первым созданным шаром вообще не происходит...второй шар вроде просчитывается...хотя в посл время прога просто вылетает при создании второго...но когда все работало (уже не помню, что менял) заметил, что если шар рисуется поверх кирпичей, происходит коллизия, если рисуется под кирпичами (как в случае с первым шаром) - коллизии нет.

P.S. Как же блин сложно угодить этой Яве...куда не влезешь - ошибки или вылеты))) Прям руки опускаются
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
19.12.2013, 14:47 #12
Объекты надо сравнивать так - s.equals(s2) - return true/false
Строки надо сравнивать также через equals, либо для производительности юзать hashCode

Цитата Сообщение от m210 Посмотреть сообщение
По таком алгоритму стало как то хуже только)))
А должно быть лучше
0
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
19.12.2013, 15:06  [ТС] #13
Ну в целом удобнее работать с таким алгоритмом, но во время работы цикла в него хрен влезешь, возникают исключения, с которыми я не умею работать а объекты я и через хэшкод пробовал, разницы никакой...проблема где то в другом...но где я определить не смогу о чем там эта ява думает
0
GukZiLLA
35 / 35 / 2
Регистрация: 30.11.2013
Сообщений: 102
19.12.2013, 15:09 #14
Цитата Сообщение от m210 Посмотреть сообщение
но во время работы цикла в него хрен влезешь, возникают исключения, с которыми я не умею работать
Например?
0
m210
0 / 0 / 0
Регистрация: 17.12.2013
Сообщений: 10
19.12.2013, 23:27  [ТС] #15
Например добавить новый шар (чтобы было одновременно два) не получается...программа вываливается с исключением при попытке добавить шар в лист. Видимо с добавлением объекта изменяется общий список в момент, когда цикл уже производит обработку. Кстати да...вроде бы прога вылетает при попытке добавить объект внутри цикла

Добавлено через 7 часов 40 минут
Причину вылетов я нашел...это условие

Java
1
if(FrameMath.CircleIntersect(s.x + 4, s.y + 4, 4, s2.Vortex[k].x,s2.Vortex[k].y, s2.Vortex[k + 1].x, s2.Vortex[k + 1].y))
А точнее доступ к Vortex[]
Это массив точек кирпича, который создается в конструкторе для прохождения по всем граням кирпича... массив класса Obj, который у меня задается так
Java
1
2
3
4
5
6
7
void setVortex(float x, float y, int width, int height) {
        this.Vortex[0] = new PointF(x,y);
        this.Vortex[1] = new PointF(x + width,y);
        this.Vortex[2] = new PointF(x + width,y + height);
        this.Vortex[3] = new PointF(x,y + height);
        this.Vortex[4] = new PointF(x,y);
    }
Может идея не самая лучшая?)
Добавил эти точки шарам и вылеты пропали, хотя самый первый шар по прежнему пролетает сквозь кирпичи, последующие выполняют условия циклов. Как-нить можно отловить первый шар и понять, почему он не сравнивается с кирпичами?
Он кстати может пролететь мимо нескольких кирпичей, а потом вдруг начать от них отлетать))) в общем, живет своей жизнью
0
19.12.2013, 23:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2013, 23:27
Привет! Вот еще темы с ответами:

Структуры и организация данных - Turbo Pascal
Здравствуйте, помогите пожалуйста! нужно сделать через функции 2 мерный массив через одномерный массив отобразить надо как матрицу. Вот...

Структуры и организация данных - Turbo Pascal
Помогите написать программу с комментариями! :scratch: Все нулевые элементы расположены в шахматном порядке, начиная со 2-го элемента...

Оптимальная организация структуры БД - Ruby on Rails
Добрый день! Разрабатываю тестовую торговую площадку, и у меня возник вопрос по организации таблиц в БД, а именно: есть три типа...

Организация структуры плейлиста - C++
Здравствуйте, необходимо организовать архитектуру для организации плейлиста(в котором хранится некоторое количество аудиозаписей), сам...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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