у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет. Вопрос знатокам, что не так? |
Обнаружение коллизий
Кубок мира по пинг-понгу
- Оставьте последний фильм открытым на протяжении всего данного упражнения, так как мы будем использовать его код в качестве основы. Удалите левую и правую стенки и замените их "ракетками". В качестве ракетки вы можете просто нарисовать вертикальную линию любой длины и преобразовать ее в фильм с именем pc (я добавил надписи на ракетках, чтобы следующий рисунок был понятнее).
- Создайте дубликат фильма pc и назовите его player. Перетащите инстансы обоих фильмов на рабочее место и разместите их на новом слое с именем paddles.
- Назовите инстансы именами pc_mc и player_mc соответственно. Вручную разместите pc на позиции (50,200) и player на (500, 200). Позиции _y не так важны, так как они будут динамически обновляться в нашем ActionScript, а их стартовым значением будет центр поля.
- Начнем с добавления нескольких управляющих элементов onEnterFrame для двух ракеток.
init(); function init() { RIGHT = 500; LEFT = 50; TOP = 50; BOTTOM = 350; ball_mc.velX = 0; ball_mc.velY = 0; ball_mc.onEnterFrame = move; pc_mc.onEnterFrame = pcMove; player_mc.onEnterFrame = playerMove; }
- Дальше определяем функции pcMove и playerMove. pcMove начинается как простое уравнение приближения, поэтому ракетка компьютера будет всегда пытаться попасть на позицию шарика. Чтобы было интереснее, мы позволим этой ракетке двигаться только в том случае, если шарик передвигается в ее направлении (ball_mc.velX<0). Ракетка player, т.е. ракетка игрока? будет просто проверять нажатие клавиш [ВВЕРХ] и [ВНИЗ] и, в случае нажатия, перемещаться, соответственно, вверх или вниз. В обоих случаях с ракетками будет использоваться проверка коллизий по расстоянию, чтобы не допустить их исчезновения с игрового поля.
function pcMove() { if (ball_mc.velX<0) { this._y += (ball_mc._y-this._y)/5; } if (this._y>bottom-this._height/2) { this._y = bottom-this._height/2; this.vy = 0; } if (this._y<top+this._height/2) { this._y = top+this._height/2; this.vy = 0; } } function playerMove() { if (Key.isDown(Key.UP)) { this._y -= 10; } else if (Key.isDown(Key.DOWN)) { this._y += 10; } if (this._y>bottom-this._height/2) { this._y = bottom-this._height/2; this.vy = 0; } if (this._y<top+this._height/2) { this._y = top+this._height/2; this.vy = 0; } }
Пример 7.2. - Начальные скорости шарика установлены на значение 0, чтобы можно было принимать решение, где и когда начинать игру. Это реализуется присвоением _root функции приемника событий Key, а также установкой события onKeyDown на начало движения шарика. Добавьте следующие четыре строки в функцию init и затем создайте функцию serve в конце всего кода.
Key.addListener(_root); _root.onKeyDown = serve; pcServe = true; baseSpeed = 10; function serve() { if (Key.getCode(j == Key.SPACE) { if (playerServe) { ball_mc.velX = -baseSpeed; ball_mc.velY = Math.random()*20-10; playerServe = false; } else if (pcServe) { ball_mc.velX = baseSpeed; ball_mc.velY = Math.random()*20-10; pcServe = false; } } }
Теперь при запуске игры, шарик не движется до тех пор, пока вы не нажмете пробел. Когда значением pcServe станет "истина", будет выполнен второй блок, и шарик направится к ракетке игрока.
- Если запустить код сейчас, перед вами будет неплохая игра в пинг-понг, однако будет заметен один недостаток. Попробуйте упустить шарик - он все равно отскочит. Вспомните, что мы не реализуем здесь настоящего столкновения с ракеткой, а лишь пользуемся математическим вычислением позиции шарика. Вместо того, чтобы переделывать пол-игры, мы лишь внесем некоторые изменения. Мы будем проверять, ударяется ли шарик перед отскоком именно о ракетку.
Это значит, что шарик должен находиться ниже верхнего края ракетки, но выше нижнего ее края. Если он находится между этими двумя точками при ударе о right, значит, есть попадание. Если шарик пролетел мимо, он исчезает. Здесь мы могли бы применить старый добрый hitTest, однако я воспользуюсь этим случаем для представления новой концепции и действия под названием getBounds. Это одна из редко используемых команд. Она как бы разбивает hitTest на составные части и позволяет использовать именно те из них, которые необходимы.
getBounds - это метод объекта movieClip. При вызове он возвращает объект. Этот объект имеет четыре параметра, которые сообщают нам о местоположении фильма. Вот способ использования данного метода.
boundsObject=movieClip.getBounds (scope);
boundsObject имеет следующие четыре параметра: xMin, xMax, yMin и yMax. Они логически соответствуют четырем краям граничного прямоугольника фильма. Однако, вместо того, чтобы заставлять Flash вычислять, что находится внутри, а что вне рамки, мы теперь можем работать с численными значениями. Теперь можно математическим путем определять наши собственные коллизии, пользуясь значением ширины и т.п., как мы делали в случае со стенками.
Единственное, что осталось здесь определить, это параметр scope (область). Параметры min и max возвращаемого объекта boundsObject представлены в пикселях, но относительно чего? Это и есть наша область. В основном вам нужно будет вводить _root в качестве области, или любую другую позицию на временной диаграмме, на которой вы осуществляете проверку коллизий. Это даст вам значения X и Y фильма из _root.
Если вы сделали сам фильм областью, он будет возвращать значения своих углов такими, каковы они есть с его точки зрения. Например, квадрат со стороной 100 пикселей с центральной точкой регистрации всегда будет возвращать значения -50 и 50 в качестве минимального и максимального значений, независимо от того, в каком месте экрана находится фильм. С точки зрения фильма, он распространяется на 50 пикселей вверх от центра, на 50 пикселей вниз, на 50 влево и на 50 вправо.