Статьи

Лазерный генератор, препятствия и точное обнаружение попадания

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


Давайте посмотрим на конечный результат, к которому мы будем стремиться:


Откройте Flash и создайте новый документ Flash (ActionScript 3.0).

Установите размер сцены на любое стандартное разрешение. Мой 500 х 350 пикселей.

Установите частоту кадров 24 кадра в секунду.

Сохраните файл в папке по вашему выбору.


Давайте теперь создадим лазерный генератор.

Нарисуйте круг радиуса 20, то есть 40 х 40. Кроме того, залейте его красивым цветом радиального градиента.

LaserGenerator_Circle

Теперь нам нужно преобразовать этот круг в символ Flash, чтобы мы могли управлять им с помощью ActionScript.

Выберите круг и нажмите F8 или перейдите в « Модификация»> «Преобразовать в символ» . Выберите муви клип для типа символа. Также установите точку регистрации в центр, чтобы лазерный генератор вращался из своего центра. Введите laserGenerator_MC в поле имени экземпляра, а затем в laserGenerator_MC но не в последнюю очередь, отметьте «Экспорт для ActionScript» в группе «Расширенные», чтобы мы могли получить доступ к лазерному генератору из нашего класса документов, с которым мы скоро встретимся.

ConvertToSymbol_Settings

После настройки всех вышеперечисленных параметров нажмите ОК. Нажмите OK еще раз для появления диалогового окна с предупреждением об определении класса. Это создаст определение класса для лазерного генератора во время выполнения.

Теперь нам не нужен символ laserGenerator_MC на сцене, поскольку он доступен на панели «Библиотека» с идентификатором laserGenerator_MC . Поэтому удалите этот символ со сцены. Ваша сцена должна быть пустой сейчас.

Library_Panel

Теперь, когда мы добавим рот к этому генератору, чтобы создать ощущение устройства. На панели библиотеки дважды щелкните laserGenerator_MC символа laserGenerator_MC (слева от имени символа), чтобы перейти в режим редактирования. Добавьте рот к нему, как показано ниже.

Не стесняйтесь добавлять свой собственный дизайн.

Примечание: не меняйте положение круга, так как нам нужно повернуть его вокруг его центра.

LaserGenerator_With_Mouth

После добавления рта к генератору выйдите из режима редактирования символа и вернитесь к основной временной шкале.

Ваша ракета покинула землю. Устройство лазерного генератора готово и ждет выполнения.


Чтобы добавить драму к нашей сцене, нам нужен ActionScript. Чтобы действовать умно, нам нужен класс документов.

На этом шаге мы создадим базовую структуру нашего класса документов.

Для подробного объяснения класса документов ознакомьтесь с этим кратким советом .

Итак, создайте новый файл ActionScript 3.0. Введите следующий код:

1
2
3
4
5
6
7
package {
    public class Laser_HitDetection{
        public function Laser_HitDetection () {
            // constructor code
        }
    }
}

Сохраните этот класс документа как Laser_HitDetection.as в той же папке, где вы сохранили свой FLA для этого урока. Хороший взлет. Ваш базовый класс документов готов.


В вашем FLA-файле откройте панель «Свойства» для документа и введите имя класса в поле «Класс документа», доступное в группе «Публикация».

ClassName_Field

Теперь мы готовы общаться с FLA через этот класс документов Laser_HitDetection.as .


Мы создадим экземпляр лазерного генератора из библиотеки и поместим его в центр сцены.

Измените класс документа Laser_HitDetection.as, как показано ниже (выделенные строки):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package
{
    import flash.display.Sprite;
     
    public class Laser_HitDetection extends Sprite
    {
        var laserGun:Sprite;
 
        //Constructor
        public function Laser_HitDetection()
        {
            CreateLaserGun();
                     
        }
 
        //Get and place laser generator from library
        public function CreateLaserGun():void
        {
            laserGun = new laserGenerator_MC();
            addChild(laserGun);
 
            //Place laser generator at the centre of the stage
            laserGun.x = stage.stageWidth / 2;
            laserGun.y = stage.stageHeight / 2;
        }
    }
}

Если вы сейчас протестируете фильм, вы увидите, что наша лазерная пушка прекрасно расположена в центре сцены.


