Пример или справка по предотвращению столкновений - PullRequest
3 голосов
/ 28 ноября 2010

Я пытался найти пример предотвращения столкновений, который я могу адаптировать и использовать для игры, над которой я работаю.Он будет использоваться для моделирования движения лыжника, чтобы избежать деревьев на холме.Я основываю движение на Поведение рулевого управления для автономных персонажей , и есть много хороших примеров для следования по пути и флокирования, но я не могу найти хороших примеров для предотвращения столкновений. На сайте Code of Nature были отличные учебные пособия по рулевому управлению, но, казалось, они охватывали все, кроме предотвращения препятствий.

Я преобразовал код из здесь , но он не работает каккак и должно быть, поскольку столкновения обнаруживаются путем проецирования центра препятствий на вектор скорости без учета того, что центр препятствий может находиться за пределами столкновения, но круг все еще сталкивается.Вот код, который я адаптировал (написанный на языке «Обработка (на основе Java))».

// Method to update location
void update() {
  // Update velocity
  vel.add(acc);
  // Limit speed
  vel.limit(maxspeed);
  loc.add(vel);
  // Reset accelertion to 0 each cycle
  acc.mult(0);
}

void obstacleAvoid() {
  float checkLength = 30*vel.mag();
  PVector forward,diff,ray,projection,force;
  float dotProd,dis;
  forward = vel.get();
  forward.normalize();
  ray = forward.get();
  ray.mult(checkLength);
  for ( int i = 0; i < obs.size(); i++ ) {
    Obstacle ob = (Obstacle)obs.get(i);
    diff = ob.pos.get();
    diff.sub(loc);
    PVector temp2 = forward.get();
    temp2.mult(ob.r);
    diff.sub(temp2);
    dotProd = diff.dot(forward);
    if ( dotProd > 0 ) {
      projection = forward.get();
      projection.mult(dotProd);
      dis = PVector.dist(projection,diff);
      if ( (dis < (ob.r + r)) && (projection.mag() < ray.mag()) ) {
        ob.hit = true;
        force = forward.get();
        force.mult(maxforce);
        if ( sign(diff,vel) == -1 ) { //CCW
          force.set(force.y,-force.x,0);
        }
        else { //CW
          force.set(-force.y,force.x,0);
        }
        force.mult(1-(projection.mag())/ray.mag());
        force.limit(maxforce);
        acc.add(force);
      }
    }
  }  
}

Поэтому, чтобы помочь мне, мне было интересно, если бы кто-нибудь знал о каких-либо полных примерах предотвращения столкновений, которые следуют за Поведение рулядля автономных персонажей способ сделать вещи лучше. Этот сайт является примером приложения для газеты и является точным примером, для которого я хотел бы увидеть код.К сожалению, нет никакого кода, чтобы пойти с ним, и я попытался декомпилировать его, но он просто показал основной класс, так что это было не очень полезно.Если у кого-то есть код для этого примера или что-то в этом роде, или учебник, я был бы очень признателен.

Ответы [ 2 ]

1 голос
/ 14 декабря 2010

Крейг Рейнольдс не может выпустить исходный код для интересующих вас апплетов. Аналогичный исходный код доступен на c ++ по адресу OpenSteer , который поддерживается Reynolds.Кристиан Шнеллхаммер и Томас Фейлкас работали над расширением оригинальной статьи Рейнольдса.Их статья переведена на английский и содержит раздел об избежании препятствий.Исходный код их работы доступен на Java .Тем не менее, Я думаю, что код Шиффмана - отличная отправная точка , и похоже, что вы уже достаточно близки к тому, что вы хотите

Одна из моих первых программ обработки изменила пример Boids для имитациизомби-апокалипсис.Треугольники преследовали круги, которые избегали их.Каждый выживший проверяет других зомби в своем видении и усредняет векторы угроз в функции, PVector panic(ArrayList infected).После этого нужно было взвешивать новый вектор отрицательно и добавлять его к текущему вектору выжившего, как и любую другую силу.Что-то вроде:

void flock(ArrayList uninfected, ArrayList infected) {
  PVector sep = separate(uninfected);   // Separation
  PVector ali = align(uninfected);      // Alignment
  PVector coh = cohesion(uninfected);   // Cohesion
  PVector pan = panic(infected);        // Panic
  // Arbitrarily weight these forces
  sep.mult(4.0);
  ali.mult(1.0);
  coh.mult(2.0);
  pan.mult(-3.0);
  // Add the force vectors to acceleration
  acc.add(sep);
  acc.add(ali);
  acc.add(coh);
  acc.add(pan);
}

Если ваш лыжник успешно обнаруживает препятствия, тогда уклонение является проблемой.Добавление более сильного веса к вектору уклонения, увеличение радиуса, который лыжник может «видеть» для взаимодействия с объектами, или даже добавление к объекту метода, который возвращает местоположение ближайшей точки к лыжнику, может решить вашу проблему.Вы также можете добавить замедление в зависимости от расстояния от лыжника до ближайшего препятствия перед ним.

Помните, что даже интересующий вас апплет не может полностью избежать препятствий.Мое решение, возможно, не совсем то, что происходит в апплете, но, играя с силами, определяющими направление вашего лыжника, вы можете добиться очень похожего (и, возможно, лучшего) эффекта.

0 голосов
/ 29 ноября 2010

Воспользуйтесь этой ссылкой на сайте разработки игр NEHE:

В этом руководстве вы познакомитесь с основами обнаружения столкновений, реагирования на столкновения и физических эффектов моделирования.В этом руководстве больше внимания уделяется тому, как работает обнаружение коллизий, чем фактическому коду, хотя объяснен весь важный код.,Хотя вы найдете ссылку для Java Port с использованием JOGL.

Также Исходный код для http://www.red3d.com/cwr/steer/ доступен здесь http://opensteer.sourceforge.net/, хотя и на c ++.Вы проверяли это?

...