“Cкроллинг”, или как смещать фон вместо персонажа

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

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

Спешу ответить.
Есть один способ, самый простой, на мой взгляд, вот его и рассмотрим. Возьмём конечный результат из “предыдущего примера”, теперь “обернём” всё полученное в новый символ game. Наглядно результат показан на слайде 1 - код, персонаж, противники (если есть), платформы, графика и всё всё всё, должно оказаться внутри этого клипа. Такой клип можно смещать, масштабировать, крутить, копировать в другой fla-файл - игра будет работать.

Принцип, по которому будем скролировать фон: при любом смещении персонажа, клип с игрой game смещаем на такое же расстояние, но в противоположную сторону. То есть, если главный герой бежит вправо, то клип с игрой нужно сместить влево. Это основа, для этого достаточно в коде игры (см. предыдущий пример) после того как переместили клип hero, добавить следующие строки:

//вместо героя сммещаем фон
_x = -(hero._x - 275);
_y = -(hero._y - 100);

275 и 100 - это половина ширины и высоты моей флешки - при этом персонаж будет всегда оставаться в центре. Что получилось, можно увидеть на слайде 2. Замечу, что на этом этапе масштабировать клип уже нельзя, так как системы координат внутри и снаружи клипа game должны быть одинаковы. Иначе получите не то что ожидали :)

Это уже рабочий вариант для игры. Если нарисуете интересный фон с запасом, то можно так и оставлять. Кому надо чтобы фон не прокручивался дальше пределов уровня - идём дальше.

Я немного увеличил размеры уровня, чтобы прокрутка была наглядней. Ещё нужно определить границы, за которые клип game не должен выходить. Сделать это просто: смещайте клип game в максимально допустимое положение и в панели Info смотрите его координаты. Вам придётся самим подобрать значения для вашего случая. Код теперь такой (с крайними значениями которые получились у меня):

//крайнее положение, когда персонаж упирается влево
var x0 = 39;
//крайнее положение, когда персонаж упирается вправо
var x9 = -145;
//крайнее положение, когда персонаж упирается в потолок
var y0 = 10;
//крайнее положение, когда персонаж внизу
var y9 = -130;
_x = -(hero._x - 275);
_y = -(hero._y - 100);
//проверяем чтобы клип game не выходил за ограничения
_x = (_x > x0)? x0 : (_x < x9)? x9 : _x;
_y = (_y > y0)? y0 : (_y < y9)? y9 : _y;

Получаем слайд 3. Чтобы увеличить производительность, вместо if else используется сокращённый вариант () ? :

Кому этого мало, могут использовать камеру для “слежения” за персонажем (клип с самой камерой назовём camera). В этом случае ограничивающие координаты будут чуть другими. Так же с камерой можно легко задействовать масштабирование. Код:

camera._xscale = camera._yscale = Math.max(100, 100 + (1 - hero._y / 250) * 28);
var x0 = -39 + camera._width / 2;
var x9 = 697 - camera._width / 2;
var y0 = -9 + camera._height / 2;
var y9 = 329 - camera._height / 2;
camera._x = hero._x;
camera._y = hero._y;
camera._x = (camera._x < x0)? x0 : (camera._x > x9)? x9 : camera._x;
camera._y = (camera._y < y0)? y0 : (camera._y > y9)? y9 : camera._y;

Сейчас чем выше забирается персонаж, тем больше становится камера и в её обзор попадает всё большая площадь. Эффект масштабирования лучше воспринимается если отключить ограничения по координатам. “Наезд” камерой на персонажа можно эффектно использовать в играх, меняя обзор в зависимости от участка уровня. Там где нужно много прыгать можно дать широкий обзор местности, а когда дело дойдёт до схватки, камеру можно уменьшить до размера персонажей. Но чтобы не было тормозов, фон должен быть растровой картинкой.

Это не единственный способ прокрутки фона. Можно разбить фон на квадраты и добавлять/удалять по мере необходимости, можно сдвигать всё кроме самого персонажа. Выбирать вам.

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