В приведенном выше коде мы использовали класс Sprite для создания экземпляра объекта Sprite, который будет содержать лазер. Для этого мы объявляем переменную как:

1
var laserGun:Sprite;

Затем мы добавили новый метод « CreateLaserGun () », в котором мы присвоили экземпляр laserGenerator_MC из библиотеки вышеупомянутой laserGun как:

1
laserGun = new laserGenerator_MC();

После добавления его на сцену мы поместили его в центр сцены как:

1
2
laserGun.x = stage.stageWidth / 2;
laserGun.y = stage.stageHeight / 2;

Наконец, мы вызвали этот метод из метода конструктора класса документа как:

1
2
3
4
5
//Constructor
public function Laser_HitDetection()
{
    CreateLaserGun();
}

Ракета разгоняется с полной тягой. Очень скоро мы активируем эту лазерную пушку, которая будет проектировать лазер. Перед этим добавим несколько препятствий. Пошли.


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

Препятствия

Теперь мы поместим все эти фигуры в один символ. Выделите все фигуры одновременно и нажмите F8 или перейдите в « Модификация»> «Преобразовать в символ» . Выберите Movie Clip в качестве типа символа. Назовите этот символ obstacles_MC в текстовом поле имени. Установите точку регистрации в центре. Также отметьте «Экспорт для ActionScript», чтобы мы могли получить к нему доступ из нашего класса документов.

После конвертации в MovieClip у нас в библиотеке выявляется файл fractles_MC с тем же именем идентификатора. Одновременно с laserGenerator_MC нам не нужен этот символ на сцене, поэтому удалите его со сцены. Теперь ваша сцена пуста.

Obstacles_MovieClip

То, как мы поместили нашу laserGenerator_MC на сцену, в центре, аналогично, мы будем размещать на сцене символ obstacles_MC . Измените класс документа, как показано ниже:

01
02
03
04
05
06
07
08
09
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
package
{
    import flash.display.Sprite;
     
    public class Laser_HitDetection extends Sprite
    {
        var laserGun:Sprite;
        var obstacles:Sprite;
         
        //Constructor
        public function Laser_HitDetection()
        {
            CreateLaserGun();
            CreateObstacles();
        }
 
        //Get and place laser generator from library
        public function CreateLaserGun():void
        {
            laserGun = new laserGenerator_MC();
            addChild(laserGun);
 
            //Place laser generator at the centre of the stage
            laserGun.x = stage.stageWidth / 2;
            laserGun.y = stage.stageHeight / 2;
        }
         
        //Get and place obstacles from library
        public function CreateObstacles():void
        {
            obstacles = new obstacles_MC();
            addChild(obstacles);
             
            //Place obstacles at the centre of the stage
            obstacles.x = stage.stageWidth / 2;
            obstacles.y = stage.stageHeight / 2;
        }
    }
}

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

LaserGun_Obstacles

Ваша ракета достигает предельной скорости. Теперь пришло время активировать лазерную пушку. Он должен генерировать лазер из него. Давайте сделаем это сейчас.


Как мы будем имитировать лазер? Есть предположения? …………… Как насчет использования некоторых членов класса Graphics, таких как lineStyle() , moveTo() , lineTo() . Если вы знакомы с этими методами, то ваша работа проста. Для тех, кто не знает этих методов, мы всегда с вами. Давайте посмотрим на них подробно.

Мы добавим новый метод ProjectLaser() . Давайте Laser_HitDetection наш Laser_HitDetection документа Laser_HitDetection как показано ниже:

01
02
03
04
05
06
07
08
09
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
//Constructor
package
{
    import flash.display.Sprite;
     
    public class Laser_HitDetection extends Sprite
    {
        var laserGun:Sprite;
        var obstacles:Sprite;
         
        var laser:Sprite;
 
        var startX:Number;
        var startY:Number;
        var endX:Number;
        var endY:Number;
         
        //Constructor
        public function Laser_HitDetection()
        {
            CreateLaserGun();
            CreateObstacles();
            ProjectLaser();
        }
 
        //Get and place laser generator from library
        public function CreateLaserGun():void
        {
            laserGun = new laserGenerator_MC();
            addChild(laserGun);
 
            //Place laser generator at the centre of the stage
            laserGun.x = stage.stageWidth / 2;
            laserGun.y = stage.stageHeight / 2;
        }
         
        //Get and place obstacles from library
        public function CreateObstacles():void
        {
            obstacles = new obstacles_MC();
            addChild(obstacles);
             
            //Place obstacles at the centre of the stage
            obstacles.x = stage.stageWidth / 2;
            obstacles.y = stage.stageHeight / 2;
        }
 
        //Project a laser from laser generator device
        public function ProjectLaser():void
        {
            laser = new Sprite();
            addChild(laser);
             
            //Set origin of the laser as the centre of the laser gun
            startX = laserGun.x;
            startY = laserGun.y;
             
            //Set end point of the laser
            endX = startX + 230;
            endY = startY;
             
            //Draw laser
            laser.graphics.lineStyle(1, 0xFF0000);
            laser.graphics.moveTo(startX, startY);
            laser.graphics.lineTo ( endX, endY );
        }
    }
}

Проверьте фильм.

LaserGun_Projecting_Laser

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


На этом этапе мы успешно спроектировали лазер. Для этого мы выполнили следующие задачи:

Сначала мы объявили пять новых переменных:

1
2
3
4
5
6
var laser:Sprite;
 
var startX:Number;
var startY:Number;
var endX:Number;
var endY:Number;

Во-вторых, мы добавили новый метод ProjectLaser() :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public function ProjectLaser():void
{
    laser = new Sprite();
    addChild( laser );
     
    //Set origin of the laser as the centre of the laser gun
    startX = laserGun.x;
    startY = laserGun.y;
     
    //Set end point of the laser
    endX = startX + 230;
    endY = startY;
 
    //Draw laser
    laser.graphics.lineStyle ( 1, 0xFF0000 );
    laser.graphics.moveTo ( startX, startY );
    laser.graphics.lineTo ( endX, endY );
}

В приведенном выше методе сначала мы создали пустой объект Sprite для удержания лазера, а также добавили его на сцену, как показано ниже:

1
2
laser = new Sprite();
addChild( laser );

Поскольку мы хотели, чтобы лазер начинал проецироваться из лазерной пушки, мы назначаем значение X лазерной пушки для startX и значение Y для startY как показано ниже:

1
2
startX = laserGun.x;
startY = laserGun.y;

(Позже мы предоставили эти значения moveTo(startX, startY) которым мы скоро встретимся.)

Затем мы определили endX и endY :

1
2
endX = startX + 230;
endY = startY;

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

А теперь важная часть этого метода. Рисование прямой линии внутри объекта лазерного спрайта для имитации проецируемого лазера.

Сначала мы обработали стиль нарисованной линии, как показано ниже:

1
laser.graphics.lineStyle ( 1, 0xFF0000 );

Этот метод lineStyle () используется для управления стилем обводки рисованного объекта, такого как линия, прямоугольник, овал и т. Д. Для этого метода можно указать максимум восемь аргументов. Если не указано, вместо них назначаются значения по умолчанию. Для нашего примера нам понадобятся только два аргумента. Первый аргумент — это толщина линии (т. Е. 1), а второй аргумент — это цвет линии (т. 0xFF0000 , то есть красный).

Для подробного объяснения этого метода обратитесь к справочному документу Adobe по методу «lineStyle (args ..)» .

Затем мы поместили начальную точку линии, как показано ниже:

1
laser.graphics.moveTo ( startX, startY );

startX и startY гарантируют, что начальная точка должна быть центром лазерной пушки.

После этого мы завершили линию:

1
laser.graphics.lineTo ( endX, endY );

Помните, что эти endX и endY являются временными значениями, просто чтобы показать проекцию. Нам нужно, чтобы они были настроены, если на пути лазера возникнет какое-либо препятствие. Мы сделаем это в следующих шагах.

Итак, мы нарисовали линию от ( startX , startY ) до ( endX , endY ).

Ракета уходит и уходит. Смотрите эти пейзажи, водные пейзажи ..

Теперь пришло время для реальных действий. Обнаружение попадания с препятствиями.


