Простой платформенный движок для флеш-игр
16.06.2009, автор Stormit, рубрики: ActionScript, Flash игрыЧтобы сделать игру как на примере (слайд 12), не нужны продвинутые знания в физике и математике. По сути, мало что нужно вообще, потому как флеш располагает всем необходимым, чтобы сделать неплохую платформенную игру без особых усилий.
Обычно для определения столкновений фигур используются непростые математические расчёты проекции векторов. И это часто оправдано, так как позволяет сделать игры с реальным поведением объектов. Но если реальной физикой в вашей игре можно пренебречь, то организовать прогулки по платформенному миру - не проблема. Герой дня - популярная функция hitTest(), которая и будет решать все вопросы определения столкновений.
У этого движка есть свои плюсы и минусы. К недостаткам можно отнести:
1) отсутствие физики (есть только гравитация)
2) отсутствие наклонных поверхностей
3) платформы только прямоугольной формы
4) в сложных уровнях, во избежание глюков, требует дополнительной настройки персонажа
5) есть небольшая “дерганность” персонажа при контакте с платформами (связано с тем, что пересечение с платформой компенсируется не по направлению движения, а с раскладкой на оси X и Y).
К достоинствам:
1) прост в разработке
2) простое и быстрое построение уровней сложной формы
3) персонаж автоматически шагает по невысоким ступенькам
4) несёт в себе определённую стилизацию и хорошо подходит для пиксельной графики.
Пошаговая инструкция:
- Для начала создадим персонажа. Я делаю это так: рисование в виде контурных линий (с раскладкой частей тела по слоям), разукрашивание и конвертация в символы всех значимых элементов. Слайд 1.
(Полезная деталь - кисти рук обрамляются неразрывной контурной линией, а сама рука без линий на запястье и в плече. Это позволяет крутить символы под разными углами с правильным наложением. Так же с ногами.) - Создаём структуру символов как на слайде 2. В главном клипе героя hero есть 3 кадра в которых расположены символы с одинаковым именем man, содержащие разные состояния героя: 1) стоит на месте; 2) идёт; 3) в прыжке. Если в вашей игре персонаж может погибнуть, это состояние можно поместить в 4-й кадр.
- Добавим нашему персонажу возможность атаковать. В этом примере нельзя бить на ходу или в прыжке, поэтому анимацию удара сделаем только в положении “стоит на месте” - hero.man (1 кадр). Внутри символа man оборачиваем руки, туловище и голову в клип body и внутри него делаем анимацию удара. Слайд 3.На слайде обозначены 4 кадра с кодом, которые требуют пояснения. Превый кадр - stop() - остановить персонажа в состоянии готовности (покоя). Второй кадр - play() - не знаю природу этого глюка, но иначе при ударе на ходу персонаж “зависает”. 3-й скриптовый кадр - примерно тут должна быть проверка на попадание по противникам (там где происходит удар). Последний кадр сбрасывает флаг отвечающий за состояние удара (дальше в коде он будет включаться при нажатии клавиши ПРОБЕЛ).
Если вы захотите сделать, чтобы персонаж мог атаковать на ходу и в прыжке, позаботьтесь чтобы в этих состояниях были клипы body с соответствующим кодом и анимацией. - Персонаж готов и пора его проверить. Этот временный код позволяет попробовать персонажа в действии и на раннем этапе поправить анимацию, если это необходимо.
//считаем что изначально персонаж стоит на поверхности var groundY = hero._y; //сила гравитации var grav = 1; //начальная скорость прыжка var jumpSpeed = -11.9; //шаг по Х var speedX = 5; //шаг по Y var speedY = 0; //максимальная скорость падения var maxSpeedY = 14; //отображает состояние прыжка var jump = false; //отображает состояние удара var shoot = false; Key.addListener(this); onKeyDown = function () { //прыгаем if (Key.isDown(Key.UP) && !jump && !shoot) { jump = true; speedY = jumpSpeed; } //бъём if (Key.isDown(Key.SPACE) && !jump && !shoot) { shoot = true; hero.gotoAndStop(1); hero.man.body.gotoAndPlay(2); } }; function stepHero() { if (!shoot) { //смещаемся влево/вправо if (Key.isDown(Key.LEFT)) { hero._xscale = -100; hero._x -= (jump) ? speedX * .8 : speedX; } else if (Key.isDown(Key.RIGHT)) { hero._xscale = 100; hero._x += (jump) ? speedX * .8 : speedX; } } //применяем по цепочке: гравитация -> скорость -> _y speedY += grav; speedY = (speedY > maxSpeedY) ? maxSpeedY : speedY; hero._y += speedY; if(hero._y > groundY) { hero._y = groundY; speedY = 0; jump = false; } if (!shoot) { if (jump) { //в позу полёта hero.gotoAndStop(3); } else { if (oldX != hero._x) { //если позиция по Х изменилась - в позу хотьбы hero.gotoAndStop(2); } else { //иначе - по стойке смирно hero.gotoAndStop(1); } } } oldX = hero._x; } onEnterFrame = function () { stepHero(); };
- Получаем примерно то что на слайде 5. В коде текущее положение персонажа считается поверхностью земли, так что для наглядности можно нарисовать опору у него под ногами.
- Главная хитрость. Добавляем в клип hero 4 символа и располагаем их по сторонам света (начиная с “восточного” и дальше по часовой стрелке называем их p1, p2, p3, p4). Назовём их условно “маркеры”. По этим зонам мы будем проверять пересечение с платформами методом hitTest(). Также эти маркеры определяют расчётные габариты персонажа (ширину и высоту). Поэтому размещать их нужно не “от балды”, а так чтобы они совпадали со ступнями, головой и, как минимум, туловищем. Чтобы не было сползания графики, суммарно эти 4 символа должны располагаться строго по центру клипа hero. Самый простой способ сделать это - сгруппировать их и отцентрировать с привязкой к stage. После этого двигайте (корректируйте) графику под них. У нашего героя голова вылазит за маркер и может накладываться на платформу - для мультяшных стилей это приемлемо. Чтобы маркеры участвовали в программных расчётах, но при этом не отображались на сцене, внутри каждого (или только внутри одного, если это один и тот же символ) пишем:
_visible = false;
Выглядеть будет примерно как на слайде 6.
- Пришло время заняться платформами. Создаём прямоугольный клип и внутри него в кадре пишем одну простую строчку:
_parent.addBox(this);
В этом вся прелесть. В этой строке вызывается функция, которая добавит этот блок в массив платформ и в дальнейшем при проверке мы будем в цикле проходить по этому массиву.Слайд 7.
- Теперь можно со скоростью звука создавать уровень из этих клипов, совершенно не заботясь каких они размеров, как перекрываются, как их зовут и где у них центр - всё это никак не повлияет на наш расчёт. Одно но - поворачивать нельзя - платформы должны сохранять горизонтальные и вертикальные линии. Строим уровень примерно как на слайде 8. Не забудьте стенки и опору под ногами.
- Пишем сам код платформера. Суть проста, проверяем каждую платформу на пересечение с маркерами персонажа. Если есть контакт, то смещаем персонажа в противоположную сторону до отсутствия пересечения.
//массив с платформами var boxes = []; //каждая платформа при старте вызывает эту функцию и передаёт себя как параметр addBox = function (obj) { boxes.push(obj); } //-------------------------------- //сила гравитации var grav = 1; //начальная скорость прыжка var jumpSpeed = -11.9; //шаг по Х var speedX = 5; //шаг по Y var speedY = 0; //максимальная скорость падения var maxSpeedY = 14; //половина ширины персонажа var hhx = (hero.p1._x - hero.p3._x + hero.p1._width / 2 + hero.p3._width / 2) / 2; //половина высоты персонажа var hhy = (hero.p2._y - hero.p4._y + hero.p2._height / 2 + hero.p4._height / 2) / 2; //отображает состояние прыжка var jump = false; //отображает состояние удара var shoot = false; Key.addListener(this); onKeyDown = function () { //прыгаем if (Key.isDown(Key.UP) && !jump && !shoot) { jump = true; speedY = jumpSpeed; } //бъём if (Key.isDown(Key.SPACE) && !jump && !shoot) { shoot = true; hero.gotoAndStop(1); hero.man.body.gotoAndPlay(2); } }; function stepHero() { if (!shoot) { //смещаемся влево/вправо if (Key.isDown(Key.LEFT)) { hero._xscale = -100; hero._x -= (jump) ? speedX * .8 : speedX; } else if (Key.isDown(Key.RIGHT)) { hero._xscale = 100; hero._x += (jump) ? speedX * .8 : speedX; } } //применяем по цепочке: гравитация -> скорость -> _y speedY += grav; speedY = (speedY > maxSpeedY) ? maxSpeedY : speedY; hero._y += speedY; //проверка на пересечение с платформами checkHitPlatform(); //если закомментировать строку ниже, то можно будет свалиться с платформы //и прыгнуть оттолкнувшись от воздуха. Этой строкой устраняем этоот глюк jump = (speedY < 5 && speedY > 0)? true : jump; if (!shoot) { if (jump) { //в позу полёта hero.gotoAndStop(3); } else { if (oldX != hero._x) { //если позиция по Х изменилась - в позу хотьбы hero.gotoAndStop(2); } else { //иначе - по стойке смирно hero.gotoAndStop(1); } } } oldX = hero._x; } checkHitPlatform = function(){ //перебираем все платформы и проверяем пересечение с персонажем с учётом того, //в какую сторону он смотрит var i = boxes.length; while (i--) { var curB = boxes[i]; if (curB.hitTest(hero.p1)) { //контакт справа if (hero._xscale > 0) { hero._x = curB._x - curB._width / 2 - hhx; } else { hero._x = curB._x + curB._width / 2 + hhx; } } else if (curB.hitTest(hero.p2)) { //контакт снизу jump = false; speedY = 0; hero._y = curB._y - curB._height / 2 - hhy; } else if (curB.hitTest(hero.p3)) { //контакт слева if (hero._xscale > 0) { hero._x = curB._x + curB._width / 2 + hhx; } else { hero._x = curB._x - curB._width / 2 - hhx; } } else if (curB.hitTest(hero.p4)) { //контакт сверху speedY = 0; // как вариант: speedY *= -1; hero._y = curB._y + curB._height / 2 + hhy; } } } onEnterFrame = function () { stepHero(); };
- Совмещаем наш код, платформы и персонажа вместе и получаем рабочий вариант как на слайде 10.
Устранение глюков
Если у кого-то движок начнёт глючить, убедитесь что соблюдается одно важное условие - с каждой платформой не должны одновременно пересекаться несколько маркеров. Чтобы этого избежать, нужно корректировать размеры и положение маркеров, а также скорость персонажа. В частности есть такие правила, слайд 11 (всё в пикселах):
- скорость по оси X не должна быть больше W1, иначе персонаж может “уйти” под платформу.
- скорость падения не должна превышать H1 (в коде она ограничивается переменной maxSpeedY)
- начальная скорость прыжка не должна превышать H2
- чтобы персонаж, стоя на краю платформы не висел в воздухе, подгоните нижний маркер (W2) под ширину ног когда персонаж стоит
- высота коридоров (с учётом ступенек, если они есть) не должна быть меньше чем высота персонажа. Если перс откажется переступать невысокую ступеньку в узком коридоре - вам сюда.
- чтобы ступенька была проходимой, её высота не должна превышать H1
Теперь можно добавить графику для уровня и сделать платформенную flash-игру, например как на слайде 12.
При желании можно добавить лифты (подвижные платформы). Вертикальные должны заработать автоматически, а к горизонтальным нужно “привязывать” персонажа на время езды. Также можно добавить плавное торможение персонажа, если завести переменную для скорости по X, но мне кажется что рисунок уровня и специфическая “дёрганность” движка, требуют резкого пиксельного смещения.
Интересно на 100%




