onClipEvent(load) {
_root.initGame();
onClipEvent(enterFrame) {
_root.newBalloon() ;
_root.moveBalloons() ;
_root.moveFox();
_root.moveBullets();
}
function initGame() {
// Инициализируем переменные, связанные с объектами-шарами.
nextBalloonTime = 0;
nextBalloon = 0;
balloons = [];
numBalloons = 10;
// Инициализируем переменные,
nextBulletTime = 0;
function newBalloon () {
// Определяем, могут ли появиться новые шары,
if (nextBalloon < numBalloons) {
// Проверяем, пришло ли достаточно времени
// после появления последнего шара,
if (getTimerO > nextBalloonTime) {
// "Бросаем монетку",
if (Math.Random()
"balloon"+nextBalloon,
// Создаем новый шар.
attachMovie("balloon", nextBalloon);
// Выбираем, с какой стороны
// и с какой скоростью полетит шар.
if (Math.Random()
_root["balloon"+nextBalloon]._x = -30;
dx = int(Math.Random()*3)+3;
} else {
_root["balloon"+nextBalloon]._x = 580;
dx = -int(Math.Random()*3)-3;
// Выбираем высоту.
_root["balloon"+nextBalloon]._y = int(Math.Random()*100)+20;
// Выбираем цвет.
balloonColor = new Color("balloon"+nextBalloon)
r = int(Math.Random()*5)+1;
if (r == 1) {
balloonColor.setTransform({rb:255}) ;
} else if (r == 2) {
balloonColor.setTransform({gb:255}) ;
} else if (r == 3) {
balloonColor.setTransform({bb:255}) ;
} else if (r == 4) {
balloonColor.setTransform({rb:255,gb:255});
} else if (r == 5) {
balloonColor.setTransform({rb:255,bb:255});
}
// Добавляем новый шар.
balloons.push({clip:"balloon"+nextBalloon,d:dx});
// Изменяем значение переменных.
nextBalloon++;
nextBalloonTime = getTimerf) + 2000;
}}
}}
Чтобы быстро задать 50-процентную вероятность, лучше использовать фрагмент кода (Math. Random ()
Имейте в виду, что в цикле for функции moveBalloons перечисление осуществляется в обратном порядке: начинается с последнего элемента в массиве balloons и заканчивается 0. Благодаря этому удаление элемента не влияет на остальную часть массива. Предположим, из массива, состоящего из пяти элементов, был удален третий элемент. Тогда четвертый элемент становится третьим, а пятый - четвертым. Если бы вы считали в прямом направлении, вы бы пропустили третий элемент и сразу перешли к четвертому. При счете в обратном порядке такой проблемы не возникает.
function moveBalloons() {
// Перемещаем все шары,
for(i=balloons.length-1;i>=0;i--) {
// Определяем скорость шара
//и получаем ссылку на клип,
dx = balloons[i].d; balloon = _root[balloons[i].clip];
// Перемещаем шар.
balloon._x += dx;
// При вылете за экран шар удаляется,
if ((dx < 0) and (balloon._x < -20)) {
balloon.removeMovieClip() ;
balloons, splice (i,l);
} else if ((dx > 0) and (balloon._x > 570) balloon.removeMovieClip();
balloons.splice(i,1);
// Если шары закончились, игра завершается.
if ((nextBalloon >= numBalloons) and (balloons.length < 1)){
gotoAndStop("game over");
}}
function moveFox () {
// Подвинуть лису влево.
if (Key.isDown (Key.LEFT)) {
dx = -10;
fox._xscale = Math.abs(fox._xscale);
// Подвинуть лису вправо, перевернув ее клип по вертикали.
То есть изменив знак у свойства _scale, мы создаем зеркальное отражение клипа; лиса теперь идет в другую сторону.
}else if (Key.isDown(Key.RIGHT)) { dx = 10;
fox._xscale = -Math.abs(fox._xscale);
// Иначе лиса не двигается.
} else {
dx = 0;
// Перемещаем лису.
fox._x += dx;
if ((dx == 0) and (fox._currentFrame != 1)) {
// Переходим к кадру, в котором лиса стоит,
fox.gotoAndStop(1);
} else if ((dx != 0) and (fox._currentFrame == 1)) {
// Переходим к кадру, где лиса бежит.
fox.gotoAndPlay(2);
}
}
function shootBullet () {
// Проверяем, что с момента
// предыдущего выстрела прошло достаточно времени.
if (getTimerO > nextBulletTimei {
// Создаем новую пулю.
attachMoviet"bullet", "bullet'4nextBullet,nextBullet+9999) ;
// Устанавливаем ее координагы.
_root ["bullef+nextBullet] ._jc = fox._x+2;
_root [ "bullef+nextBullet] ._y = fo.x._y-55;
/ / Добавляем новую пулю к массиву.
bullets.push(nextBullet) ;
// Изменяем значение переменных, отвечающих
//за появление пуль.
nextBullet++;
nextBulletTime = getTimer()+1000;
}}
function moveBullets () {
/7 Проверяем, попали ли пули в шар.
for(i=bullets.length-1;i>=O;i--) {
// Выбираем элемент.
bullet = _root["bullet"+bullets[i]];
// Передвигаем пулю вверх,
bullet._y -= 10;
// Выясняем, достигла ли она конца экрана,
if (bullet._у < 0) {
bullet.removeMovieClip();
bullets.spliced,1) ;
// Определяем, не попал ли игрок по шару.
} else {
if (checkCollision(bullet)) {
bullet.removeMovieClip();
bullets.splice (i,1);
}}
}}
Почему для определения попадания используется функция distance, а не hitTest? Причина в том, что функция hitTest выдает значение true в случае, если снаряд попадет в любую часть шара, в том числе и в нитку, которая его держит
function checkCollision(bullet) {
// Просматриваем все шарики,
for(j =balloons.length-1;j >=0;j--) {
balloon = __root[balloons!j].clip];
// Проверяем, попала ли пуля.
if (distance(bullet,balloon) < 10) {
// Переходим к кадру, в котором шар взрывается.
balloon.gotoAndPlay(2);
// Убираем шар из массива,
balloons.splice(j,1);
// Увеличиваем счет,
score += 1;
// Возвращаем значение true,
return(true);
// Если игрок не попал, возвращаем значение false,
}}
return(false);
}
function distance(clipl, clip2) {
// Определяем расстояние между клипами,
dx = clipl._х - clip2._x;
dy = clipl._y - clip2._y;
return (Math.sqrt(dx*dx+dy*dy));
}
onClipEvent(load) {
root.initGame();
onClipEvent(enterFrame) {
_root.newBalloon ();
_root.moveBalloons() ;
_root.aimStraw();
_root.moveBullets() ;
}
Углы измеряются в радианах или градусах. Полный круг в радианах будет равен 6,28 (2Pi), в градусах - 360. Радианы используются Flash в математических функциях наподобие Math.sin и Math.cos, а градусы - в параметрах клипов „rotation. Поэтому вы должны уметь преобразовывать значения из одних единиц измерения в другие.
Функция Math.atan2 является прекрасным инструментом для программирования игр. Арктангенс (во Flash - Math.atan) представляет собой функцию, вычисляющую угол наклона линии. Так как такой наклон определяется двумя точками, с помощью арктангенса можно преобразовать координаты этих точек в значение угла наклона. Однако при использовании арктангенса не учитывается, какая точка линии является анкером, а какая указателем, задающим угол. Поэтому легко получить углы, противоположные по значению тем, которые вам необходимы. Для того чтобы учесть различные варианты, необходимо написать несколько условных выражений. Функция Math.atan2 (y,x) вычисляет угол наклона линии между началом координат и точкой с координатами (х, у,). Тем самым решается проблема неоднозначности.
function aimStraw() {
// Определяем разницу координат начала
//и конца линии.
dx = _xmouse - straw._x;
dy = _ymouse - straw._y;
// Вычисляем угол наклона.
strawRadians = Math.atan2(dy,dx);
// Переводим полученное значение в градусы.
strawDegrees = 360*strawRadians/(2*Math.PI);
straw._rotation = strawDegrees;
}
Функции Math.sin и Math.cos используются здесь для определения горизонтальной и вертикальной сторон угла. Для того чтобы наглядно представить это, возьмем круг, центр которого находится в точке 0,0; крайняя верхняя точка имеет координаты 0, -1(система координат, в которой ось Y направлена вниз); крайняя правая - 1,0. Задав в функции Math.sin любой угол, вы получите координату y этого угла на окружности. Функция Math.cos позволяет вычислить координату х. Таким образом, значение Math, sin (0) будет равно (-1), значение Math.cos (0) - 0, что соответствует координатам 0, -1.
Более важно понять то, что перемещение имеет две составляющие: скорость и угол. Значения расстояний для монитора компьютера не могут быть заданы по диагонали, они задаются только по вертикали и горизонтали. Функции Math, sin и Math.cos позволяют преобразовать значения скорости и угла в расстояние по горизонтали и вертикали.
function shootBullet () {
// Проверяем, можно ли выстреливать следующую пулю,
if (getTinerO > nextBulletTime) {
// Создаем пулю.
attachMovie("bullet","bullet"+nextBullet, L.nextBullet+9999);
bullet = _root["bullet"+nextBullet];
// Устанавливаем координаты.
bullet._x = straw._x + Math.cos(strawRadians)*20;
bullet._y = straw._y + Math.cos(strawRadians)*20;
// Добавляем в массив информацию о пуле:
// clip = название клипа,
// angle = начальный угол,
// down = эффект гравитации.
bullets.push({clip:bullet.angle:strawRadians,down:0}
// Увеличиваем счетчик пуль.
nextBullet++;
nextBulletTime = getTimer()+1000;
}}
function moveBullets() {
// Перемещаем все снаряды.
for(i=bullets.length-1;i >=0;i —) {
// Определяем название клипа,
bullet = bullets[i].clip;
// Перемещаем клип.
bullet._x += Math.cos(bullets[i].angle)*10;
bullet._y += Math.sin(bullets[i].angle)*10;
// Добавляем искажение траектории
// из-за воздействия гравитации.
bullet._у += bullets[i].down;
// Увеличиваем значение параметра гравитации,
bullets[i].down += .2;
// Выясняем, достигла ли пуля земли,
if (bullet._у > 400) {
bullet.removeMovieClip();
bullets.splice(i,1);
// Определяем, есть ли попадение.
} else {
if (checkCollision(bullet)) {
bullet.removeMovieClip();
bullets.spliced(i, 1) ;
}}
}}
onClipEvent(load) {
_root.initGame();
onClipEvent(enterFrame) {
_root.moveBalloons();
_root.moveFox();
_root.moveBullets();
}
function initGame() {
// Создаем шарики.
createBalloons О;
// Параметры снарядов.
nextBulletTime = 0;
nextBullet = 0;
bullets = [];
// Переменная счета.
score =0;
}
function createBalloons() {
balloons = new Array();
balloonNum = 0;
// Создаем новый ряд.
forfvar y=0;y
for(var x=0;x
// Создаем и размещаем новый шарик.
attachMovie("balloon", "balloon"+balloonNum, balloonNum) ;
balloonClip = this["balloon"+balloonNum];
balloonClip._x = x*30+20;
balloonClip._y = y*30+20;
// Добавляем в массив,
balloons, push (balloonClip) ;
// Устанавливаем цвет.
balloonColor = new Color(balloonClip);
if (y == 0) {
balloonColor.setTransform({rb: 255});
} else if (y == 1) {
balloonColor.setTransform({gb: 255});
} else if (y == 2) {
balloonColor.setTransform({bb: 255});
balloonNum++;}
}
// Направление (скорость) шариков.
balloonDirection = 3;
}
function moveBalloons() {
// Переменная-флаг изменения направления,
var newDirection = false;
// Просматриваем все шарики,
for(var i=0;i
// Передвигаем текущий шарик,
balloons[i]._x += balloonDirection;
// Смотрим, не достиг ли шарик границы экрана.
if ((balloonDirection > 0) and (balloons[i]._x > 530)) {
newDirection = true;
} else if ((balloonDirection < 0) and (balloons[i]._x < 20)) newDirection = true;
// При столкновении с границой экрана
// шарики опускаются и меняют направление.
if (newDirection) {
balloonDirection *= -1;
for(var i=0;i < balloons.length;i++) {
balloons[i]._y += 3;
//He достигли ли шарики земли?
if (balloons[i-l],_y > 300) {
gotoAndStop("game over");
}
}
function checkCollision(bullet) {
// Просматриваем все шарики,
for(j=balloons.length-1;j>=0;j—) {
balloon = balloons[j];
// Смотрим не попала ли пуля в шарик,
if (distance(bullet,balloon) < 10) {
// Удаляем шар из массива,
balloons.splice(j,1);
// Переходим в кадр взрыва шарика,
balloon.gotoAndPlay(2);
// Увеличиваем счет, score += 1;
// Если шаров больше нет - игра заканчивается,
if (balloons.length == 0) {
gotoAndStop("game over");
}
// Возвращаем значение true, так как попали в шарик,
return(true);
}}
// Возвращаем false, поскольку попали в шарик,
return(false);
}