у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет. Вопрос знатокам, что не так? |
Обнаружение коллизий
Поддержка множества объектов в массиве
Вместо поддержки объектов самих по себе, которую мы использовали до сих пор, лучше поддерживать их на главной временной диаграмме. Самый удобный способ осуществить это - использовать массив. При создании каждого объекта мы добавляем его в массив, и тогда все наши объекты будут находиться в одном массиве для простоты доступа и управления.
- Используйте фильм из последнего упражнения с фильмом ball в Library и сохраните его под другим именем. Удалите все инстансы с рабочего места, а также весь имеющийся код. Начните с добавления в кадр 1 слоя actions этого кода.
init(); function init() { max = 10; balls_array = new Array(); for (n=0; n<max; n++) { balls_array[n] = attachMovie("ball", "b"+n, n) ; balls_array[n]._x = Math.random 0*550; balls_array[n]._y = Math.random()*400; balls_array[n].velX = Math.random()*10-5; balls_array[n].velY = Math.random()*10-5; balls_array[n]._xscale = balls_array[n]._yscale = Math.random()*50+30; } }
Здесь мы установили значение max, которое будет определять число создаваемых шариков. Затем создается массив для хранения в нем фильмов. Цикл для присвоения фильмов практически идентичен предыдущему файлу, за исключением того, что он присваивает фильм элементу массива и осуществляет доступ к нему через этот элемент для присвоения параметров. Мы также опустили управляющий элемент onEnterFrame, так как управление фильмами будет осуществляться извне.
- Вместо этого, мы добавим функцию onEnterFrame в _root. Сначала реализуем присвоение в функции init (под строкой max = 10; ):
_root.onEnterFrame = main;
- Теперь мы можем определить функцию main, в которой и будет заключаться весь смысл. Сначала обрабатываем циклом массив для передвижения каждого шарика по отдельности. Здесь все довольно просто.
function main() { for (i=0; i<balls_array.length; i++) { balls_array[i] ._x += balls_array[i] .velX; balls_array[i] ._y += balls_array[i] .velY; if (balls[i]_array._x>550) { balls[i]_array._x = 0; } if (balls[i]_array._x<0) { balls[i]_array._x = 550; } if (balls[i]_array._y>400) { balls[i]_array._y = 0; } if (balls[i]_array._y<0) { balls[i]_array._y = 400; } } }
Выглядит знакомо? Так и должно быть. Это тот же самый код, что и ранее, однако здесь мы осуществляем доступ к фильму извне через элемент массива, в котором он сохранен, вместо внутреннего доступа с использованием this. Запуститe фильм. Вы увидите десять кругов, в случайном порядке двигающихся по экрану. Теперь перейдем к обнаружению столкновений:
- В этом шаге мы будем использовать цикл for. Внешний цикл будет обрабатывать каждый элемент массива (содержащий ссылку на фильм), а внутренний цикл будет использоваться для проверки этого элемента относительно каждого последующего элемента в массиве. Приведем псевдокод, чтобы показать, как это реализуется.
for (i=0; i<balls_array, length-1; i++) { for (j=i+l; j<balls_array. length; j++) { // test between balls_array[i] and balls_array[j] here } }
Это еще одна ваша шпаргалка. Мы будем использовать код проверки коллизий на основе окружностей/расстояния для проверки столкновения шариков. В случае столкновения оба шарика будут удаляться.
- Чтобы удалить шарики, нам нужно будет удалить не только фильм, но также его ссылку в массиве. Мы реализуем это с помощью метода array.splice (index, number). Эта команда удаляет число number элементов из массива, начиная с index. Измените функцию main следующим образом.
function main() { for (i=0; i<balls_array.length; i++) { balls_array[i]._x += balls_array[i].velX; balls_array[i]._y += balls_array[i].velY; if (balls_array[i]._x>550) { balls_array[i]._x = 0; } if (balls_array[i]._x<0) { balls_array[i]._x = 550; } if (balls_array[i]._y>400) { balls_array[i]._y = 0; } if (balls_array[i]._y<0) { balls_array[i]._y = 400; } } for (i=0; i<balls_array.length-1; i++) { for (j=i+1; j<balls_array.length; j++) { dx = balls_array[i]._x-balls_array[j]._x; dy = balls_array[i]._y-balls_array[j]._y; dist = Math.sqrt(dx*dx+dy*dy); if (dist<balls_array[i]._width/2+ balls_array [j]._width/2) { removeMovieClip(balls_array[j]); balls_array.splice(j, 1); removeMovieClip(balls_array[i]); balls_array. splice(i, 1); } } } }
Пример 7.5. - В конечном итоге все фильмы уничтожат друг друга, поэтому мы сделаем так, чтобы они появлялись заново. Cоздадим управляющий элемент onMouseDown в начале функции init.
_root.onMouseDown = createBall;
- Теперь добавим эту новую функцию под всем имеющимся кодом.
function createBall() { ball_mc = attachMovie("ball", "b"+n, n++); ball_mc._x = _root._xmouse; ball_mc._y = _root._ymouse; ball_mc.velX = Math.random()*10-5; ball_mc.velY = Math.random()*10-5; ball_mc._xscale = Math.random()*50+30; ball_mc._yscale = Math.random()*50+30; ball_mc.onEnterFrame = ballMove; bal1s_array.push(ball_mc); }
Это похоже на код, использованный в init для создания исходных фильмов ball. Основное отличие заключается в том, что здесь ссылка на фильм записывается во временную переменную, присваиваются все его параметры, и затем используется array.push для добавления его в массив.
Интересным моментом при настройке наших циклов в функции main является то, что мы использовали balls_array.length для определения числа повторений. Параметр length массива будет обновляться при добавлении и удалении объектов из массива, поэтому наши циклы будут всегда выполняться нужное число раз.
- Запустите ваш фильм. Для проверки правильности написания кода, приведем полный исходный код программы.
init(); function init () { max = 10; _root.onEnterFrame = main; _root.onMousedown = createBall; balls_array = new Array(); for (n=0; n<max; n++) { balls_array[n] = attachMovie("ball", "b"+n, n); balls_array[n]._x = Math.random()*550; balls_array[n]._y = Math.random()*400; balls_array[n].velX = Math.random()*10-5; balls_array[n].velY = Math.random()*10-5 ; balls_array[n]._xscale = balls_array[n]._yscale= Math. random 0*50+30; } } function main() { for (i=0; i<balls_array.length; i++) { balls_array[i]._x += balls_array[i].velX; balls_array[i]._y += balls_array[i].velY; if (balls_array[i]._x>550) { balls_array[i]._x = 0; } if (balls_array[i]._x<0) { balls_array[i]._x = 550; } if (balls_array[i]._y>400) { bal1s_array[i]._y = 0; } if (balls_array[i]._y<0) { balls_array[i]._y = 400; } } for (i=0; i<balls_array.length-1; i++) { for (j=i+1; j<balls_array.length; j++) { dx = balls_array[i]._x-balls_array[j]._x; dy = balls_array[i]._y-balls_array[j]._y; dist = Math.sqrt(dx*dx+dy*dy); if (dist<balls_array[i]._width/2+ balls_array[j] ._width/2) { removeMovieClip(balls_array[j]); balls_array.splice(j, 1); removeMovieClip(balls_array[i]); balls_array.splice(i, 1); } } } } function createBall() { ball_mc = attachMovie("ball", "b"+n, n++); ball_mc._x = _root._xmouse; ball_mc._y = _root._ymouse; ball_mc.velX = Math.random()*10-5; ball_mc.velY = Math.random()*10-5; ball_mc._xscale = Math.random()*50+30; ball_mc._yscale = Math.random()*50+30; ball_mc.onEnterFrame - ballMove; balls_array.push(ball_mc); }
Пример 7.6. - Сохраните ваш фильм и закройте его (или поиграйте в игру, если желаете).