среда, 16 мая 2012 г.

Урок 7. Метод hitTest. Определение столкновений. Часть 1

Прошу прощения за ОГРОМНЫЙ перерыв в ведении блога, сами понимаете учеба и всё такое...)
Итак! Так как я очень часто вижу на всяких форумах посвященных флешу вопросы типа "а как мнэ сделат, что-бэ чувак не ходил по стэнам?? ололо пыщь пыщь", то сегодня я попытаюсь вам рассказать как сделать "что-бэ чувак не ходил по стэнам", но для начала расскажу о методах определения столкновений, а всё остальное потом.
Для выполнения этого урока нужно знать предыдущие, так как для создания игр мы будем использовать все то что рассказывалось ранее.
За 2 части этого урока мы сделаем вот такие флешки:



Начнем! Для определения столкновений во флеше есть 2 метода hitTestObject и hiTestPoint. Рассмотри каждый из них. Как вы уже наверное поняли из названия, hitTestObject определяет пересечение объектов как бы это сказать... полностью. Сейчас все объясню на примере. Допустим у наc есть синий квадрат и зеленый треугольник
Назовем их box и triangle соответственно, и напишем такой код:
if(box.hitTestObject(triangle)){
 //то что то делать, например подсвечивать квадрат
}
Код мне кажется пояснений не требует.
При пересечение объектов будет что-то вроде
Всё вроде-бы хорошо, но у этого метода есть огромнейший недостаток. При проверке на столкновения с помощью данного способа флеш рисует вокруг объектов квадраты, и пересечения проверяет только по этим квадратам. Выглядит это примерно так:
И соответственно, если например повернуть треугольник, то когда эти квадраты пересекутся, даже если нет визуального контакта между объектами, то засчитается соприкосновение.
Теперь немного о hitTestPoint. Создадим треугольник и точку.
Напишем такой код:
if(triangle.hitTestPoint(point.x,point.y,true)){
 //то подсвечивать треугольник
}
Как вы уже наверное поняли метод hitTestPoint определяет пересечение не между объектом и объектом, а между объектом и координатой, только вот объект этот может быть любой формы, и квадрат вокруг него рисоваться никакой не будет.
Каждый из методов по своему удобен для разных целей. В этом уроке мы создаем две игры, первую с помощью метода hitTestObject, а вторую с помощью hitTestPoint. Приступим к созданию флешки  №1. Как создать пчелу и как сделать что-бы она летала описывать не буду, так как это рассматривалось в предыдущих уроках. Сразу приступим к созданию врага (ну или препятствия хз что там у вас будет в игре=)). Вот как он выглядит у меня:
На первом кадре анимация полета, на втором -  смерти. Код на кадре - stop(); В поле AS Linkage дайте ему имя "mosquito".
Для этого нажмите в библиотеке правой кнопкой мышки по мувику с противником, и выберите там "properties". После этого сделайте все как показано на изображение:
Теперь нужно, что-бы этот враг каким-то образом доставался из библиотеки и помещался на сцену. Сейчас мы этим и займемся. Для этого напишем следующий код:
var enemyArr:Array= new Array();//Создаем массив который будет хранить в себе всех врагов
var enemySpeed:Number=10;//Задаем скорость передвижения
const enemyNum:int = 20;//И количество врагов
for (var i=0; i<enemyNum; i++)
{
 var enemy:MovieClip= new mosquito();//Присваиваем переменной enemy мувиклип нашего врага из библиотеки
 enemyArr.push(enemy);//push добавляет значение в первую пустую ячейку
 enemyArr[i].x = Math.random() * 5000 + 600;//Размещаем врага случайным образом по иксу
 enemyArr[i].y = Math.random() * 350;//И по игрику
 addChild(enemyArr[i]);//Добавляем его на сцену
 addEventListener(Event.ENTER_FRAME,enemyMove);//создаем слушатель
}
function enemyMove(e:Event):void
{
 for (var i=0; i<enemyNum; i++)
 {
  var enemy=enemyArr[i];//присваиваем переменной enemy текущего врага
  enemy.x-=enemySpeed;//сдвигаем его
 }
}

