Воспоминания о Crimsonland 2: наведение на цель
27.02.2009, автор Stormit, рубрики: ActionScript, Flash игры, Игровые баннерыЭто небольшое дополнение к предыдущему посту, которое может сделать флеш-игру ещё интересней.
Очень часто разработчики, когда им нужно навести дуло на цель или направить монстра на жертву, делают это мгновенно. То есть, объект шёл в одну сторону, и тут бац.. идёт уже в другую. Это подходит для многих случаев и повышает контроль над ситуацией, мотивируя игрока проявить свои возможности, но иногда (а может и часто :)) нужно сделать чтобы дуло пушки или персонаж наводились на цель плавно.
Собственно небольшой код для реализации плавного поворота за мышкой (башня на слайде 1 крутится таким образом):
rotToMouseSpeed = 3;//скорость поворота function onEnterFrame() { mDx = _xmouse - body._x; mDy = _ymouse - body._y; mAngle = Math.atan2(mDy, mDx); //получаем угол между мышкой и башней в градусах mAngleD = mAngle / Math.PI * 180; //сколько градусов нехватает для полного поворота на мышь dAngleD = body._rotation - mAngleD; //без этой проверки башня будет неправильно крутиться //при переходе границы -180 и +180 градусов if (dAngleD > 180) { dAngleD = -360 + dAngleD; } else if (dAngleD < -180) { dAngleD = 360 + dAngleD; } //поворачиваем башню с нашей скоростью if(Math.abs(dAngleD) < rotToMouseSpeed) { body._rotation -= dAngleD; } else if(dAngleD > 0) { body._rotation -= rotToMouseSpeed; } else { body._rotation += rotToMouseSpeed; } }
Естественно вращение происходит вокруг центра клипа body, поэтому располагайте графику корректно.
Если вернуться к нашему Рэмбо, то же самое можно применить и к нему, нужно только учитывать ещё угол поворота самого клипа hero. Там упоминали что при переходе из крайне-левого положения в крайне-правое корпус неестественно дёргается - теперь этого не будет. Новый код выглядит теперь так (слайд 2):
var step = 2; var rotDirSpeed = 5; var rotToMouseSpeed = 7; onEnterFrame = function () { if (Key.isDown(Key.LEFT)) { hero._rotation -= rotDirSpeed; } else if (Key.isDown(Key.RIGHT)) { hero._rotation += rotDirSpeed; } var mDx = _xmouse - hero._x; var mDy = _ymouse - hero._y; //угол поворота между клипом hero и мышкой в градусах var mAngleD = Math.atan2(mDy, mDx) / Math.PI * 180; //угол поворота между башней и мышкой в градусах var dAngleD = hero._rotation + hero.body._rotation - mAngleD; //без этой проверки башня будет неправильно крутиться //при переходе границы -180 и +180 градусов if (dAngleD > 180) { dAngleD = -360 + dAngleD; } else if (dAngleD < -180) { dAngleD = 360 + dAngleD; } //поворачиваем башню с нашей скоростью if(Math.abs(dAngleD) < rotToMouseSpeed) { hero.body._rotation -= dAngleD; } else if(dAngleD > 0) { hero.body._rotation -= rotToMouseSpeed; } else { hero.body._rotation += rotToMouseSpeed; } //проверка на реализм поворота корпуса человека if(hero.body._rotation < -90) { hero.body._rotation = -90; } else if(hero.body._rotation > 90) { hero.body._rotation = 90; } var dirAngle = hero._rotation / 180 * Math.PI; if (Key.isDown(Key.UP)) { hero.foot.play(); hero._x += step * Math.cos(dirAngle); hero._y += step * Math.sin(dirAngle); } else if (Key.isDown(Key.DOWN)) { hero.foot.play(); hero._x -= step * Math.cos(dirAngle); hero._y -= step * Math.sin(dirAngle); } else { hero.foot.stop(); } }; onMouseDown = function () { hero.body.play(); };
Если у вас что-то не получается, убедитесь что на линейке присутствуют все необходимые символы, правильно вложены друг в друга, правильно названы и код прописан в нужных местах. Об этом говорилось накануне.
Ну и в жизни это стало немного по другому (слайд 3). Подобными вещами можно задавать сложность игры (помните, при старте: easy, medium, hard, nightmare). Конечно, попутно меняя скорость движения, время, очки и т.д.
Ещё пример как можно использовать плавный поворот:
Интересно на 70%




Прикольно! когда можно будет поиграть в окончательные варианты? с зомби оч интересно) музычку б подложить, мрачненькую, покряхкивания монстров при их смерти, ну и бонусы, пушки, нунчаки, мечи, адуванчики в качестве оружия:) плюс вести онлайн рекорды, эх:)
3-й слайд это почти окончательный вариант игрового баннера. Правда в оригинале главный герой бегал за мышкой. Хочу в следующей статье написать о том как запускать снаряды и разводить зомби.
какой то странный глюк в нижней влешке, иногда прицел плавно сам по себе съезжает в сторону ближе к башне %)
ещё очень не хватает инерции, все равно пушка дергается когда поворот из одной стороны сменяешь на другую.
Этот способ более ресурсозатратный чем если ипользовать векторное произведение векторов
>>иногда прицел плавно сам по себе съезжает…
Это не глюк, прицел выстраивается по центру если им не водить 5 секунд (осталось с баннера)
>>Этот способ более ресурсозатратный чем если ипользовать векторное…
класс Вектор ещё будет, потом сравним плюсы и минусы
Нее я про векторное произведение 2х векторов а не класс “вектор”. Или что ты имел в виду?
if (dAngleD > 180) {
dAngleD = -360 + dAngleD;
} else if (dAngleD < -180) {
dAngleD = 360 + dAngleD;
}
Спасибо! Когда-то голову сломал об это (компас рисовал, будто курсор выполняет функцию магнита).
Я про класс Vector, а как здесь работает векторное произведение векторов?
Все отлично работает, а как сделать выстрел, что бы цель поражать? Я так понимаю снаряд каким то образом по координатам должен совпасть с целью? Нельзя ли какой нибудь простенький пример на эту тему? Очень был бы благодарен.
“Я про класс Vector, а как здесь работает векторное произведение векторов?”
Просто смотришь знак векторного произведения и исходя из него поворачиваешь объект. При нахождении дэтерменанта матрицы координаты Z считать равными 0
2Georgi, самый простой вариант:
if (Bullet.hitTest(Zombie)) {
Zombie.gotoAndPlay(”dead”);
}
Bullet - это мувик пули, а Zombie - это мувик зомби. Только с пулей тоже надо что-то делать когда попадаем в зомби, например скрывать.
Domik, Спосибо буду пробовать!
Попробывал,ничего не выходит с пересечением объектов, создал мувик торпеды(tor) и мувик цели(zombie),которая при попадании должна измениться.В мувике торпеды написал код:
onClipEvent (load) {
speed=10;
onEnterFrame=function(){
_x+=speed;
if (tor.hitTest(Zombie)) {
Zombie.play();
}
}
}
торпеда проходит,а условие не выполняется. Подскажите пожалуйста где ошибка?
Georgi : У тебя же зомби находятся не внутри торпеды? Тогда возможно следует так
onClipEvent (load) {
speed=10;
onEnterFrame=function(){
_x+=speed;
if (this.hitTest(_parent.Zombie)) {
_parent,Zombie.play();
} } }
Если у тебя код весит на самой торпеде то не обязательно указывать при проверке if (tor.hitTest(Zombie)) - достаточно использовать this (он будет указывать на себя (на торпеду)), а вот если ты в торпеде поместил какой-то символ с которым будеш выполнять проверку тогда нужно будет указывать его имя.
Указывай правильный путь к Zombi, не забывай что они находятся на разной глубине клипов.
вот теперь дошло.спосибо. Все работает.
У меня опять вопрос, есле можно. Пытаюсь сделать игру. Такая раньше в автоматах(атракционы) была.Плывут корабли и с перескопа подлодки торпедами их топишь. Проблема вот в чем: Корабль плывет я в него попадаю он взрывается и тонет, на этом игра останавливается. а как сделать чтобы как то зациклить что ли, т.е обратно с начала она началась? Посоветуйте что нибудь пожалуйста!
Georgi - а зачем вам эта игра?
Вариант: раз в 5 секунд (например) создаётся программно корабль (attachMovie() или duplicateMovieClip()) и начинает двигаться. Если уходит за край экрана или умирает, просто удаляется (removeMovieClip()). Такая игра будет вечной, пока вы не определите условие для победы.
dedpbIxto-Зачем игра? да все просто: в детстве она мне очень нравилась, а на ее примере мне легче продвигаться в изучении флеш.
Stormit-Большое спосибо за подсказку теперь понял как.
Что то у меня не идет! Дублирую клип, он дублируется, задаю другое место-появляется два, но вот как это связать чтоб они ходили друг за другом? Например создаю мувик в нутри програмно задаю движение. В кадре дублирую-двое движуться, а как сделать так чтоб они постояно ходилили друг за другом? Примерно как в этой флешке самолеты постоянно появляются. На этом полностью застопорился. Помогите пожалуйста!
Респект!
Но почему вы никогда не выкладываете код полностью?
(исходник)
Исходники я удаляю сразу после написания статьи чтобы не было соблазнов.
*спустя год*
все получилось
большое спасибо!
былоб прекрасно если ваша статья была бы дополненна видеоматериалом заснятым в процессе …
ну или сделайте видеокурс для новичков или для тех кто хочет но не пытался создать игру так как не знает с чего начать . на этом можете заработать так как видеокурсов в нете полно .. но про создание игр вроде как ни слова . и про флеш только сайты
Деньги нужно зарабатывать на богатых людях, а делать платные видеоуроки для обычных людей, который вчера школу окончил, а сегодня крякнутый флеш установил - мне совесть не позволяет.
Может в будущем, при удачном стечении обстоятельств
Посещайте почаще флеш-конференции, это отличная возможность пообщаться с опытными разработчиками вживую и узнать много полезного.
Здрасте автару
Не могли бы вы объяснить как организуется выстрел и попадание по цели?
По вашим статьям сделал и танк и медленную анимацию. Но не могу создать полноценный игры. Не пойму как создать объект по которому будет попадать выстрел. Пожалуйста можно по подробнее? Буду очень признателен.
При выстреле помещаем снаряд на конец пушки и задаём ему speedX и speedY чтобы он двигался в направлении, куда смотрит пушка. Дальше, на onEnterFrame клип со снарядом прибавляет к своим координатам эти скорости и проверяет себя на пересечение с противниками ( hitTest() ). Как только есть пересечение, удаляем клип-снаряд со сцены и запускаем анимацию умирания/повреждения в противнике. Например, так.
Ещё бы очень хотелось ответ на такой вопрос: Можно ли сделать что при попадании, будь то дистанционная атака или близкая, выполнялось действие как по кнопке?
Например у меня есть приложение-визитка. Там при нажатии на кнопки открывается аватарка и пара слов. Очень бы классно было сделать такое: при атаке по этой кнопке выполняется действие, но при этом что бы нельзя было её просто нажать.
Хм. Почти понял. Спасибо за такую резкость)) А что на счет второго?
onMouseDown = function () {
hero.body.play();
в этом участке будет задана координата скорости по Х:У и проверка на столкновение?
};
Простите если вопросы глупые. Если можно отправьте туда где можно почитать эту стадию
Скажите пожалуйста, как вы создаете такой след за самолетом?
Летит самолёт и каждый кадр располагает сзади себя мувиклип (duplicateMovieClip()) внутри которого анимация где облачко сначала растёт, а затем плавно исчезает, после чего клип удаляется со сцены. Сам клип с облачком содержит анимацию где белое облачко переходит в чёрное и остановлен в первом кадре. Когда подбиваем самолёт, дублируя каждое новое облачко, переводим его в более тёмный кадр. Вроде бы так, насколько помню.
Тема классная, все предельно четко и доступно. Спасибо большое!
Можно исходники попросить?
info@strahovie-spori.com
Заранее спасибо!
Люди! Делаю игру, танчики))) и делаю прицел мышкой, она не по центру ходит, также изменяет свое положение((( ЧТО ЭТО! ПоМОГИТЕ!