Теперь мы оснащены лазерной пушкой. У нас также есть несколько препятствий. Мы находимся на уровне, на котором мы можем добавить обнаружение попадания, что, безусловно, добавит смысл сцене.

Вы можете подумать, что это очень точное обнаружение попадания потребует сложной математики. Если так, то вы не правы. Он просто использует hitTestPoint (), встроенный в метод ActionScript вместе с циклом for . Сложная математика, лежащая в основе идеального обнаружения попаданий, обрабатывается этим методом. Вам нужно только разумно использовать этот метод и цикл for .

Мы собираемся внести некоторые важные изменения в наш класс документов, главным образом, в метод ProjectLaser() и некоторые новые переменные, поэтому соблюдайте и применяйте его внимательно. Давайте изменим это, как показано:

Сначала добавьте эти новые переменные:

1
2
3
var rad:Number = Math.PI/180;
var maxDist:Number = 250;
var adjustedDist:Number;

Затем измените метод ProjectLaser() , добавив цикл for как показано ниже (также обратите внимание, что теперь endX и endY находятся внутри цикла):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//Project a laser from laser generator device
public function ProjectLaser():void
{
    laser = new Sprite();
    addChild(laser);
             
    //Set origin of the laser as the centre of the laser gun
    startX = laserGun.x;
    startY = laserGun.y;
 
    for (adjustedDist = 0; adjustedDist < maxDist; adjustedDist ++)
    {
        //Trigonometry to aim the laser wrt laser gun’s rotation
        endX = laserGun.x + Math.cos ( laserGun.rotation * rad ) * adjustedDist;
        endY = laserGun.y + Math.sin ( laserGun.rotation * rad ) * adjustedDist;
 
        //calculate hit test
        if ( obstacles.hitTestPoint ( endX, endY, true ) )
        {
            break;
        }
    }
 
    //Draw laser
    laser.graphics.lineStyle( 1, 0 x FF0000 );
    laser.graphics.moveTo( startX, startY );
    laser.graphics.lineTo ( endX, endY );
}

Проверьте фильм.

Laser_HitDetection

Бум …. я уверен. Глядя на этот эффект, вы вдохновляетесь на создание Flash-игры, обладающей интеллектом безопасности. Идеальный ИИ, для разработки интересной игры во Flash.


Прежде всего, мы добавили новые переменные в наш класс документов, как показано ниже:

Изначально угол в радианах

1
var rad:Number = Math.PI/180;

Вышеуказанная переменная используется в формуле для расчета угла в радианах.

Формула, radians = degrees * Math.PI/180 . Больше информации здесь. Мы использовали эту формулу в нашем коде в следующих строках:

1
2
endX = laserGun.x + Math.cos ( laserGun.rotation * rad ) * adjustedDist;
endY = laserGun.y + Math.sin ( laserGun.rotation * rad ) * adjustedDist;

В laserGun.rotation * rad , градусы = laserGun.rotation и рад = Math.PI/180 .

Во-вторых, мы создали переменную для максимального расстояния, которое должен пройти лазер:

1
var maxDist:Number = 250;

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

Laser_MaxDistance

В-третьих, у нас есть переменная для текущего расстояния лазера в момент пересечения с любым препятствием.

1
var adjustedDist:Number;

Когда на пути лазера возникает какое-либо препятствие, лазер блокируется, а не перемещается на максимальное расстояние.

Расстояние после блокировки лазера — не что иное, как отрегулированное расстояние в зависимости от ситуации.

Цикл for и hitTestPoint() играют важную роль в расчете этого расстояния.

Laser_AdjustedDistance

В-четвертых, мы изменили метод ProjectLaser() , добавив в ActionScript метод hitTestPoint() вместе с циклом for . Мы переназначили переменные endX и endY .

01
02
03
04
05
06
07
08
09
10
11
12
for (adjustedDist = 0; adjustedDist < maxDist; adjustedDist ++)
{
    //Trigonometry to aim the laser wrt laser gun’s rotation
    endX = laserGun.x + Math.cos ( laserGun.rotation * rad ) * adjustedDist;
    endY = laserGun.y + Math.sin ( laserGun.rotation * rad ) * adjustedDist;
 
    //calculate hit test
    if ( obstacles.hitTestPoint ( endX, endY, true ) )
    {
        break;
    }
}

