[19]: Обнаружение столкновений “Отрезок-Отрезок”

Приветствую вас, ребята и девчонки :) Сегодня продолжается серия уроков по обнаружению столкновений в action script 3.0. :) Расписывать подробно я  как обычно не буду, всё ооочень чётко изложено в видеоуроке. Здесь я распишу лишь алгоритм на основе которого всё работают.

При разработке игр очень важно знать о том, как обнаружить пересечение отрезков. Зачем? А затем что они будут применяться для расчетов полета объектов. Допустим 1 линия – это кривая стена, а 2 линия – траектория полета мяча в стену. Чтобы знать момент столкновения, нужно рассчитать точку пересечения этих линий с помощью action script 3.0. И проверить находиться ли эта точка в пределах отрезка представляющего стену. Только так можно независимо от кадров определить столкновение окружности с кривой стеной.

В этом уроке вы научитесь писать код обнаружения столкновений “отрезок-отрезок” с нарисованными физически линиями :) С программно нарисованными дело проще, просто сохраните координаты х2, у2. (урок 18 вам в помощь).

Все расчеты аналогичны предыдущему 18 уроку про пересечение линий. Вся разница лишь в том, что мы проверяем входит ли точка пересечения линий в пределы наших отрезков! 

Обо всём этом (и не только этом) смотрите в видеоуроке ниже:

Исходник: yadi.sk/d/TPB_ZA7DF48fA
Код ActionScript 3.0 из урока:

Всё подробно рассказано в видео :) Если будут какие-либо вопросы, пишите в комментариях к видео. Надеюсь, данный урок по реализации скорости в action script 3.0 в программе adobe flash, поможет вам в разработке игр. :)

Комментарии
  1. MrFOX

    Вообщем посмотрел это видео и решил сделать что-то подобное, только с нарисованными линиями…Но некоторые моменты, когда визуально точка пересечения есть, а код её не находит.
    Например при таком условии код не видит точку пересечения:
    Line1x1 = 150; //Начальная точка по оси Х для первого отрезка
    Line1y1 = 300; //Начальная точка по оси Y для первого отрезка
    Line1x2 = 150; //Конечная точка по оси Х для первого отрезка
    Line1y2 = 100; //Конечная точка по оси Y для первого отрезка

    Line2x1 = 195; //Начальная точка по оси Х для второго отрезка
    Line2y1 = 355; //Начальная точка по оси Y для второго отрезка
    Line2x2 = 100; //Конечная точка по оси Х для второго отрезка
    Line2y2 = 100; //Конечная точка по оси Y для второго отрезка

    Вообщем вот идеальный вариант:

    import flash.geom.Point;

    var Line1:Shape = new Shape ;
    addChild(Line1);
    var Line1x1 = 150;//Начальная точка по оси Х для первого отрезка
    var Line1y1 = 300;//Начальная точка по оси Y для первого отрезка
    var Line1x2 = 150;//Конечная точка по оси Х для первого отрезка
    var Line1y2 = 100;//Конечная точка по оси Y для первого отрезка
    Line1.graphics.clear();
    Line1.graphics.lineStyle(0, 0x00FF00, 1);
    Line1.graphics.moveTo(Line1x1, Line1y1);
    Line1.graphics.lineTo(Line1x2, Line1y2);

    var FF:Point = new Point ;
    //Создаем второй отрезок…
    var Line2:Shape = new Shape ;
    addChild(Line2);
    var Line2x1 = 195;//Начальная точка по оси Х для второго отрезка
    var Line2y1 = 355;//Начальная точка по оси Y для второго отрезка
    var Line2x2 = 100;//Конечная точка по оси Х для второго отрезка
    var Line2y2 = 100;//Конечная точка по оси Y для второго отрезка
    Line2.graphics.clear();
    Line2.graphics.lineStyle(0, 0x0000FF, 1);
    Line2.graphics.moveTo(Line2x1, Line2y1);
    Line2.graphics.lineTo(Line2x2, Line2y2);

    var a1:Point = new Point(Line1x1,Line1y1);
    var a2:Point = new Point(Line1x2,Line1y2);

    var b1:Point = new Point(Line2x1,Line2y1);
    var b2:Point = new Point(Line2x2,Line2y2);

    var shape:Shape = new Shape ;

    var de:Number = (b2.y – b1.y) * (a2.x – a1.x) – (b2.x – b1.x) * (a2.y – a1.y);
    var u0:Number = (b2.x – b1.x) * (a1.y – b1.y) – (b2.y – b1.y) * (a1.x – b1.x);
    var u1:Number = (b1.x – a1.x) * (a2.y – a1.y) – (b1.y – a1.y) * (a2.x – a1.x);
    var intersectPoint:Point = new Point ;

    if (de != 0.0)
    {
    u0 /= de;
    u1 /= de;
    if ((u0 >= 0.0) && (u0 = 0.0) && (u1 <= 1.0))
    {
    intersectPoint.x = a1.x + u0 * (a2.x – a1.x);
    intersectPoint.y = a1.y + u0 * (a2.y – a1.y);
    trace(intersectPoint);
    shape.graphics.beginFill(0xff0000,1);
    shape.graphics.drawCircle(intersectPoint.x,intersectPoint.y,5);
    shape.graphics.endFill();
    addChild(shape);
    }
    }

  2. Михаил

    Привет, Евгений!
    подскажи, пожалуйста, как можно программно узнать толщину обводки линии? просто дело в том, что ширина линии считается, как ширина + толщина обводки, а высота=высота+ширина обводки. и по этому, соответственно не правильно рассчитываются координаты X2 и Y2 и длина линии. и чем толще линия, тем не правильнее расчет(((

    • admin

      Привет, Майк. Есть такое дело с толщиной линии. Но! Эти линии делаются как каркас системы, изображение накладывается поверх отдельным слоем или скриптом. Поэтому всё строится тонкими линиями.

      На самом деле есть ещё одна проблема! Я когда то думал её исправить, но сейчас уже не помню как… В общем если развернуть линии наоборот, то пересечения не будет. Т.е. мы берем среднюю вертикальную и нижнюю горизонтальную линии и поворачиваем каждую на 180 градусов. И у нас не будет определяться пересечение в таком коде! А должно бы.. И это не проблема кода, а проблема кривизны флеша…
      Потому что, размещая на сцене тупо прямую линию имеем:
      начало линии с координатами 396.85 283.75 а конец 659.8000190150212 283.75
      поворачиваем её на 180 градусов и имеем:
      начало линии с координатами 659.65 283.75 а конец 396.6999809849788 283.75000000000006
      Из за вот этих 0.00000000000006 и выходит что перевернутые линии могут не определяться пересечением. Поэтому, с данным кодом приходится делать линии с маленьким заездом друг на друга, либо не переворачивать линии при сборке скелета игры.
      P.s. в данном примере кода используются не линии, а клипы, состоящие из линии внутри. :) Поэтому толщина влияет. Если использовать чисто линии, то это только программное рисование линий.

  3. Дмитрий

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

    • admin

      Здравствуй. Либо толстые линии, либо точка привязки не по левому краю.
      Ещё может быть вариант с перевёрнутыми линиями. Насколько я помню там нужно описывать уже по другому.

Добавить комментарий для admin Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">