Всё! Теперь нажимаем ctrl+enter и любуемся как комары летят на нашу пчелку!
Вот теперь пришло время использовать знания полученные в этом уроке. В функцию enemyMove после строки
enemy.x-=enemySpeed;//сдвигаем его
Пишем следующее:
if(bee.hitTestObject(enemy))//Если персонаж пересекается с врагом, то
  {
   enemy.gotoAndStop(2);//перейти на кадр со смертью
   bee.gotoAndStop(2);//перейти на кадр с подергивание
  }
  /*Так как после того как пролетят все 20 комаров, новые больше не летят. Надо это исправить.*/
  if(enemy.x<=-enemy.width/2)//Для этого проверяем вылетел ли комар за экран, если да, то
  {
   enemy.x = Math.random() * 5000 + 600;//размещаем его в случайном месте
   enemy.y = Math.random() * 350;//размещаем его в случайном месте
   enemy.gotoAndStop(1);//и переводим на первый кадр (это на тот случай, если комар был убит)
  }
Первая часть урока окончена. Вторая будет завтра, а сейчас спокойной ночи.

17 комментариев:

  1. Спасибо за урок

    ОтветитьУдалить
  2. Круто! даже самому столкновения обсчитывать не надо

    ОтветитьУдалить
  3. Здорово! Все просто и понятно! Продолжай! :)

    ОтветитьУдалить
  4. Спасибо) отличный урок) продолжай в том же духе)

    ОтветитьУдалить
  5. А зачем каждый раз в цикле "for (var i=0; i<enemyNum; i++)" создавать слушатель события Event.ENTER_FRAME??

    ОтветитьУдалить
  6. Этот комментарий был удален автором.

    ОтветитьУдалить
  7. затем что я тупанул)) сейчас пишу с телефона, уже второй месяц интернета нет, как появится исправлю, заодно и статью допишу))

    ОтветитьУдалить
  8. и где же продолжнение?

    ОтветитьУдалить
  9. Или урок скопипастен , или на аффтора напала ужжжосная болезнь и сожрала всю информацию о продолжении урока .

    ОтветитьУдалить
  10. ага кул бл**ь, а ни чё так что он мне пишет синтаксис ерор вот тут

    в это строчке
    const enemyNum:int = 20;//И количество врагов
    следовательно дальше у меня ничего не пойдёт....

    ОтветитьУдалить
    Ответы
    1. Попробуй удали комментарий
      Если что комментарий это вот эта часть "//И количество врагов"

      Удалить
  11. Как сделать тоже самое, только, чтоб комары шли сверху вниз?
    В этом случае у меня не получается эта часть:
    /*Так как после того как пролетят все 20 комаров, новые больше не летят. Надо это исправить.*/
    if(enemy.x<=-enemy.width/2)//Для этого проверяем вылетел ли комар за экран, если да, то
    {
    enemy.x = Math.random() * 5000 + 600;//размещаем его в случайном месте
    enemy.y = Math.random() * 350;//размещаем его в случайном месте
    enemy.gotoAndStop(1);//и переводим на первый кадр (это на тот случай, если комар был убит)
    }

    ОтветитьУдалить
    Ответы
    1. if(enemy.y<=stage.height+enemy.height)//Для этого проверяем вылетел ли комар за экран, если да, то
      {
      enemy.y = Math.random() * (-5000) - 600;//размещаем его в случайном месте
      enemy.x = Math.random() * stage.width;//размещаем его в случайном месте
      enemy.gotoAndStop(1);//и переводим на первый кадр (это на тот случай, если комар был убит)
      }
      попробуй, должно работать

      Удалить
    2. спасибо!

      Удалить
  12. не работает проверка столкновений с врагом

    ОтветитьУдалить
  13. Очень хотелось бы увидеть продолжение уроков:)

    ОтветитьУдалить