Петля for гарантирует, что настроенное расстояние будет увеличено до максимального расстояния. Вы можете подумать: «Что интересного в том, чтобы настроить скорректированное расстояние равным максимальному расстоянию?»

На самом деле, это скорректированное расстояние разрешено таким образом, чтобы соответствовать максимальному расстоянию естественным образом, но как только оно hitTestPoint() с hitTestPoint() либо препятствиями (что определяется методом hitTestPoint() ), это расстояние помечается как максимальное расстояние для данной текущей ситуации. Спасибо hitTestPoint() за простую задачу.

Мы также переназначили значения endX и endY как:

1
2
endX = laserGun.x + Math.cos ( laserGun.rotation * rad ) * adjustedDist;
endY = laserGun.y + Math.sin ( laserGun.rotation * rad ) * adjustedDist;

Тригонометрические функции Math.cos() и Math.sin() используются для расчета угла поворота лазера относительно лазерной пушки.

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

Для получения дополнительной информации о тригонометрии, прочитайте этот Quick Tip .

Наконец кульминация сцены:

1
2
3
4
if ( obstacles.hitTestPoint ( endX, endY, true ) )
{
    break;
}

hitTestPoint() принимает три параметра, из которых первый и второй параметры необходимы, а третий ( shapeFlag ) будет оставлен в качестве значения по умолчанию (т.е. false ), если он не указан.

В нашем примере shapeFlag установлен в true так как мы хотим, чтобы обнаружение попадания соответствовало точной форме целевого объекта (т.е. obstacles ). Если для этого значения установлено значение false обнаружение попадания происходит относительно ограничивающей рамки этого объекта, а не точной формы.

Первый и второй параметры hitTestPoint() определяют точку (x, y), в которой проверяется пересечение с экранным объектом. В нашем случае obstacles endX том, что экранный объект, а endX и endY представляют точку пересечения на сцене.

Неясно? Правильно. Для упрощения мы разместим логику в следующей последовательности:

  1. Цикл for позволяет продолжить проецирование лазера (путем обновления endX и endY ), если он находится на максимальном расстоянии.
  2. hitTestPoint() ожидает прерывания цикла for как только увидит пересечение. Как только цикл for прерывается, endX и endY замораживаются.
  3. Наконец, эти замороженные endX и endY передаются в метод graphics.lineTo() .

Чтобы добавить вращение к лазерной пушке, нам нужно выполнить несколько важных изменений:

  1. ProjectLaser () метода ProjectLaser () .
  2. Размещение всей логики обнаружения попаданий в новом методе HitTest() .
  3. Добавление нового оператора laser.graphics.clear() в цикл for .
  4. Импортировать оператор import flash.events.Event

Сначала мы реструктурируем метод ProjectLaser() , переместив всю логику обнаружения попаданий в новый метод HitTest() .

Затем мы добавим laser.graphics.clear() перед оператором laser.graphics.lineStyle( 1, 0xFF0000 ) внутри цикла for нового метода HitTest() . Это удалит старую проекцию лазера со сцены, когда лазерная пушка начнет вращаться.

Посмотрим, как это будет выглядеть после внесения всех четырех основных изменений:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public function ProjectLaser():void
{
    laser = new Sprite();
    addChild(laser);
 
    //Set origin of the laser as the centre of the laser gun
    startX = laserGun.x;
    startY = laserGun.y;
}
 
//Hit test
public function HitTest():void
{
    for (adjustedDist = 0; adjustedDist < maxDist; adjustedDist ++)
    {
        //Trigonometry to aim the laser wrt laser gun’s rotation
        endX = laserGun.x + Math.cos(laserGun.rotation * rad) * adjustedDist;
        endY = laserGun.y + Math.sin(laserGun.rotation * rad) * adjustedDist;
 
        //calculate hit test
        if (obstacles.hitTestPoint(endX,endY,true))
        {
            break;
        }
    }
 
    //Draw laser
    laser.graphics.clear();
    laser.graphics.lineStyle( 1, 0xFF0000 );
    laser.graphics.moveTo( startX, startY );
    laser.graphics.lineTo ( endX, endY );
}