Класс, как всегда все очень полезно! Я уже думал не будет больше постов)
Талантливый вы перец :о))
Отличный урок! От себя хочу добавить: чтобы избавится от дерганий персонажа при проверках столкновений нужно отказываться от полезной функции hitTest(), так как она проверяет столкновение только тогда, когда оно уже произошло, что очень не подходит для игр. По хорошему персонажа надо смещать используя новые временные координаты, которые проверять на возможные столкновения и другие условия, а после проверки и реакции на столкновение уже двигать (или как еще говорят - рендерить) персонажа в соответствии с временными координатами. Думаю, что автор поймет, что я имею в виду. Разбор альтернативного метода проверки столкновений без дерганий, легко тянет на отдельный урок
Спасибо.
Честно говоря я никогда не замечал тормозов связанных с этим “рендером”. Что, если сместить клип 10 раз в пространстве, он за 1 кадр 10 раз отрисуется (просто не владею такой информацией)? Да и статью тогда можно было не писать, так как тут вся соль в методе hitTest()
Stormit С делай плиз хотябы один урок по движку box2d на as3 (или видео урок (если надо камтасию и уроки по ней я скину))
Обязательно, когда руки дойдут
Bulat http://wonderfl.kayac.com/search?q=box2d туча примеров
Stormit прикольно моргает чел. только боюсь во рту у него пересохнет…
Круто! сейчас пытаюсь стартонуть в разработке игрушек. Этот урок мегаполезен! Заклинание новичка ёпрст! Спасибо!
У меня в движке несколько другой подход - вместо четырех прямоугольных маркеров восемь точечных - по два на каждую сторону. Весь уровень собирается в отдельном клипе level и столкновения проверяются level.hitTest(…) для каждой из восьми точек-маркеров (кстати для временных координат как предлагал Domik). Вот вопрос: какой метод лучше по производительности? или это не принципиально?
Кстати да. Проверок получается меньше, но зато по координатам (что быстрее?).
Правда есть и минус - не представляю как легко можно выровнять персонажа по краю стенки. Если платформы одним клипом, то сложно определить границы внутренних стенок.
В моём варианте для повышения производительности нужно проверять столкновение персонажа не со всеми платформами, а с ближайшими (завести сетку с данными какие платформы в какой ячейке - проверять по ячейкам соседним с позицией персонажа), но это отдельная тема.
>>только боюсь во рту у него пересохнет…
Терпения не хватило рот доделать. По-хорошему, он должен молчать закусив губу, иногда что-то невнятное произносить, а при ударе распахивать рот как сейчас. Но это не главное здесь
Хорошо рисуете. А вы где-то учились(в смысле на художника) или всё пришло по урокам и опыту ? Можете что-нибудь подсказать на эту тему
Несколько лет работал рядом с хорошими художниками, которые, кстати, нигде не учились.
Уроки отличные и нужные !!
Можно их побольше плиз)
Ура! Автор снова хитрит.
Мы уж заждались ))
а это в Action Script 2 или 3 ?
это на первом - нет типизации переменных
Уважаемый Stormit! Хочу создать игру с вашим движком, да вот проблема: как сделать так чтоб игрок стоял на месте а фон за ним передвигался (создавая ощущение движения персонажа). Если можно то объясните ( только просто) и если можете то ещё и скодом=))))))))
что то я застрял на 3 шаге, немогли бы вы поподробнее расписать ход действий?
TRY - ранее уже был описан тут http://xitri.com/2008/04/28/loop-background3-game-banner.html и http://xitri.com/2008/04/21/loop-background2.html и http://xitri.com/2008/04/17/loop-background1.html
>> это в Action Script 2 или 3 ?
На этом блоге все примеры пока на ActionScript1 (в последних версиях флеша просто выбирайте ActionScript 2 - там меньше нет). Если будет AS3, я это обязательно упомяну.
Удалил несколько повторяющихся комментариев на эту тему, чтобы не засорять ветку.
>>чтоб игрок стоял на месте а фон за ним передвигался
Есть простой способ, напишу небольшую статью об этом в ближайшем будущем.
>>я застрял на 3 шаге
Нужно чтобы в первом кадре клипа hero, в клипе man, был клип body с содержимым (анимация и код) как на слайде 3. То есть, когда персонаж стоит (не бежит и не прыгает/падает) должна быть цепочка hero.man.body
у меня Macromedia Flash 8, там во вкладке Publish Settings должно стоять Action Script 1.0 ведь так ? или я могу оставить Action Script 2.0 ?
и еще кое что у меня выдает
**Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 2: Statement must appear within on/onClipEvent handler
…
Это значит что код был на писан на клипе без обработчика события onClipEvent, хотя должен писаться вообще в кадре. На такие вопросы моментально отвечает гугл, так как это популярная ошибка начинающих флешеров.
… или я могу оставить Action Script 2.0 ?
AS2 включает в себя синтаксис AS1, в новых версиях флеша AS1 в опциях публикации уже нет, так как это не обязательно. Ставьте AS2.
не совсем понятно что значит проверка_попадания(); ? так и писать ?
Вызывайте в этом кадре ваш код для проверки попадания по противникам. В этом примере противников нет, поэтому и проверять не на чем. Лучше создать функцию проверки попадания там же где и остальной код, а из этого кадра (как на рисунке) просто её вызывать. Это будет примерно так:
_parent._parent._parent.checkHit();
Спасибо, а код как на слайде 4 писать в пустом кадре клипа Hero ?
Код нужно писать в кадре, в той же временной линейке, где находятся клип hero и все платформы. Вообще, в таких случаях нужно смотреть по самому коду и располагать его так, чтобы для него были доступны все клипы с которыми он работает.
Stormit а уроки по ас3 будут?
По самому AS3 - нет, я и сам не мастер, да и не интересно мне это. А конкретные реализации тех или иных идей на AS3, думаю будут со временем.
Stormit а о тебе инфа на сайте есть ?
тут есть
Денис, а Вы долго учились рисовать?
Ээээ Stormit! У меня чё-та не получается с платформами и с маркерами (мой hero постаянно проваливается сквозь платформы). Да и ещё - где нужно рисовать клип с платформай и её код (там где сам hero, или внутри него?)?
Пожалуйста помогите!
Юрій, это не по спортивному
Денис, вроде, ни когда не отказывался отвечать на вопросы, так что можете спросить, что не понятно.
Отличный сайт! Спасибо огромное за такие статьи!!! Очень помогают.
У меня вопрос… Допустим игра состоит из 2 флешек: level_1.swf и level_2.swf. Как сделать так, чтобы параметры из level_1.swf передавались в level_2.swf? Например патроны к оружию, кол-во жизней. Помогите пожалуйста.
Привет Stormit. У меня проблема, ибо я мало чего понимаю в этом деле) Вообщем я вроде все сделал как написано до 4-ого шага. Теперь вопрос! Куда код вписывать??? В символ hero? Сделал… Поставил на scene 1 и появилось окно, мол у мну 14 ошибок…. Код полностью списал (кроме комментариев к командам) =). Вощем, жду ответа)
Скажите, а как можно программно удалить платформы? То ли я чего-то недопонимаю, то ли removeMovieClip тут бесполезен?
очень круто!!!!! мегаполезная статья!!))))
вот это да… не думал , что все так просто…спасибо огромное !!
Блог расчитан на людей хоть с самой минимальной но базой, а вопросы типа “а куда ентод код то фтыкать парни?” совершенно не катят) Berch для передачи между swf используют LocalConnect, только надо ли вам оно…
млин =( Не получатеся D: Тут же 1 кадр должен быть??? Если да, то в него засовывать трехкадровый символ hero??? Заранее спасибо, извините за тупые вопросы =(
Просьба к тем кто задаёт вопросы, читать кроме статьи ещё и комментарии - там часто бывают ответы.
Как определить куда писать код, если явно не указано (относится к AS1):
1) если код внутри обработчика onClipEvent(имя_события) {…} , то пишем НА символе
2) если код внутри обработчика on(имя_события) {…} , то пишем НА кнопке
3) если код записан без этих обработчиков событий, его писать можно только В кадре. Писать нужно в том кадре, чтобы ссылки на все клипы и переменные, которые используются в коде были доступны.
>>в него засовывать трехкадровый символ hero???
На слайде 2 голубыми рамками условно показано в каком клипе что находится.
То есть символ hero сам 3-х кадровый, и в каждом кадре содержится клип с именем man внутри которых анимации разных состояний (одинаковые только имена клипов - man)
Stormit а как у клипов может быть одно и то же имя ?! у меня пишет что имя man уже занято
Это не имя в библиотеке символов. Это имя клипа на сцене (instanceName).
Главное, чтобы независимо от текущего состояния персонажа, можно было выполнить код hero.man.play() - полиморфизм в кадровом виде
Всё понятно, а только, с помощью чего вы это всё делаете?
http://www.ziddu.com/download/5481454/Platformer.rar.html
вот мой исходник, можете объяснить где я ошибку сделал ?
Или лучше выложите свои исходники по этому уроку.
Короче HonorRanger! Во-первых: У тебя ваще не назван клип hero (это самый главный), затем: чего ты в hero с названиями намудрил я не знаю. В главном клипе у тебя в верхнем слою должны быть “маркеры” тоисть p1, p2, p3, p4. Слоем ниже три состаяния героя: стоит, бежит и прыгает (и у них всех имя “man” но в библиотеке называй их по-разному). И самое главное - КОД ИГРЫ НУЖНО ПИСАТЬ НЕ В КАДРЕ С HERO А СЛОЕМ ВЫШЕ. В любом случае пользуйся примером этой статьи (по идее всё должно быть понятно).
Stormit вы могли бы ответить? Вот мой вопрос - как сделать так чтоб когда два клипа перекрещивались происхожила определённая анимация????? Пытался разобраться в вашем примере из Crimsonland с пауками (клип hit и bullet) но нечего не получилось. Если всётоки сможете ответить то пожалуйста напишите в месте с кодом=))
Эх, если бы Вы еще показали, как к этому делу скроллинг применить
Если я правильно тебя понял, то тебе нужна хитрая камера буквально из соседнего поста.
Ой. Спасибо ))
Ээээ, нет, я не это имел ввиду. )
Я про скроллинг, в смысле, когда персонаж подходит к краю экрана, фон начиает прокручиваться вверх-вниз и влево-вправо
Молодец! Я правда до этого додумался, но все равно спасибо, что сказали.
Я все время думал что я как-то неправильно делаю
Ну вот например второй вариант)) http://www.ziddu.com/download/5492693/Platformerv1.001.rar.html
где я тут снова нахимичил ?)
p.s. лучше выложите кто то исходник))
Эх HonorRanger. Почему ты не назвал самого героя? И маркеры у тебя без имени. Потом ты столько всего понаделал в клипах man что голова кругом. Зачем столько лишних слоёв? В клипе body не надо писать - проверка_попадания(); дословно, в этом месте нужно пишется код на проверку попадания в врагов (если они у тебя конечно есть) не удивляйся если не найдёшь его в этой статье, его здесь нет.
Вобщем попробуй поменьше лишних кадров делать.
“Эх HonorRanger. Почему ты не назвал самого героя? ”
Ок, спасибо, та вот в чем меня загвостка была!
Всегда рад помочь.
Если кто знает как припересечении клипов сделать так, чтоб происходила анимация - то пожалуйста ответте.
Функция checkHitPlatform() определяет с какой стороны от персонажа был контакт с платформой. Можно здесь анимацию запускать (функция play() для клипа с анимацией). Например, можно здесь создать дубликат клипа (анимация пыли от приземления) и поставить в нужном месте (в последнем кадре анимации удалить его).
Спасибо за совет. Но вообще я хотел узнать немного другое. Например - у меня летит шарик (клип с именем “ball”), когда он долетает до столба (”post”) то в нутри внутри него должна играть определённая анимация. Если я ещё не надоел то пожалуйста ответте.
if(ball.hitTest(post)) {ball.play()}
или hitTest по маркерам если они есть
Скажи когда прочтёшь, я почищу ветку от лишних комментариев
Stormit, если Вам не трудно, расскажите, пожалуйста, как сделать скроллинг карты как в Striped Escape. То есть не просто зацикленный фон, а когда игрок отходит на определенное расстояние от середины экрана, начинает двигаться не персонаж, а оружение: фон, враги, предметы и т.п.
PatrickRus
Самое простое это привязываешь _root._x и _y к _x и _y персонажа
В Striped Escape немного услажнено
SARFEX
Спасибо, попробую то-нибудь свое к этому коду добавить.
Следующий пост будет об этом
Отлично, спасибо
Огрооооомное спасибо за ответ!!!!!!!
Здравствуйте. Спасибо за информацию, оченно помогла. Мне сейчас нужно сделать игрушку-поздравлялку для клиентов. Основа—ваш движок, а вот причендалы мои, но вот есть у меня несколько моментов которые упорно не хотят сдаваться.
Игрушку выкладываю: http://www.7474.ru/game
Задумка следующая: мужик (пока что безрукий) бегает и ловит подарки (сейчас шарики), которые выбрасывают облачка. В принципе всё почти получилось, НО непонятно:
1) Почему шарики-подарки останавливаются не там где я им указываю.
2) Почему то не работают вместе onEnterFrame(), который сбрасывает шарики-подарки вниз и который запускает stepHero(), в рузультате пришлось stepHero() запускать с помощью setInterval().
3) Использую класс Tween, потому что не смог написать приличного кода функции для алгоритма: приезжает — сбрасывает — уезжает; Скажите насколько обоснованно применение данного класса, можно ли написать своё? Если да то подскажите пожалуйста как именно. (остальное удалено чтобы не засорять ветку)
Простите, не написал что в работе облаков, сбрасывающих круги наблюдаются серьёзные сбои, тоже не пойму почему.
Во-первых вы бессовестно спёрли графику с кирпичами из моего примера, во-вторых здесь обсуждается статья, а не ваша игра.
Я могу ответить на вопросы по своему коду или подсказать принцип как что-то добавить, но искать ошибки в чужом коде мне, как минимум, не интересно.
Спасибо за урок, и всем тем кто помогал мне с возникающими вопросами))
Оказалось не очень сложно)
Вот что у меня получилось)http://www.ziddu.com/download/5591011/Platformer2.rar.html
HonorRanger скинул бы fla….) А то у мну проблемы как у тебя =( (до сих пор)
“Эх HonorRanger. Почему ты не назвал самого героя? ” просто не понимаю этой фразы)
В этой фразе нет нечего сложного. Ты просто должен в панеле properties (обычно это нижний левый угол) под надписью movie clip написать hero. Вот и всё!
Ок! Спасибо TRY!)
А Stormit-у тоже ОГРООООМНОЕ спасибо)
Что-то я опять напартачил) Млин ребят, реально простите, просто оч хачу доделать) вот фла http://depositfiles.com/files/fqjvvq9g3
Да всё просто, нужно только привить себе привычку выставлять центр символа в нужном месте. У вас в платформах и маркерах центр сбит, поэтому и глюки (графику в этих клипах нужно отцентрировать).
Анализируйте код, например строка:
var hhy = (hero.p2._y - hero.p4._y + hero.p2._height / 2 + hero.p4._height / 2) / 2;
требует чтобы половина высоты персонажа корректно определялась.
Вроде все отцентрировал, проверил.. Все нормана, тока опять не прыгает)
Все ок) Терь даже прыгает) Спасибо)
Ой забыл, он у меня еще не атакует(Когда жму пробел все клавиши замыкаются и герой даже не двигается)
Нуууу здесь тоже всё очень просто. Первое - ты не назвал в клипе hero клипы man, второе - в внутри первого man-а не назван клип с ударом body. Когда всё это зделаешь - должно работать.
Уважаемые! Из за чего может быть такой глюк, что при попадании на платформу персонаж начинает постоянно немного подпрыгивать, при чем на величину меньшую высоты прыжка и несколько быстрей.
У тебя неправильно смещён центр платформы. Попробуй его поставить чуть выше или ниже.
Отлично! TRY, благодарю, помогло. Но появился другой косяк, при столкновении с вертикальными платформами (столкновения слева и справа) персонаж резко уходит вверх, на саму платформу. Я конечно это попробую сам поправить, но если у кого есть какие идеи, буду рад.
У вас одновременно пересекаются 2 маркера с платформой - боковой и нижний. Нужно нижний маркер сделать меньше по ширине.
Stormit - - - ты где-то учился графике и аннимации или это всё приобрёл сам?
(Рисуешь просто здорово и как ты разбираешься в тенях? У меня с ними проблема я просто не понимаю как их нужно расставлять и из-за этого половина моих работ - без теней, да и вообще я раньше не думал что всеръёз увлекусь аннимацией так создал какую-нить работу и удалил сразу-же что-б место не занимало Раньше мне казалось что это всё ерунда и что написать игру или программу может любой дурак но потом попробывал сам и понял что жестоко ошибался в своих убеждениях)..
(Можешь спросить плс своего друга какие проги для создания звуков он использует?)
Супер нужная штука: быстро, просто и практично !!!
Добрый день. Рисую я хорошо, а вот в программерстве я полний чайник. Даже скопипастив ентот движок у меня ничего не получилось. кто-нибудь может подсказать, где возможна самая простая ошибка?
Автору огромный респект! Спасибо, Stormit! Уважаю программеров, которые с пониманием относятся к новичкам)
странно , я сделал все , как описано здесь , и ничего не происходит , обьясните пожалуйста , в чем дело ? http://narod.ru/disk/12475314000/MUTANT%20ATTACK.fla.html
а что делает строка Key.addListener?
to kramfus
вы переопределяете onEnterFrame, так, что мой остаётся не у дел
to GALLlblSH
этой строкой мы добавляем слушателя к объекту Key. Когда возникнет событие onKeyDown, он вызовет метод onKeyDown() у всех, кто на него подписался.
А разве нельзя без него обойтись? Если заунуть код в обработчик nenterFrame? Например:
onEnterFrame = function(){
if (Key.isDown(Key.UP) && !jump && !shoot) {…}
//и так же для пробела
stepHero()
}
Можно, но тогда код будет выполняться каждый кадр (бессмысленно нагружая, хоть и слегка, процессор), а подписавшись, функция вызовется только при нажатии клавиши, тем более что прыжок срабатывает только один раз - дальнейшее удержание кнопки ни к чему не приводит
Дорогой дружище Stormit спасибо тебе за твой ресурс! Прости что я как то раз стибрил у тебя кирпичи! Я нарисовал новые, вот погляди http://www.7474.ru/game/boy.html
Отлично получилось. И по стилю эти сюда больше подходят
Такое дело, до 6 пункта всё ок, а после получается так что персонаж либо начинает как бешеный скакать по полю, или вообще проваливается, всё из темы про “УСТРАНЕНИЕ ГЛЮКОВ” применил, но продолжается такая бурда =(
Думаю что проблема вызвана “hitTest” хотя хз……
плиз, выложте кто- нибудь рабочий исходник, а то уже несколько дней мучаюсь и никак не получаеться.Умоляю! ААААААА!!!!!!
Пожалуйсто ктонибудь может мне сказать что я тут сделал не так?
http://depositfiles.com/files/clvdbyfrd
_parent._parent._parent.checkHit(); - это ужас… очень плохие хитрости.
начал выполнять,анимация сделал,дошел до встваления кода,непонял куда его вставлять и какой это язык Ас2 или Ас3 подскажите плз что делать)
Вставлять надо в Layer, а язык тут AC2
Выложите кто нибудь исходник, а то что то неполучается…
Я поддерживаю, не плохо было бы выложить исходник, так будет понятнее, если не жалко))
Я хочу создать игру для двоих игроков, делаю второго игрока по тому же принципу, после этого ни один персоонаж не двигаеться. Почему?
Ура у меня все получилось!!!!!! я сделал это!!!!! просто перед данным уроком нужно немного почитать про ActionScript
поначалу во многие моменты не въезжал.
2 недели ковыряний и вот что получилось http://www.gamedev.ru/projects/forum/?id=84082&page=2#m22
Собственно, статью давно прочитал, но как-то забил, а вот надысь ночью делать было нечего и вот решил таки сделать себе игрушку - http://file.qip.ru/file/108688133/5a0c01d1/pa_online.html
из управления: ходить и прыгать так же на стрелках, стрелять - пробел, 1 - пистолет, 2 - автомат.
TricK Dexter, тут всё отлично написано. Нечего тут учить. Читай внимательнее.
Спасибо за отличный урок. Сам только начал флэш учить. Очень помог. Хотелось бы больше узнать про противников и про объекты с которыми возможно взаимодействие ( типа ящики, которые можно двигать и т.д.)
хороший урок, правда) автору спасибо огромное - все четко, ясно, ничего лишнего.
единственный вопрос. у меня ._xscale идет не от центра, а от левого края. как это исправить?
Отличный урок, отличный сайт, именно то что мне было нужно, спасибо
Уроки классные, только на старом as… почему на as3 не пишете?
Уважаемый Stormit, и другие, скажите пожалуйста, надо ли что - то писать к маркерам(p1, p2…)?
Тут есть исходник к этому движку
Большое спасибо, очень пригодилось! Творческих вам успехов и с праздниками )
А как во Flash 8 заставить работать такой код?
hero.gotoAndPlay(2);
Нифига он не работает ни в какой форме сколько раз пробовал.
P.S.
Я имею в виду код перехода в клип на главном кадре (название_клипа.кадр_или_чтото_другое)
кто-то может к этому создать видео урок ?????
зачем. и так всё ясно. даже разбираться то и не надо…
а куда флешпрограммы сдавать ну или флеш игры
кстати сайт крутой
А как сделать чтобы герой на ходу бил? Очень надо.
Огромное спасибо за Ваш ресурс. Давно порывался сделать игру, да пугало кодирование, а у Вас все доходчиво и понятно так, по полочкам разложено и описано…И заработало все сразу. То же хочу уличить себя в плогиате - Вашего героя - несмотря на то, что и своих героев я достаточно нарисовал, но Ваш очень уж он вписывался в мою концепцию. Но если Вы будете против я его непременно удалю. Игра здесь - http://mobkon.land.ru, хотя полностью сценарий игры еще не доделан.
Еще раз огромное спасибо!
Berch может и тибе и ясно а я новачок в етом деле много незнаю. Но очень хочу научиться
очень полезная статья, но я в этом деле новичок, то есть только рисовать умею, а в экшн скрипт вообще ни в зуб ногой((( ув. Stormit, скажите, можно ли комфортно сделать описанное в этом уроке, используя программу Macromedia Flash 5? заранее спасибо.
странно.у меня герой ходит сквозь стены, но даже не ходит а платформа выполняет функцию телепорта. кто нибудь знает в чем дело???
а что значат эти строчки:
var i = boxes.length;
while (i–) {
var curB = boxes[i];
Георгий, у меня тоже был этот глюк, только когда героя лифт “придавливал”, но к сожалению, приоду не знаю. Может, с маркерами проблема?
Sk65, строки означают:
Объявляется переменная “i” и ей присваивается значение количества элементов массива “boxes”.
Оператор цикла(выполняется столько раз, сколько элемнтов сожержит масив “boxes”(управляется переменной “i”))
Объявляется переменная “curB” и ей присваивается значение элемента массива под “номером” значения переменной “i”.
Я только только осваиваю флеш. И вот уже часа два ломаю себе мозг.. в итоге запутался окончательно. Я не могу создать три символа ман разного содержания, если я изменяю один - меняются остальные. Прошу, если не трудно объясните как сделать шаг 2
eiolve, проблема в том что ты не создаешь 3 разных мувика, а дублируешь один и тот же (создаешь экземпляры одного муви клипа). В этом случае все экземпляры наследуют все свойства родительского библиотечного клипешника. Чтобы они были по-настоящему разными, найди имя первого клипа в библиотеке, кликни по нему правой кнопкой и выбери Duplicate или чо то там в этом духе. Флэша предложит тебе ввести имя нового клипа, после ввода он создастся и вот ЭТО будет уже новый независимый сам себе родительский клип, вытаскивай его на сцену и можешь править его независимо от всего остального.
Извиняюсь за стиль письма, настроение чо-то хорошее)))
eiolve, ещё момент. В продублированном в библиотеке новом клипе могут также быть экземпляры других клипов. Например, рука. Вот у тебя есть человечек — chel_mc, скажем, он содержит клип, hand_mc, ты дублируешь человечка для того чтобы создать в нем другое содержимое, скажем второй будет изображать движение, так вот клип hand_mc в нём ТОТ ЖЕ САМЫЙ! и естесссно если ты его как то изменишь то и в первом клипешнике рука тоже изменится. Чтоб такой фигни не было читай предыдущий комментарий) Удачи)))
eiolve, щас тока понял, можно прямо на сцене по правому клику дублироваьт символ, он правда сдублируется всё равно в библиотеку откуда его надо будет вытащить. ЭТО не одно и тоже что перенести его удерживая левую кнопь мыши и кнопочку Alt)))
Спасибо)) Буду пробовать)))
Все супер, работает, но небольшой глюк - когда перс соприкосается с боковой стеной - он исчезает
eiolve, скорее всего во время проверки столкновения героя с платформой у тебя координата x куда то неожиданно для всех изменяется так, что героя даже не видно. Косяк в этом блоке:
checkHitPlatform = function(){
//перебираем все платформы и проверяем пересечение с персонажем с учётом того,
//в какую сторону он смотрит
var i = boxes.length;
while (i–) {
var curB = boxes[i];
if (curB.hitTest(hero.p1)) {
//контакт справа
if (hero._xscale > 0) {
hero._x = curB._x - curB._width / 2 - hhx;
} else {
hero._x = curB._x + curB._width / 2 + hhx;
}
} else if (curB.hitTest(hero.p2)) {
//контакт снизу
jump = false;
speedY = 0;
hero._y = curB._y - curB._height / 2 - hhy;
} else if (curB.hitTest(hero.p3)) {
//контакт слева
if (hero._xscale > 0) {
hero._x = curB._x + curB._width / 2 + hhx;
} else {
hero._x = curB._x - curB._width / 2 - hhx;
}
} else if (curB.hitTest(hero.p4)) {
//контакт сверху
speedY = 0; // как вариант: speedY *= -1;
hero._y = curB._y + curB._height / 2 + hhy;
}
}
}
То есть, ты героя-то своего нарисовал, скорее всего, а значит по-своему расставил маркеры, и вот что-то где то не совпадает. Изучи вопрос ещё раз, в расставлении маркеров есть нюансы они здесь понятно расписаны и даже проиллюстрированы. Ещё обращай внимание на то где у тебя точка будет когда клип создаёшь (там такие 9 контурных квадратиков появляются и один закрашен черным). От неправильного положения этой самой точки может не работать.
Да, спасибо. Я проверил все, и персонажа делал своего. В символах точки ставил стандартные (центральный левый квадратик) попробую на самый центральный
Мне кажется что все дело именно в том что я создал своего персонажа и поэтому маркеры расположены несколько иначе.
Я немного не понимаю суть строки
hero._x = curB._x + curB._width / 2 + hhx;
единственное что я понимаю - hero - герой
curB- блок
hhx - расстояние равное половине ширины.
eiolve, эта строка фактически означает:
положение героя = координата блока + половина ширины блока + значение переменной которая там в коде тоже вычисляется.
Совет такой: не следуй тупо коду который тут дан, тебе нужно понять суть происходящего, а это простейшие вычисления расстояний.
То есть тебе нужно чтобы герой, например, не уходил за левую границу. у героя есть левый маркет у маркера, точка регистрации в центре и он имеет ширину скажем 10 пикселей. У левого блока точка регистрации тоже в центре и он имеет ширину, для простоты, тоже 10. Значит максимально допустимая координата героя с левой стороны будет равна:
координата левого блока + половина ширины блока + половина ширины левого маркера внутри героя. Всё.
Почему прибавляем половину ширины?
Потому что точка регистрации в центре, была бы точка в левом углу, прибавляли бы всю ширину блока, была бы справа ничего бы не прибавляли.
А почему точка именно в центре?
Да потому что предполагаем что блоки будем располагать и справа и слева и сверху и снизу, поэтому для упрощения жизни делаем её в центре. Иначе прищлось бы постоянно оглядываться на то какую именно стороны сейчас обрабатываем и в зависимости от этого либо прибавлять ширину блока либо не прибавлять.
Что касается “+ значение переменной которая там в коде тоже вычисляется”, что написано ранее, то это переменная hhx если посмотришь внимательно на то из чего она состоит то всё поймешь я думаю.
блин, написала все это в AS3
но когда он налетает на блоки, то дрыгается (застревает) в них и все. либо отлетает на солидное расстояние
я уже не знаю, чего делать. сижу-думаю-верчу-проверяю… вроде все учла из вышесказанного - маркеры друг друга не перекрывают и т.п.(
И спасибо большое за статью. это реальная помощь для меня)
>>Анна
А тут в последней статье прилагался исходник этого движка, вы бы попробовали его взять, да и портировать на as3, вероятность ошибок в коде тогда стремится к нулю и если по прежнему гадость какая-то будет, то можно уже будет на скрипт грешить.
что-то конвертор по-тупому переводит, чисто грамматику исправляет, а приемы нет
например, в AS2:
onEnterFrame = function () {
stepHero();
}
function stepHero() {
}
Конвертер мне ничего не исправляет, типа все ок. Когда в AS3 надо делать:
hero.addEventListener (Event.ENTER_FRAME, stepHero);
function stepHero (event:Event):void {
}
===========
груусненько)
ооо, нашла свою ошибку в коде
спасибо всем большое)
*ведь знала же, что сама где-то ооооо*
AS 3.0 круче гораздо
А что это за програмка, через которую это делается? Понять никак не могу! Название?
Flash MX
у меня через Flash MX не получается как в инструкции, и как вообще зделать слайды для движений.
Я просто новичок в этом деле.
>>Лёша
Что вам сказать, читайте книги по флешу и научитесь.
У меня всё работает кроме удара! можете поподробнее описать как его сделать?
а откуда взять Flash MX
bas, купить
а с какого нибудь сайта скачать нельзя
Можно, только не думаю что тут ссылки на другие сайты разрешено давать. Поиском пользоваться нужно, трекеры смотреть. Всё есть везде.
А вообще пиратство - зло
Если уже чето качать, то Adobe Flash CS какой-нибудь….
понял. спасибо
Да. Вышел же Adobe Flash CS5… А вообще конечно можно и скачать для одиночного пользования то…
а рисуется все в обычном редакторе или специальной прогой
Ну, адобовские пакеты сейчас же взаимно совместимы - так что ,обладая знаниями в фотошопе, флеше и иллюстраторе, можно вообще бомбезные вещи делать.. Я молчу о зании АС… ^__^
Подскажите как реализовать 7й шаг на AS3.. во фрейме пола кладу: parent.addBox(this);
в AS файле public function addBox(obj) { boxes.push(obj); } Ругается на то и на другое ( ошибка 1061) CS4.
Извиняюсь за глупый вопрос, но не работает анимация удара. По нажатии пробела герой даже не дергается с места, а просто застывает. После этого ни ходьба ни прыжки больше не работают…
Люди помогите мне с програмой для создания ф игор.на сайт. я не знаю ни одной такой проги чтоб ей васпользоваться. рисовать умею програмировать не очень, тоесть для вас вапще не умею. мне бы хотелось узнать есть ли такая прога чтоб интерфейс русский был и в ней все скрипты и прочее уже было тоже. и чтоб бесплатная ато я не хочу покупать лиш потому что не уверен что смогу ей пользоваться.
Боюсь, нет :)… Но есть много книг, где все описано. В том числе на русском. + есть много сайтов - например, этот где на примерах все растолковано и имеется много полезных виджетов, а без знания базы хотя бы редактора и АС, боюсь, ничего не получится..
Вот есть один ресурс с конструктором для игр - но о флеше придется тогда забыть. Там все на ангельском, но программа несомненно полезная:
http://www.yoyogames.com/gamemaker/
Там все описано и все бесплатно - так что мечты сбываются:)
Jazzcat спасибо за помощь. но я уже пробовал гейм макер. мне чтото другое надо.
Jazzcat А можно спросить с какими программами работаеш ты.
ну, ничего уже проще, думаю, не существует - я не хочу сказать, что это простой редактор (GM), но более-менее качественный продукт в программной средой без знаний программинга создать не получится - это в любом случае. Лично я во флеше работаю - по работе веб-дизайн, а хобби - флеш-игры. Вот в данном блоге Денис вполне доходчиво изложил кучу уроков - просто начни сначала их выполнять сначала - и все станет намного понятнее.. А еще лучше - изучить перед этим базу по какой-нибудь книге “Основы Flash”..
Уважаемый Stormit ! Хочу сделать игру на два игрока, да клавиш не хватает. Попробовал в вашем примере использовать getCode () , но тогда откликаются все клавиши подряд. Обьясните непонятливому, пожалуйста. Работаю на шестом флэше, AS3.
И ещё вопрос: я поделил уровень на кадры, но почему-то при переходе на другой кадр у меня снова восстанавливается индикатор жизней. Может в коде надо вводить типа oldenergy=currentenergy. Помогите кто-нибудь! Код работы индикатора такой:
var ind = 1;
var imax=21;
indi = function () {
indicator.gotoAndStop(ind);
};
Ребята помогите кто нибудь помогите пожалуйста. Все сделала, ходит прыгае, ручками машет. Но не могу разобраться с платформами и маркерами, он у меня все равно заходит за платформы. Кажется проблема в том что не правильно отцентрировала, как только не центрирую все равно не получается. Очень очень надо, а то из за этого законсить не могу! http://files.mail.ru/2FA48K