Простой платформенный движок для флеш-игр

16.06.2009, автор Stormit, рубрики: ActionScript, Flash игры

Чтобы сделать игру как на примере (слайд 12), не нужны продвинутые знания в физике и математике. По сути, мало что нужно вообще, потому как флеш располагает всем необходимым, чтобы сделать неплохую платформенную игру без особых усилий.

Обычно для определения столкновений фигур используются непростые математические расчёты проекции векторов. И это часто оправдано, так как позволяет сделать игры с реальным поведением объектов. Но если реальной физикой в вашей игре можно пренебречь, то организовать прогулки по платформенному миру - не проблема. Герой дня - популярная функция hitTest(), которая и будет решать все вопросы определения столкновений.

У этого движка есть свои плюсы и минусы. К недостаткам можно отнести:
1) отсутствие физики (есть только гравитация)
2) отсутствие наклонных поверхностей
3) платформы только прямоугольной формы
4) в сложных уровнях, во избежание глюков, требует дополнительной настройки персонажа
5) есть небольшая “дерганность” персонажа при контакте с платформами (связано с тем, что пересечение с платформой компенсируется не по направлению движения, а с раскладкой на оси X и Y).

К достоинствам:
1) прост в разработке
2) простое и быстрое построение уровней сложной формы
3) персонаж автоматически шагает по невысоким ступенькам
4) несёт в себе определённую стилизацию и хорошо подходит для пиксельной графики.

Пошаговая инструкция:

  1. Для начала создадим персонажа. Я делаю это так: рисование в виде контурных линий (с раскладкой частей тела по слоям), разукрашивание и конвертация в символы всех значимых элементов. Слайд 1.
    (Полезная деталь - кисти рук обрамляются неразрывной контурной линией, а сама рука без линий на запястье и в плече. Это позволяет крутить символы под разными углами с правильным наложением. Так же с ногами.)
  2. Создаём структуру символов как на слайде 2. В главном клипе героя hero есть 3 кадра в которых расположены символы с одинаковым именем man, содержащие разные состояния героя: 1) стоит на месте; 2) идёт; 3) в прыжке. Если в вашей игре персонаж может погибнуть, это состояние можно поместить в 4-й кадр.
  3. Добавим нашему персонажу возможность атаковать. В этом примере нельзя бить на ходу или в прыжке, поэтому анимацию удара сделаем только в положении “стоит на месте” - hero.man (1 кадр). Внутри символа man оборачиваем руки, туловище и голову в клип body и внутри него делаем анимацию удара. Слайд 3.На слайде обозначены 4 кадра с кодом, которые требуют пояснения. Превый кадр - stop() - остановить персонажа в состоянии готовности (покоя). Второй кадр - play() - не знаю природу этого глюка, но иначе при ударе на ходу персонаж “зависает”. 3-й скриптовый кадр - примерно тут должна быть проверка на попадание по противникам (там где происходит удар). Последний кадр сбрасывает флаг отвечающий за состояние удара (дальше в коде он будет включаться при нажатии клавиши ПРОБЕЛ).
    Если вы захотите сделать, чтобы персонаж мог атаковать на ходу и в прыжке, позаботьтесь чтобы в этих состояниях были клипы body с соответствующим кодом и анимацией.
  4. Персонаж готов и пора его проверить. Этот временный код позволяет попробовать персонажа в действии и на раннем этапе поправить анимацию, если это необходимо.
    //считаем что изначально персонаж стоит на поверхности
    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. Получаем примерно то что на слайде 5. В коде текущее положение персонажа считается поверхностью земли, так что для наглядности можно нарисовать опору у него под ногами.
  6. Главная хитрость. Добавляем в клип hero 4 символа и располагаем их по сторонам света (начиная с “восточного” и дальше по часовой стрелке называем их p1, p2, p3, p4). Назовём их условно “маркеры”. По этим зонам мы будем проверять пересечение с платформами методом hitTest(). Также эти маркеры определяют расчётные габариты персонажа (ширину и высоту). Поэтому размещать их нужно не “от балды”, а так чтобы они совпадали со ступнями, головой и, как минимум,  туловищем. Чтобы не было сползания графики, суммарно эти 4 символа должны располагаться строго по центру клипа hero. Самый простой способ сделать это - сгруппировать их и отцентрировать с привязкой к stage. После этого двигайте (корректируйте)  графику под них. У нашего героя голова вылазит за маркер и может накладываться на платформу - для мультяшных стилей это приемлемо. Чтобы маркеры участвовали в программных расчётах, но при этом не отображались на сцене, внутри каждого (или только внутри одного, если это один и тот же символ) пишем:
    _visible = false;

    Выглядеть будет примерно как на слайде 6.

  7. Пришло время заняться платформами. Создаём прямоугольный клип и внутри него в кадре пишем одну простую строчку:
    _parent.addBox(this);

    В этом вся прелесть. В этой строке вызывается функция, которая добавит этот блок в массив платформ и в дальнейшем при проверке мы будем в цикле проходить по этому массиву.Слайд 7.

  8. Теперь можно со скоростью звука создавать уровень из этих клипов, совершенно не заботясь каких они размеров, как перекрываются, как их зовут и где у них центр - всё это никак не повлияет на наш расчёт. Одно но - поворачивать нельзя - платформы должны сохранять горизонтальные и вертикальные линии. Строим уровень примерно как на слайде 8. Не забудьте стенки и опору под ногами.
  9. Пишем сам код платформера. Суть проста, проверяем каждую платформу на пересечение с маркерами персонажа. Если есть контакт, то смещаем персонажа в противоположную сторону до отсутствия пересечения.
    //массив с платформами
    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. Совмещаем наш код, платформы и персонажа вместе и получаем рабочий вариант как на слайде 10.