Вы можете спросить, почему мы сделали такие серьезные изменения? Единственная причина — событие ENTER_FRAME .

Чтобы применить непрерывное вращение, мы добавим новый метод LaserGunRotation( evt:Event ) который активируется событием ENTER_FRAME (это означает, что он запускается 24 раза в секунду, поскольку наша частота кадров составляет 24 кадра в секунду). Когда используется это событие, вы должны быть осторожны, чтобы добавлять только те свойства, которые мы хотим изменить в течение определенного периода времени. Избегайте ввода тех значений, которые остаются постоянными на протяжении всего выполнения.

В нашем случае, если вы наблюдаете старый метод ProjectLaser() , он имеет:

1
2
laser = new Sprite();
addChild(laser);

Представьте, если вы добавите вышеприведенные операторы в метод, который использует событие ENTER_FRAME ; затем новый лазерный объект Sprite будет создаваться и добавляться на сцену многократно — 24 раза в секунду.

Это абсолютно ненужно. Поэтому мы реструктурировали метод ProjectLaser() и добавили новый метод HitTest() . Вы можете переименовать метод ProjectLaser() в InitializeLaser() поскольку он больше не проецирует лазер. Теперь он только создает пустой держатель для лазера и определяет его начальную точку. Проекция обрабатывается новым методом HitTest() .

Теперь давайте посмотрим на новый метод LaserGunRotation( evt:Event ) . Перед этим добавьте следующий оператор импорта в начале класса документа:

1
import flash.events.Event;

И добавьте следующий метод:

1
2
3
4
5
6
7
//Rotate Laser Gun
public function LaserGunRotation( evt:Event ):void
{
    laserGun.rotation += 0.5;
 
    HitTest();
}

Также не забудьте вызвать этот метод с событием ENTER_FRAME внутри функции конструктора, как показано ниже:

1
2
3
4
5
6
7
8
9
//Constructor
public function Laser_HitDetection()
{
    CreateLaserGun();
    CreateObstacles();
    ProjectLaser();
     
    addEventListener( Event.ENTER_FRAME, LaserGunRotation );
}

Это позволяет запускать LaserGunRotation() 24 раза в секунду.

Проверьте фильм.

Ракета уже проникла в облака. Посмотри на прекрасную Землю.


На этом шаге мы добавим элемент управления для настройки точности обнаружения попадания. Это важно, поскольку вам не нужно каждый раз точно определять попадание; вам может понадобиться средний уровень обнаружения попаданий. Это также поможет снизить потребление ресурсов процессора во время обнаружения попаданий.

Мы введем новую переменную tolerance как:

1
var tolerance:Number = 1;

Затем мы изменим инструкцию приращения цикла for следующим образом:

1
for (adjustedDist = 0; adjustedDist < maxDist; adjustedDist += tolerance)

Теперь цикл for будет выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
for (adjustedDist = 0; adjustedDist < maxDist; adjustedDist += tolerance)
{
    //Trigonometry to aim the laser wrt laser gun’s rotation
    endX = laserGun.x + Math.cos(laserGun.rotation * rad) * adjustedDist;
    endY = laserGun.y + Math.sin(laserGun.rotation * rad) * adjustedDist;
 
    //calculate hit test
    if (obstacles.hitTestPoint(endX,endY,true))
    {
        break;
    }
}

Это означает, что вместо проверки столкновения на каждом пикселе лазерной линии, мы проверяем только на столкновение на каждом втором пикселе или на каждом третьем пикселе и т. Д.

Понижение значения «допуск» повысит точность определения попадания, но потребует больше ресурсов процессора. Попробуйте поэкспериментировать с разными значениями «толерантности».

Друзья, пора покинуть ракету и открыть парашют. Безопасно приземлитесь на землю и начните использовать вышеописанную технику в своих Flash-играх и приложениях Наслаждайтесь!


В этом уроке мы в основном увидели идеальное использование hitTestPoint() и цикла for для точного определения попадания без использования сложной математики.

Этот эффект может быть использован в экшн-игре типа безопасности, где требуются камеры и лазерное оружие.