(81) Хитрых на тему «“Cкроллинг”, или как смещать фон вместо персонажа»

  1. Green

    Замечательный пример!!

  2. TRY

    Даааа хороший урок!

  3. Роланд Чанишвили

    А вот с управлением чтото не то - когда “идеш” вправо\влево - прыжок не всегда отрабатывает. И удар хорошо-бы наносить в движении…

  4. HonorRanger

    Замечательный урок! Супер!
    Вот что у меня получилось )) http://www.ziddu.com/download/5591381/Platformer3.rar.html

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

  5. Stormit

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

  6. Сталекс

    респект и уважуха! Единственный и достаточный ресурс для создателей игор всех уровней!:)

  7. Bulat

    спс огромное какраз нужно было сделать подвижный фон

  8. Димастый

    а этот код пойдет для as 2. Просто у меня стоит flash 8

  9. Platon

    2 Stormit:
    а есть ли хитрости для того, чтобы при наведении камеры фон не пикселизировался?

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

    Вариант грубоватый, но работает. а есть ли другие способы?

  10. Stormit

    Можно выставить сглаживание для картинки.

  11. Bulat

    Stormit а можно еще уроков по рисованию? и анимации плиз

  12. psih

    Отличный урок! Stormit - ваши роботи радуют глаз и вдохновляют :)

  13. Domik

    Такой вопрос к автору: если уровни делать не цельной большой картинкой, а собирать из небольших битмапов созданных по ходу выполнения и завернутых в отдельные мувики -насколько производительность будет ниже по сравнению с цельной большой картинкой?

  14. HonorRanger

    А можно узнать, о чем следующий урок будет ?) неплохо было бы добавить каких-нибудь противников))

  15. elbik

    Спасибо за идеи и новые уроки :)) продолжай в таком же духе ;)

  16. shaman4d

    Урок правильный. Спасибо за идеи.
    Правда посмешило: “Чтобы увеличить производительность, вместо if else используется сокращённый вариант”

    И почему так лагает в 4й стадии примера? - так тормозит при прыжке что прыгать не хочется :)

  17. Stormit

    Просто уже задавали вопросы, что означает такая строка.
    А тормозит, потому что фон векторный, к тому же есть анимация факелов. При масштабировании нужно перерисовывать весь экран. Чтобы избавиться от тормозов, нужен статический растровый фон :)

  18. Возвращение. Wacom. « Murlyka Studio

    […] Хitri рассказал про скроллинг, динамические фоны и простой движок для флеш […]

  19. HonorRanger

    У меня вопрос, на чем лучше писать игры на AS2 или AS3 ? Стоит ли переходить на ActionScript 3.0 ??

  20. Stormit

    Если игра не сложная, то её лучше сделать на AS1 - будет быстро и не успеете забыть где и какой код прописан.
    Если же игра сложная, то лучше делать на AS3. Грамотное использование принципов ООП позволяет не запутаться в классах и писать игры любой сложности. К тому же в сети масса бесплатных и полезных библиотек, которые можно использовать в играх и которые написаны на AS3.
    Учить AS3 в любом случае стоит, если не хотите со временем “зависнуть” на мелких работах.

  21. PatrickRus

    Stormit
    Замечательный туториал, спасибо огромное )))

  22. HonorRanger

    Stormit
    А Пчелоид и флеш-игра Striped Escape сделаны на AS3 ??

  23. Stormit

    На AS2

  24. Bulat

    Stormit Давай тогда доведешь этот платформер до ума (добавишь противнков и тд) плиз

  25. HonorRanger

    согласен с Bulat

  26. animefish

    HonorRanger и Bulat - а вы типа свою графику туда добавите и продавать побежите да?

  27. Stormit

    Да, парни, в готовом виде ничего выкладывать не хочу, потрудитесь немного сами - там ничего сложного.

  28. Bulat

    HonorRanger нас раскусили :D :D :D
    сори за оффтоп

  29. HonorRanger

    контору накрыли))

  30. Crash

    Привет всем=)
    Классные уроки и поучиться стоит - понравилось что камера(фон) теперь следит за главным героем и аннимацию доделали))

    Вы оказываете помощь многим людям, даёте запал и идеи будующим анниматорам, пробуждаете интерес к новому, объясняете и заставляете совершенствоваться.

    Спасибо Всем Вам))

    p.s: Хотел выложить одну интересную флэшку которая Очень понравилась))

    http://www.newgrounds.com/portal/view/420606

  31. kramfus

    cпасибо Вам огромное за замечательный урок !! но на днях я обнаружил более простой спосб смещения фона , вот : http://letitbit.net/download/6703.69a84c5580d40edbd55d1ac44/game.fla.html

    простите за лишний код …

  32. Stormit

    Тут вряд ли можно применять понятие “более простой” - нужно смотреть для какого конкретного случая он проще. Кстати, там описана та же самая камера, только в другом виде.

  33. HonorRanger

    Stormit а вы не могли бы показать как сделать “гладкие” и движущиеся платформы? Надо что то проделывать с маркерами, не так ли ?

  34. DreamCasterXP

    Здравствуйте Stormit. У меня вопрос не по данной теме. Хотелось бы вашего совета.
    Я пытаюсь сделать флеш игру в жанре Tower Defense.
    Допустим имеется MovieClip в виде круга, как сделать, что бы его площадь изменялась относительно расстояния выстрела башни? (Иными словами хочется создать видимость радиуса выстрела выбранной башни. Какой функцией можно задать?)
    Я пытался использовать вот эту
    onClipEvent (load) {
    _root.getNextHighestDepth(_width:turret.range, _height:turret.range);
    }}

  35. palaum

    Спасибо за интересный сайт.
    Вот такой получился подарок на свадьбу — http://dowedding.spb.ru
    Использовался ваш движок — очень удобно, действительно не приходится запариваться на счет программинга.

  36. pacific

    А как сделать камеру вид сверху и чтобы управление было как в игре Булварк 53 http://f-games.ru/Bulwark-53.html

  37. Лёша

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

    p.s Заранее огромное спасибо…

  38. psih

    Не совсем в тему :) Но я опять повторюсь что восхищаюсь и вдохновляюсь работами Stormit-а. Я все говрю говорю но наконец есть что и показать… пока игры не доступны для общего просмотра но есть небольшие видео
    1) http://www.youtube.com/watch?v=UsIsdoJ8Mm4
    (обратите внимание на обход препятствий, метод описанный на сайте только под АС3, и не только :) )
    2) http://www.youtube.com/watch?v=ExwJlgmgK4w
    (чем не кримсонлед ? :) )
    Мой опыт работы с флешем начался именно с этого сайта , когда что то не клеилось я заходил сюда и после все получалось. Stormit - огромное пасиба!

  39. Юрій

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

  40. Саша

    Обновляйте блог давайте уже

  41. Crash

    Думаешь это так просто?

  42. Юрій

    вот об этом я хочу написать
    http://vkontakte.ru/app730506_22652795

  43. Senyuha

    У меня вопрос, на чем лучше писать игры на AS2 или AS3 ? Стоит ли переходить на ActionScript 3.0 ??

  44. Юрій

    as2-легче
    as3-имеет лучшую производительность
    выбирайте сами

  45. неизвестный

    странно,блог остановился

  46. Денис

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

  47. Stormit

    Этот способ скролирования отлично работает для растрового фона размером 1200х1200.
    Для более больших уровней, можно разбить уровень на несколько кусков и показывать только те, которые видны пользователю.
    Честно говоря я не вижу прямой связи между использованием “тайлов” и отсутствием циклов для проверки столкновений - это может быть только в вашем конкретном движке.
    У меня, например, в Striped Escape, уровни из плиток и в цикле проверяется столкновение с плитками, которые находятся возле персонажа.

  48. AN_G

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

    pacific, для такой игры(вид сверху) все есть на сайте, а если пошаманить над “простой движок для флэш-игр типа “Вид сверху”” и переделать его под клаву, то получатся столкновения еще круче, так же интелект зомби основан на нем.

  49. Stormit

    В последнем примере используется камера

  50. AN_G

    к стати, Stormit, недавно поиграл в Skarygirl, игра и вправду мега, но, скорее из-за своего дизайна и гейм плея, движок там не такой уж и сложный, в fancy pants такой же.

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

    если для тебя это еще актуально, могу поискать и скинуть.

  51. Денис

    Stormit - :) Просто есть формула которая позволяет находить пересечения без циклов если хотите могу скинуть урок?:) Именно нахождение тайлов без циклов. Ну если вы хотите сделать сложное нахождение пересечения то малюсенький цикл понадобится :) Кстате та формула позволяет практически делать “бесконечные” карты. А не как при использовании циклов максимум 100х100 и комп кровью комнату захарькивает. Ну думаю смысл поймете :)

  52. Stormit

    Наверное вы имеете ввиду так называемую “сетку
    Это делается для больших карт и с большим количеством объектов. Если игра не большая и процессор легко справляется, то всё это становится излишеством и только отнимет зря время.

  53. Денис

    Неее там вектор раз, флешь обрабатывается на проце. У меня эта игра на 3600 Гц тормазит. А вообще если делать большой тайловый мир. То избовляться от циклов нужно, и использовать только нужные тайлы и экономить ресурсы для обработки движка, а в обработки движка нужно остовлять ресурсы для графики :) Круг такой жестокий :) Видуха не помогает обрабатывать процу графику. Там нужно много ресурсоэкономных алгоритмов использовать. Вот ща пишу такой двиг как напишу кусочки поскидую. Если хотите конечно.

  54. Субарахноидальное пространство

    Прекрасный пример, я это обязательно учту, но пока что у меня другая проблема(((
    Написал интерактивное движение человека на AS 3:

    mvl.alpha = 0 // Моделька движения влево не видна
    mvr.alpha = 0 // Моделька движения вправо не видна
    str.alpha = 0 // статическая моделька повёрнутая вправо не видна
    //Мы видим лишь stl - статическую модель повёрнутую влево

    stage.addEventListener(KeyboardEvent.KEY_DOWN, mov); //слушатель события нажатия клавиши
    stage.addEventListener(KeyboardEvent.KEY_UP, stay); // слушатель события отпускания клавиши

    function mov(event:KeyboardEvent):void // функция движения
    {
    if (event.keyCode == Keyboard.LEFT) //смещение влево и включение нужной модели движения
    {
    mvl.x–
    mvr.x–
    str.x–
    stl.x–
    mvl.alpha = 100
    stl.alpha = 0
    str.alpha = 0
    }
    if (event.keyCode == Keyboard.RIGHT)
    {
    mvl.x++
    mvr.x++
    str.x++
    stl.x++
    mvr.alpha = 100
    stl.alpha = 0
    str.alpha = 0
    }
    }

    function stay(event:KeyboardEvent):void // функция остановки
    {
    if (event.keyCode == Keyboard.LEFT) // остаётся видимой повёрнутая в нужную сторону статическая моделька
    {
    mvl.alpha = 0
    stl.alpha = 100
    }
    if (event.keyCode == Keyboard.RIGHT)
    {
    mvr.alpha = 0
    str.alpha = 100
    }
    }

    Проблема в следующем: при нажатии любой клавиши реакция происходит не плавная. В момент нажатия на кнопку происходит смещение на 1, потом на короткое время движение прекращается, а потом становится непрерывным. Трудно объяснить… В общем всё это напоминает “точка тире”. Как сделать плавное движение, чтобы оно не прерывалось, а сразу становилось непрерывным, пока кнопка не отпускается? Если передвигать фон вместо персоонажа - всё обстоит точно так же. Подскажите, пожалуйста.

  55. Stormit

    Ваш подход к программированию соответствует нику :)
    Это ОЧЕНЬ нехорошее решение. Во первых вы смещаете все четыре состояния вместо того чтобы: а) засунуть всё в один клип и смещать только его; б) используйте visible=false вместо alpha=0 - это меньше нагрузит процессор (прозрачные клипы всё равно участвуют в расчётах); в) используйте свойство scaleX для поворота персонажа влево/вправо вместо 2-х отдельных клипов.
    А что касается проблемы с кнопками, то обрабатывать нужно не нажатие клавиши, а на ENTER_FRAME проверять какая клавиша нажата. Если добавите в игру прыжок, то столкнётесь с тем что AS3 помнит только последнюю нажатую клавишу - тут вам поможет этот класс

  56. Субарахноидальное пространство

    Stormit, большое спасибо. Я просто совершенно никогда не работал во Флэше. Несколько дней назад скачал и что-то пытаюсь, не зная синтаксиса и стандартных классов, так что не обижайте уж, исправлюсь.

  57. Иван

    HonorRanger,выложите пожалуйчто исходник flasки которую вы выложили по этому адресу- http://www.ziddu.com/download/5591381/Platformer3.rar.html. Заранее спасибо..

  58. Lgunchik

    Кто знает как помочь мне??))
    Моя задача такова, мне надо что бы “машина” (в моей игре) стояла на месте, а дорога ехала в обратную сторону как показано в примере, НО проблема в том что дорога слишком маленькая что бы хватило на наслаждающую поездку((
    помогите плз…

  59. Konstantsiya

    Очень полезные советы.

  60. Денис

    Lgunchik - тайловую рамдомную карту сделай и все :)

  61. Arkon

    Денис, скинь урок с чудо-формулой которая позволяет находить пересечения без циклов. плиз ;)

  62. hammerhl

    Вот, собственно, что получилось у меня, http://file.qip.ru/file/108688133/5a0c01d1/pa_online.html добавил противников и оружие ;).

  63. Денис

    http://file.qip.ru/file/109185308/ac6fbc25/_online.html
    Вот маленький пример этой формулы :) В игре где карты примерное 16х302, она отлично работает. На ошибки не ругайтесь :)

  64. Денис

    Если понравится, напишу на ней маленькую игрульку и объясню что к чему :)

  65. Zalupa

    А почему нельзя файлы к коментам прикреплять ? :(
    Я начал делать одну космическую игруху.
    Потратил на неё много времени, нашёл много зарисовок кораблей.
    Осталось только собрать всё в кучу.
    И сделать регистры и всё остальное.

    Вобщем если кто заинтересуеться, вот исходник:
    http://slil.ru/28268249

  66. NewLeaX

    О Боже, какая прелесть))

  67. vitaLee

    i followed a link to your blog through emanuele feronato blog.
    just wanted to say that you have really nice blog here. congratulations!!!
    i’ll be following it with interest.
    greetings from Bulgaria :)

  68. Yegor

    Привет, Stormit, извини что не в тему. Недавно увдел флеш игру. Там надо шарик на веревочке забросить в углубление. Хотелось бы знать как это сделать, не поможешь http://www.ababasoft.com/flash_games/040222.html - ссылка на нее

  69. СЕРГЕЙ

    у меня не получается я прописываю код а у меня не работает

  70. Stormit

    Исходник есть здесь

  71. In-Finity

    Попытался делать скроллинг экрана, как вы описали, и столкнулся с одной проблемой.

    Постараюсь объяснить на словах, но чтобы было понятно, наверное лучше всего посмотреть исходник.
    Суть такова:
    У меня есть объект CAR и препятствие LEVEL1. При столкновении происходит обычный hitTest. Всё это засунуто в клип GAME.
    Всё работает отлично.
    Код такой:

    game.car._x = 100;
    game.car._y = 200;
    game.text._visible = 0;
    function KEYS() {

    if (Key.isDown(Key.LEFT)) {game.car._x -=3;}
    if (Key.isDown(Key.RIGHT)){game.car._x +=3;}
    if (Key.isDown(Key.UP)) {game.car._y -=3;}
    if (Key.isDown(Key.DOWN)){game.car._y +=3;}

    // game._x = -(game.car._x - 300);
    // game._y = -(game.car._y - 200);

    }

    function HIT() {
    if (game.level1.hitTest(game.car._x, game.car._y, true)) {game.text._visible = 1;}
    else {game.text._visible = 0;}
    }

    onEnterFrame = function() {
    KEYS();
    HIT();
    }

    Но я хочу сделать, чтобы мой объект CAR оставался посередине, а скролился весь экран. Для этого я раскомменчиваю две закомменченые строки.

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

    Почему так происходит? Как это исправить?

  72. kurdyumoff

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

  73. Rokiko

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

  74. hammerhl

    >>Rokiko
    Adobe Flash.

  75. Xcite

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

  76. Chelovek

    Большое спасибо, Отличный пример!

  77. Kemerover

    не легче ли юзать камеру?

  78. алекс

    Денис, дык, ведь ничего особенного в твоей формуле нет, впринципе все давно известно.

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

    У меня вопрос есть по графике, Стормит, как получить картинку с пиксельным шумом, как у тебя в этой демке?
    Спасибо.

  79. Лёва

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

  80. Den15

    Эмм, ну так этож формула,для начало мышления, а дальше ее дорабатвать для сложных пересечений.

  81. Лёва

    Знаете, это похоже единственный сайт, включая сайт адоба, где написан пример сокращенного if
    спасибо большое

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