Устранение глюков

Если у кого-то движок начнёт глючить, убедитесь что соблюдается одно важное условие - с каждой платформой не должны одновременно  пересекаться несколько маркеров. Чтобы этого избежать, нужно корректировать размеры и положение маркеров, а также скорость персонажа. В частности есть такие правила, слайд 11 (всё в пикселах):

  • скорость по оси X не должна быть больше W1, иначе персонаж может “уйти” под платформу.
  • скорость падения не должна превышать H1 (в коде она ограничивается переменной maxSpeedY)
  • начальная скорость прыжка не должна превышать H2
  • чтобы персонаж, стоя на краю платформы не висел в воздухе, подгоните нижний маркер (W2) под ширину ног когда персонаж стоит
  • высота коридоров (с учётом ступенек, если они есть) не должна быть меньше чем высота персонажа. Если перс откажется переступать невысокую ступеньку в узком коридоре - вам сюда.
  • чтобы ступенька была проходимой, её высота не должна превышать H1

Теперь можно добавить графику для уровня и сделать платформенную flash-игру, например как на слайде 12.

При желании можно добавить лифты (подвижные платформы). Вертикальные должны заработать автоматически, а к горизонтальным нужно “привязывать” персонажа на время езды. Также можно добавить плавное торможение персонажа, если завести переменную для скорости по X, но мне кажется что рисунок уровня и специфическая “дёрганность” движка, требуют резкого пиксельного смещения.

Интересно на 75%

(111) Хитрых на тему «Простой платформенный движок для флеш-игр»

  1. moja

    Класс, как всегда все очень полезно! Я уже думал не будет больше постов)

  2. GB

    Талантливый вы перец :о))

  3. Domik

    Отличный урок! От себя хочу добавить: чтобы избавится от дерганий персонажа при проверках столкновений нужно отказываться от полезной функции hitTest(), так как она проверяет столкновение только тогда, когда оно уже произошло, что очень не подходит для игр. По хорошему персонажа надо смещать используя новые временные координаты, которые проверять на возможные столкновения и другие условия, а после проверки и реакции на столкновение уже двигать (или как еще говорят - рендерить) персонажа в соответствии с временными координатами. Думаю, что автор поймет, что я имею в виду. Разбор альтернативного метода проверки столкновений без дерганий, легко тянет на отдельный урок ;)

  4. Stormit

    Спасибо.
    Честно говоря я никогда не замечал тормозов связанных с этим “рендером”. Что, если сместить клип 10 раз в пространстве, он за 1 кадр 10 раз отрисуется (просто не владею такой информацией)? Да и статью тогда можно было не писать, так как тут вся соль в методе hitTest()

  5. Bulat

    Stormit С делай плиз хотябы один урок по движку box2d на as3 (или видео урок (если надо камтасию и уроки по ней я скину))

  6. Stormit

    Обязательно, когда руки дойдут :)

  7. makc

    Bulat http://wonderfl.kayac.com/search?q=box2d туча примеров

  8. makc

    Stormit прикольно моргает чел. только боюсь во рту у него пересохнет…

  9. lynxear

    Круто! сейчас пытаюсь стартонуть в разработке игрушек. Этот урок мегаполезен! Заклинание новичка ёпрст! Спасибо!

  10. mibix

    У меня в движке несколько другой подход - вместо четырех прямоугольных маркеров восемь точечных - по два на каждую сторону. Весь уровень собирается в отдельном клипе level и столкновения проверяются level.hitTest(…) для каждой из восьми точек-маркеров (кстати для временных координат как предлагал Domik). Вот вопрос: какой метод лучше по производительности? или это не принципиально?

  11. Stormit

    Кстати да. Проверок получается меньше, но зато по координатам (что быстрее?).
    Правда есть и минус - не представляю как легко можно выровнять персонажа по краю стенки. Если платформы одним клипом, то сложно определить границы внутренних стенок.
    В моём варианте для повышения производительности нужно проверять столкновение персонажа не со всеми платформами, а с ближайшими (завести сетку с данными какие платформы в какой ячейке - проверять по ячейкам соседним с позицией персонажа), но это отдельная тема.

  12. Stormit

    >>только боюсь во рту у него пересохнет…
    Терпения не хватило рот доделать. По-хорошему, он должен молчать закусив губу, иногда что-то невнятное произносить, а при ударе распахивать рот как сейчас. Но это не главное здесь :)

  13. Guest

    Хорошо рисуете. А вы где-то учились(в смысле на художника) или всё пришло по урокам и опыту ? Можете что-нибудь подсказать на эту тему :)

  14. Stormit

    Несколько лет работал рядом с хорошими художниками, которые, кстати, нигде не учились. :)

  15. Bulat

    Уроки отличные и нужные !!
    Можно их побольше плиз)

  16. ShadeMemory

    Ура! Автор снова хитрит.
    Мы уж заждались ))

  17. Shram

    а это в Action Script 2 или 3 ?

  18. KorDum

    это на первом - нет типизации переменных

  19. TRY

    Уважаемый Stormit! Хочу создать игру с вашим движком, да вот проблема: как сделать так чтоб игрок стоял на месте а фон за ним передвигался (создавая ощущение движения персонажа). Если можно то объясните ( только просто) и если можете то ещё и скодом=))))))))

  20. HonorRanger

    что то я застрял на 3 шаге, немогли бы вы поподробнее расписать ход действий?

  21. animefish
  22. Stormit

    >> это в Action Script 2 или 3 ?
    На этом блоге все примеры пока на ActionScript1 (в последних версиях флеша просто выбирайте ActionScript 2 - там меньше нет). Если будет AS3, я это обязательно упомяну.
    Удалил несколько повторяющихся комментариев на эту тему, чтобы не засорять ветку.

  23. Stormit

    >>чтоб игрок стоял на месте а фон за ним передвигался
    Есть простой способ, напишу небольшую статью об этом в ближайшем будущем.

  24. Stormit

    >>я застрял на 3 шаге
    Нужно чтобы в первом кадре клипа hero, в клипе man, был клип body с содержимым (анимация и код) как на слайде 3. То есть, когда персонаж стоит (не бежит и не прыгает/падает) должна быть цепочка hero.man.body

  25. HonorRanger

    у меня Macromedia Flash 8, там во вкладке Publish Settings должно стоять Action Script 1.0 ведь так ? или я могу оставить Action Script 2.0 ?

  26. HonorRanger

    и еще кое что у меня выдает
    **Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 2: Statement must appear within on/onClipEvent handler

  27. Stormit

    Это значит что код был на писан на клипе без обработчика события onClipEvent, хотя должен писаться вообще в кадре. На такие вопросы моментально отвечает гугл, так как это популярная ошибка начинающих флешеров.
    … или я могу оставить Action Script 2.0 ?
    AS2 включает в себя синтаксис AS1, в новых версиях флеша AS1 в опциях публикации уже нет, так как это не обязательно. Ставьте AS2.

  28. HonorRanger

    не совсем понятно что значит проверка_попадания(); ? так и писать ?

  29. Stormit

    Вызывайте в этом кадре ваш код для проверки попадания по противникам. В этом примере противников нет, поэтому и проверять не на чем. Лучше создать функцию проверки попадания там же где и остальной код, а из этого кадра (как на рисунке) просто её вызывать. Это будет примерно так:
    _parent._parent._parent.checkHit();

  30. HonorRanger

    Спасибо, а код как на слайде 4 писать в пустом кадре клипа Hero ?

  31. Stormit

    Код нужно писать в кадре, в той же временной линейке, где находятся клип hero и все платформы. Вообще, в таких случаях нужно смотреть по самому коду и располагать его так, чтобы для него были доступны все клипы с которыми он работает.

  32. Bulat

    Stormit а уроки по ас3 будут?

  33. Stormit

    По самому AS3 - нет, я и сам не мастер, да и не интересно мне это. А конкретные реализации тех или иных идей на AS3, думаю будут со временем.

  34. Bulat

    Stormit а о тебе инфа на сайте есть ?

  35. Stormit
  36. Сергей

    Денис, а Вы долго учились рисовать?

  37. TRY

    Ээээ Stormit! У меня чё-та не получается с платформами и с маркерами (мой hero постаянно проваливается сквозь платформы). Да и ещё - где нужно рисовать клип с платформай и её код (там где сам hero, или внутри него?)?
    Пожалуйста помогите!

  38. LegendMAN

    Юрій, это не по спортивному :)
    Денис, вроде, ни когда не отказывался отвечать на вопросы, так что можете спросить, что не понятно.

  39. berch

    Отличный сайт! Спасибо огромное за такие статьи!!! Очень помогают.
    У меня вопрос… Допустим игра состоит из 2 флешек: level_1.swf и level_2.swf. Как сделать так, чтобы параметры из level_1.swf передавались в level_2.swf? Например патроны к оружию, кол-во жизней. Помогите пожалуйста.

  40. Антон

    Привет Stormit. У меня проблема, ибо я мало чего понимаю в этом деле) Вообщем я вроде все сделал как написано до 4-ого шага. Теперь вопрос! Куда код вписывать??? В символ hero? Сделал… Поставил на scene 1 и появилось окно, мол у мну 14 ошибок…. Код полностью списал (кроме комментариев к командам) =). Вощем, жду ответа)

  41. shofde

    Скажите, а как можно программно удалить платформы? То ли я чего-то недопонимаю, то ли removeMovieClip тут бесполезен?

  42. AllZooMer

    очень круто!!!!! мегаполезная статья!!))))

  43. kramfus

    вот это да… не думал , что все так просто…спасибо огромное !!

  44. SARFEX

    Блог расчитан на людей хоть с самой минимальной но базой, а вопросы типа “а куда ентод код то фтыкать парни?” совершенно не катят) Berch для передачи между swf используют LocalConnect, только надо ли вам оно…

  45. Антон

    млин =( Не получатеся D: Тут же 1 кадр должен быть??? Если да, то в него засовывать трехкадровый символ hero??? Заранее спасибо, извините за тупые вопросы =(

  46. Stormit

    Просьба к тем кто задаёт вопросы, читать кроме статьи ещё и комментарии - там часто бывают ответы.
    Как определить куда писать код, если явно не указано (относится к AS1):
    1) если код внутри обработчика onClipEvent(имя_события) {…} , то пишем НА символе
    2) если код внутри обработчика on(имя_события) {…} , то пишем НА кнопке
    3) если код записан без этих обработчиков событий, его писать можно только В кадре. Писать нужно в том кадре, чтобы ссылки на все клипы и переменные, которые используются в коде были доступны.
    >>в него засовывать трехкадровый символ hero???
    На слайде 2 голубыми рамками условно показано в каком клипе что находится.
    То есть символ hero сам 3-х кадровый, и в каждом кадре содержится клип с именем man внутри которых анимации разных состояний (одинаковые только имена клипов - man)

  47. PatrickJSD

    Stormit а как у клипов может быть одно и то же имя ?! у меня пишет что имя man уже занято

  48. Stormit

    Это не имя в библиотеке символов. Это имя клипа на сцене (instanceName).
    Главное, чтобы независимо от текущего состояния персонажа, можно было выполнить код hero.man.play() - полиморфизм в кадровом виде :)

  49. AZECK

    Всё понятно, а только, с помощью чего вы это всё делаете?

  50. HonorRanger

    http://www.ziddu.com/download/5481454/Platformer.rar.html
    вот мой исходник, можете объяснить где я ошибку сделал ?
    Или лучше выложите свои исходники по этому уроку.

  51. TRY

    Короче HonorRanger! Во-первых: У тебя ваще не назван клип hero (это самый главный), затем: чего ты в hero с названиями намудрил я не знаю. В главном клипе у тебя в верхнем слою должны быть “маркеры” тоисть p1, p2, p3, p4. Слоем ниже три состаяния героя: стоит, бежит и прыгает (и у них всех имя “man” но в библиотеке называй их по-разному). И самое главное - КОД ИГРЫ НУЖНО ПИСАТЬ НЕ В КАДРЕ С HERO А СЛОЕМ ВЫШЕ. В любом случае пользуйся примером этой статьи (по идее всё должно быть понятно).

  52. TRY

    Stormit вы могли бы ответить? Вот мой вопрос - как сделать так чтоб когда два клипа перекрещивались происхожила определённая анимация????? Пытался разобраться в вашем примере из Crimsonland с пауками (клип hit и bullet) но нечего не получилось. Если всётоки сможете ответить то пожалуйста напишите в месте с кодом=))

  53. PatrickRus

    Эх, если бы Вы еще показали, как к этому делу скроллинг применить ;)

  54. Лаки

    Если я правильно тебя понял, то тебе нужна хитрая камера буквально из соседнего поста.

  55. PatrickRus

    Ой. Спасибо ))

  56. PatrickRus

    Ээээ, нет, я не это имел ввиду. )
    Я про скроллинг, в смысле, когда персонаж подходит к краю экрана, фон начиает прокручиваться вверх-вниз и влево-вправо

  57. Zik

    Молодец! Я правда до этого додумался, но все равно спасибо, что сказали.
    Я все время думал что я как-то неправильно делаю

  58. HonorRanger

    Ну вот например второй вариант)) http://www.ziddu.com/download/5492693/Platformerv1.001.rar.html
    где я тут снова нахимичил ?)
    p.s. лучше выложите кто то исходник))

  59. TRY

    Эх HonorRanger. Почему ты не назвал самого героя? И маркеры у тебя без имени. Потом ты столько всего понаделал в клипах man что голова кругом. Зачем столько лишних слоёв? В клипе body не надо писать - проверка_попадания(); дословно, в этом месте нужно пишется код на проверку попадания в врагов (если они у тебя конечно есть) не удивляйся если не найдёшь его в этой статье, его здесь нет.
    Вобщем попробуй поменьше лишних кадров делать.

  60. HonorRanger

    “Эх HonorRanger. Почему ты не назвал самого героя? ”
    Ок, спасибо, та вот в чем меня загвостка была!

  61. TRY

    Всегда рад помочь.
    Если кто знает как припересечении клипов сделать так, чтоб происходила анимация - то пожалуйста ответте.

  62. Stormit

    Функция checkHitPlatform() определяет с какой стороны от персонажа был контакт с платформой. Можно здесь анимацию запускать (функция play() для клипа с анимацией). Например, можно здесь создать дубликат клипа (анимация пыли от приземления) и поставить в нужном месте (в последнем кадре анимации удалить его).

  63. TRY

    Спасибо за совет. Но вообще я хотел узнать немного другое. Например - у меня летит шарик (клип с именем “ball”), когда он долетает до столба (”post”) то в нутри внутри него должна играть определённая анимация. Если я ещё не надоел то пожалуйста ответте.

  64. Stormit

    if(ball.hitTest(post)) {ball.play()}
    или hitTest по маркерам если они есть

    Скажи когда прочтёшь, я почищу ветку от лишних комментариев

  65. PatrickRus

    Stormit, если Вам не трудно, расскажите, пожалуйста, как сделать скроллинг карты как в Striped Escape. То есть не просто зацикленный фон, а когда игрок отходит на определенное расстояние от середины экрана, начинает двигаться не персонаж, а оружение: фон, враги, предметы и т.п.

  66. SARFEX

    PatrickRus
    Самое простое это привязываешь _root._x и _y к _x и _y персонажа
    В Striped Escape немного услажнено

  67. PatrickRus

    SARFEX
    Спасибо, попробую то-нибудь свое к этому коду добавить.

  68. Stormit

    Следующий пост будет об этом

  69. PatrickRus

    Отлично, спасибо :)

  70. TRY

    Огрооооомное спасибо за ответ!!!!!!!

  71. Виталий

    Здравствуйте. Спасибо за информацию, оченно помогла. Мне сейчас нужно сделать игрушку-поздравлялку для клиентов. Основа—ваш движок, а вот причендалы мои, но вот есть у меня несколько моментов которые упорно не хотят сдаваться.

    Игрушку выкладываю: http://www.7474.ru/game

    Задумка следующая: мужик (пока что безрукий) бегает и ловит подарки (сейчас шарики), которые выбрасывают облачка. В принципе всё почти получилось, НО непонятно:
    1) Почему шарики-подарки останавливаются не там где я им указываю.

    2) Почему то не работают вместе onEnterFrame(), который сбрасывает шарики-подарки вниз и который запускает stepHero(), в рузультате пришлось stepHero() запускать с помощью setInterval().
    3) Использую класс Tween, потому что не смог написать приличного кода функции для алгоритма: приезжает — сбрасывает — уезжает; Скажите насколько обоснованно применение данного класса, можно ли написать своё? Если да то подскажите пожалуйста как именно. (остальное удалено чтобы не засорять ветку)

  72. Виталий

    Простите, не написал что в работе облаков, сбрасывающих круги наблюдаются серьёзные сбои, тоже не пойму почему.

  73. Stormit

    Во-первых вы бессовестно спёрли графику с кирпичами из моего примера, во-вторых здесь обсуждается статья, а не ваша игра.
    Я могу ответить на вопросы по своему коду или подсказать принцип как что-то добавить, но искать ошибки в чужом коде мне, как минимум, не интересно.

  74. HonorRanger

    Спасибо за урок, и всем тем кто помогал мне с возникающими вопросами))
    Оказалось не очень сложно)
    Вот что у меня получилось)http://www.ziddu.com/download/5591011/Platformer2.rar.html

  75. Антон

    HonorRanger скинул бы fla….) А то у мну проблемы как у тебя =( (до сих пор)

  76. Антон

    “Эх HonorRanger. Почему ты не назвал самого героя? ” просто не понимаю этой фразы)

  77. TRY

    В этой фразе нет нечего сложного. Ты просто должен в панеле properties (обычно это нижний левый угол) под надписью movie clip написать hero. Вот и всё!

  78. Антон

    Ок! Спасибо TRY!)

  79. Антон

    А Stormit-у тоже ОГРООООМНОЕ спасибо)

  80. Антон

    Что-то я опять напартачил) Млин ребят, реально простите, просто оч хачу доделать) вот фла http://depositfiles.com/files/fqjvvq9g3

  81. Stormit

    Да всё просто, нужно только привить себе привычку выставлять центр символа в нужном месте. У вас в платформах и маркерах центр сбит, поэтому и глюки (графику в этих клипах нужно отцентрировать).
    Анализируйте код, например строка:
    var hhy = (hero.p2._y - hero.p4._y + hero.p2._height / 2 + hero.p4._height / 2) / 2;
    требует чтобы половина высоты персонажа корректно определялась.

  82. Антон

    Вроде все отцентрировал, проверил.. Все нормана, тока опять не прыгает)

  83. Антон

    Все ок) Терь даже прыгает) Спасибо)

  84. Антон

    Ой забыл, он у меня еще не атакует(Когда жму пробел все клавиши замыкаются и герой даже не двигается)

  85. TRY

    Нуууу здесь тоже всё очень просто. Первое - ты не назвал в клипе hero клипы man, второе - в внутри первого man-а не назван клип с ударом body. Когда всё это зделаешь - должно работать.

  86. hammerhl

    Уважаемые! Из за чего может быть такой глюк, что при попадании на платформу персонаж начинает постоянно немного подпрыгивать, при чем на величину меньшую высоты прыжка и несколько быстрей.

  87. TRY

    У тебя неправильно смещён центр платформы. Попробуй его поставить чуть выше или ниже.

  88. hammerhl

    Отлично! TRY, благодарю, помогло. Но появился другой косяк, при столкновении с вертикальными платформами (столкновения слева и справа) персонаж резко уходит вверх, на саму платформу. Я конечно это попробую сам поправить, но если у кого есть какие идеи, буду рад.

  89. Stormit

    У вас одновременно пересекаются 2 маркера с платформой - боковой и нижний. Нужно нижний маркер сделать меньше по ширине.

  90. Crash

    Stormit - - - ты где-то учился графике и аннимации или это всё приобрёл сам?
    (Рисуешь просто здорово и как ты разбираешься в тенях? У меня с ними проблема я просто не понимаю как их нужно расставлять и из-за этого половина моих работ - без теней, да и вообще я раньше не думал что всеръёз увлекусь аннимацией так создал какую-нить работу и удалил сразу-же что-б место не занимало Раньше мне казалось что это всё ерунда и что написать игру или программу может любой дурак но потом попробывал сам и понял что жестоко ошибался в своих убеждениях)..
    (Можешь спросить плс своего друга какие проги для создания звуков он использует?)

  91. Chelik

    Супер нужная штука: быстро, просто и практично !!!

  92. RR

    Добрый день. Рисую я хорошо, а вот в программерстве я полний чайник. Даже скопипастив ентот движок у меня ничего не получилось. кто-нибудь может подсказать, где возможна самая простая ошибка?

  93. comRAT

    Автору огромный респект! Спасибо, Stormit! Уважаю программеров, которые с пониманием относятся к новичкам)

  94. kramfus

    странно , я сделал все , как описано здесь , и ничего не происходит , обьясните пожалуйста , в чем дело ? http://narod.ru/disk/12475314000/MUTANT%20ATTACK.fla.html

  95. GALLlblSH

    а что делает строка Key.addListener?

  96. Stormit

    to kramfus
    вы переопределяете onEnterFrame, так, что мой остаётся не у дел
    to GALLlblSH
    этой строкой мы добавляем слушателя к объекту Key. Когда возникнет событие onKeyDown, он вызовет метод onKeyDown() у всех, кто на него подписался.

  97. GALLlblSH

    А разве нельзя без него обойтись? Если заунуть код в обработчик nenterFrame? Например:
    onEnterFrame = function(){
    if (Key.isDown(Key.UP) && !jump && !shoot) {…}
    //и так же для пробела
    stepHero()
    }

  98. Stormit

    Можно, но тогда код будет выполняться каждый кадр (бессмысленно нагружая, хоть и слегка, процессор), а подписавшись, функция вызовется только при нажатии клавиши, тем более что прыжок срабатывает только один раз - дальнейшее удержание кнопки ни к чему не приводит

  99. Виталий

    Дорогой дружище Stormit спасибо тебе за твой ресурс! Прости что я как то раз стибрил у тебя кирпичи! Я нарисовал новые, вот погляди http://www.7474.ru/game/boy.html

  100. Stormit

    Отлично получилось. И по стилю эти сюда больше подходят :)

  101. Антон

    Такое дело, до 6 пункта всё ок, а после получается так что персонаж либо начинает как бешеный скакать по полю, или вообще проваливается, всё из темы про “УСТРАНЕНИЕ ГЛЮКОВ” применил, но продолжается такая бурда =(
    Думаю что проблема вызвана “hitTest” хотя хз……

  102. Иван

    плиз, выложте кто- нибудь рабочий исходник, а то уже несколько дней мучаюсь и никак не получаеться.Умоляю! ААААААА!!!!!!

  103. HororLord

    Пожалуйсто ктонибудь может мне сказать что я тут сделал не так?
    http://depositfiles.com/files/clvdbyfrd

  104. k0t0vich

    _parent._parent._parent.checkHit(); - это ужас… очень плохие хитрости.

  105. Роман

    начал выполнять,анимация сделал,дошел до встваления кода,непонял куда его вставлять и какой это язык Ас2 или Ас3 подскажите плз что делать)

  106. HororLord

    Вставлять надо в Layer, а язык тут AC2

  107. Илья

    Выложите кто нибудь исходник, а то что то неполучается…

  108. Astrey

    Я поддерживаю, не плохо было бы выложить исходник, так будет понятнее, если не жалко))

  109. Yegor

    Я хочу создать игру для двоих игроков, делаю второго игрока по тому же принципу, после этого ни один персоонаж не двигаеться. Почему?

  110. Astrey

    Ура у меня все получилось!!!!!! я сделал это!!!!! просто перед данным уроком нужно немного почитать про ActionScript

  111. TricK Dexter

    поначалу во многие моменты не въезжал.
    2 недели ковыряний и вот что получилось http://www.gamedev.ru/projects/forum/?id=84082&page=2#m22

Оставить комментарий