Какой скрипт сдвинет спрайт влево на 10 пикселей

Обновлено: 06.07.2024

До того, как в CSS появился псевдокласс :hover , создание ролловера — элемента, который меняет свой вид при наведении курсора — реализовывалось через язык JavaScript. Сейчас это делается намного проще, но есть один недостаток: если в состоянии :hover (т. е. при наведении курсора на элемент) должно появиться какое-то фоновое изображение, то оно начинает загружаться в момент наведения курсора, а не при общей загрузке страницы.

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

Что такое спрайты CSS

CSS-спрайт — это один графический файл, который содержит много различных изображений. В нем могут быть собраны, к примеру, все графические элементы интерфейса, такие как иконки, кнопки и прочее. Также в спрайты часто объединяют фоновые картинки вместе с их вариациями для состояния :hover . Типичные примеры спрайтов:

Спрайт, в котором собраны все используемые иконки

Спрайт со значками соцсетей и их вариациями для :hover Спрайт с элементами интерфейса

Преимущества CSS-спрайтов

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

Как создать спрайт из картинок

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

Ручной способ создания спрайтов — занятие довольно долгое. Поэтому, когда использование спрайтов стало набирать обороты, появились онлайн-сервисы по автоматическому созданию спрайт-листов, например, Spritegen, RetinaSpriteGenerator и другие. Вы загружаете необходимые изображения в отдельных файлах на сайт, и для вас генерируется спрайт, который вы сразу можете скачать на компьютер.

Как пользоваться спрайтами CSS

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

HTML-разметка выглядит следующим образом:

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

Переходим к CSS. Первым делом запишем общие стили для всех ссылок:

Первая строка содержит ссылку на спрайт. По факту, мы задали одно фоновое изображение для всех ссылок. Вторая строка отменяет дублирование фона — здесь оно не потребуется.

Следующие две строки — высота и ширина каждого элемента <a> . Каким образом определялись эти значения? Здесь мы отталкивались от размеров значков в спрайте. Высота каждой иконки равна 98 пикселям, а ширина — 100 пикселей. Далее мы будем позиционировать фоновую картинку для каждой ссылки, подстраивая фон таким образом, чтобы значок ровно вписался в «окошко» ссылки размером 98×100 пикселей.

Первая наша ссылка имеет класс .facebook . Зададим позиционирование для ее фона. Иконка Facebook находится точно в левом верхнем левом углу спрайта, поэтому определить ее позицию будет легко — left top :

Идем дальше: позиционируем фон для ссылки на Twitter. Иконка Твиттера расположена справа от Facebook и примыкает к ней, не создавая пустых промежутков. Нам необходимо переместить спрайт влево на столько пикселей, чтобы скрыть иконку Facebook и полностью заполнить область ссылки иконкой Twitter. Поскольку ширина каждой иконки равна 100 пикселям, то мы и сдвигаем фон влево на 100 пикселей. Вертикальное позиционирование мы пока нигде не меняем, а оставляем значение top :

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

Результат работы данного кода показан на скриншоте ниже:


Ссылки на соцсети с использованием CSS-спрайта


Теперь разберемся с поведением фоновых картинок при наведении курсора на ссылку. Нам нужно смещать спрайт по вертикали вверх таким образом, чтобы в область просмотра попадала иконка из нижнего ряда спрайта. Здесь всё довольно просто и решается одним правилом CSS, а именно присвоением значения bottom свойству background-position-y :

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

Результат работающих спрайтов смотрите на демонстрации ниже (для более красивой подачи примера мы сделали сдвиг фона более плавным при наведении курсора):

Если вам стало интересно, то вот и строка, которая отвечает за плавность изменения иконок (не волнуйтесь, чуть позднее мы будем изучать CSS-анимацию, и в частности свойство transition ):

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

Вот мы и разобрали основные методы стилизации ссылок. Рекомендуем вам дополнительно попрактиковаться, чтобы закрепить полученные знания. А следующая глава нашей книги посвящена CSS-анимации, реализация которой стала возможна благодаря свойствам, появившимся в CSS3. И в первом уроке мы разберем свойство трансформации — transform.

Исполнитель в Скретч может не только двигаться по среде, но и поворачиваться!

Вот команды, которые позволяют выполнять повороты:

Спрайт вращается вокруг своего центра (центральная точка воображаемого прямоугольника, в который вписывается картинка). Вращать можно по часовой стрелке или против (вот почему предусмотрено две команды).

Центр вращения — центр спрайта. Вращение по и против часовой стрелки

Угол поворота измеряется в градусах от 0° (нет поворота) до 360° (полный оборот).

Угол поворота измеряется в градусах. Знаком градуса является символ °. Например, запись «45°» означает 45 градусов. (Заметим, что этим знаком обозначают не только углы, но и другие величины, например, температуру)

Наведите курсор мыши на спрайт, чтобы увидеть его поворот на обозначенный угол:

Вращение по часовой стрелке Вращение против часовой стрелки
на 45° на 90° на 45° на 90°

Задача 1 . Вращение спрайта ( 1 кук ). Заставить спрайт вращаться на месте вокруг своего центра.

Решение . В этом решении спрайт вращается по часовой стрелке:

Направление вращения легко сменить на противоположное, если заменить одну команду.
Задание 1 . Заставьте кота вращаться против часовой стрелки.
Задание 2 . Попробуйте изменить величину поворота, установив её сначала в 5, а потом в 25. Что происходит?

В белом окошке команды можно записывать число со знаком минус . Знак минус меняет направление поворота на противоположное.

Обе следующие команды будут поворачивать спрайт на 15° по часовой стрелке:

Задание 3 . Заставьте кота вращаться по часовой стрелке при помощи команды .

Задание 4 . Заставьте кота вращаться против часовой стрелки при помощи команды .

Направление спрайта

Знайка достал из кармана компас и стал определять направление, в котором летел шар.

Котёнок Мурлыка любил путешествовать. Обычно он выходил утром на крыльцо и решал, куда ему идти сегодня: на север, юг, запад или восток?

Иногда Мурлыка закладывал сложные маршруты: сначала шёл на северо-восток, потом — на юго-восток, затем — на запад, и, наконец, возвращался домой на северо-восток, мурлыкая под нос «Кукарачу» (его любимая песенка).

Однажды вечером Мурлыка познакомился с роботландским математиком Плюсиком .

Плюсик удивил Мурлыку , показав ему направления, принятые в среде Скретч :

Направления, принятые в среде Скретч . Рядом с направлением показана команда, которая устанавливает спрайт в указанном направлении Отметим, что русский вариант названия команды не точно отражает оригинал на английском языке: point in direction — установить в направлении (а не «повернуть в направлении»). В дальнейшем использование этой команды в тексте учебника будет сопровождаться пояснением её реального действия: установить в направлении ( встать в направлении )

— Мур-мяу! — сказал Мурлыка . — Раньше я шёл на юг, а теперь мне надо идти в направлении 180° . А запад, так вообще, обозначается углом со знаком минус: −90° ! А если мне надо идти на северо-восток?

— Это направление обозначается углом 45° . Ничего, Мурлыка, ты быстро привыкнешь! Чтобы тебе было проще, я подготовил рисунок с указанием направлений в среде Скретч :

Направления в среде Скретч . Когда спрайт появляется в среде, он автоматически устанавливается по направлению 90° (направление «по умолчанию»). Рядом с направлением 45° показана команда, которая устанавливает спрайт в этом направлении

Видим, что направления от положения «вверх» до положения «вниз» через «направо» задаются углами от 0° до 180° .

Направления от положения «вверх» до положения «вниз» через «налево» задаются такими же углами, но со знаком минус. (Углы 180° и −180° задают одно и то же направление «вниз».)

Вопрос . Посмотрите на эти две команды. Будут ли отличия в результатах их исполнения?

Ответ . Первая команда поворачивает спрайт вокруг его центра на 45° по часовой стрелке от текущего его направления. Вторая команда устанавливает спрайт в направлении 45° вне зависимости от текущего его положения.

Первая команды выполняет повороты , вторая устанавливает в направлении

Задача 2 . Отражение от стен. Мурлыка ( 2 кука ). Изобразить движение Мурлыки в комнате с отражением от стен из начального направления в 45° .

Решение . Мурлыку находим в библиотеке спрайтов в группе Животные . Первая команда в скрипте (после «шапочки» с указанием события) устанавливает исполнителя в направлении 45° . Затем начинается бесконечное движение с отражением от стен.

Важно : команда Идти перемещает исполнителя в текущем направлении.
Важно : отражение от стен выполняется по правилу «угол падения равен углу отражения»

По правилу «угол падения равен углу отражения» отражаются: луч света от зеркала, шарик от поверхности стола или от его стенок…

По правилу «угол падения равен углу отражения» отражаются лучи света от зеркала, шарик от поверхности теннисного стола или от бортика стола бильярдного…

Задача 3 . Отражение от стен. Мурлыка и шарик ( 2 кука ). Движение, которое совершает Мурлыка , более подходит шарику. Добавьте на сцену спрайт шарика и заставьте его двигаться вместе с Мурлыкой по тем же правилам.

Решение . Шарик находим в библиотеке спрайтов в группе Предметы . Понятно, что для шарика годится скрипт, написанный для Мурлыки . Копируем и запускаем мультик.

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

Подробнее о паспорте исполнителя

Кот кричит:
— Отдавайте посылку!
— Какие у вас документы? — говорит почтальон.
— Лапы, хвост и усы! Вот мои документы.
Но Печкина не переспоришь.
— На документах всегда печать бывает и номер. Есть у вас номер на хвосте? А усы и подделать можно. Придётся мне посылку обратно относить.

Свойства спрайта можно посмотреть и даже изменить в области Спрайты , расположенной под сценой:

В области Спрайты видим обложку паспорта для каждого спрайта

Чтобы увидеть свойства спрайта нажмите пиктограмму в левом верхнем углу обложки паспорта. Паспорт откроется:

Посмотрите, что содержит паспорт каждого исполнителя:

Вид Название Менять Пояснение Имя Нужно! Кукарача советует давать свои имена спрайтам.

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

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

  • кругом (поворот на 180°),
  • влево-вправо,
  • не вращать.

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

Свойство актуально, когда сцена разворачивается кнопкой на весь экран. Видимость Можно Если снять отметку, спрайт станет невидимым.

Рекомендуется устанавливать видимость не в паспорте, а в программе.

Сцена — это тоже исполнитель!

Неожиданно занавес открылся, и все увидели за ним сцену. На сцену вышла поэтесса Самоцветик и закричала:
— Тишина! Тишина! Сейчас будет концерт. Внимание!

— Друзья! Вы будете смеяться, но сцена в Скретч — это тоже исполнитель!

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

Задача 4 . Прогулка на авто ( 3 кука ). Автомобиль катит по дороге под весёлую музыку. Щелчок на сцене меняет сельский ландшафт на городской пейзаж. И наоборот.

Сцена/Вид . Подготовим сцену: выделим (щелчком) её паспорт, добавим два новых фона из библиотеки, начальный белый фон удалим, а для оставшихся запишем подходящие имена — село и город .

Добавить фон можно в области паспорта сцены или на вкладке Фоны

Сцена/Звуки . На вкладке Звуки загрузим для сцены (её паспорт должен быть выделен) два подходящих звука:

Звук zoop находим в разделе Эффекты , звук drive around — в разделе Музыкальная петля

Звук zoop будет реакцией на щелчок, а мелодия drive around будет звучать во всё время работы программы.

Сцена/Скрипты . Первый скрипт запускает щелчок на сцене. В нём выполняются две команды — звучит zoop (имитация щелчка) и меняется фон.

Второй скрипт запускает зелёный флажок. Сцена принимает вид село , затем в цикле бесконечно проигрывается мелодия drive around .

  1. Конструкции, которые заставляют повторять вложенные в них команды, программисты называют циклами . В Скретч одной из таких конструкцией является блок Всегда :

Этот блок заставляет бесконечно выполнять вложенные в него команды. Команды выполняются друг за другом, по порядку (не одновременно!) пока программа не будет остановлена.

Сделаем ещё одно, не менее важное, замечание.

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

Вариант 1
Команды в одном скрипте работают последовательно. Сначала играет звук (до конца), затем (когда звук закончится) меняется фон
Вариант 2
Скрипты под одинаковыми шапочками работают параллельно (одновременно)

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

Команды в одном скрипте работают последовательно , а команды в разных скриптах с работают параллельно (одновременно).

Спрайт/Вид . В библиотеке в группе Транспорт выберем картинку car bug и назовём спрайт авто . Установим спрайт на сцену и уменьшим его.

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

Спрайт/Скрипты . Составим хорошо знакомый скрипт движения влево-вправо с отталкиванием от краёв сцены:

Команды подготавливают спрайт к работе. Эти команды выполняется один раз , а потом работает бесконечный цикл.

Видео проекта можно посмотреть по адресу: video/01/unit02/Walk_on_a_car.mp4

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

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

Составив скрипт смены этих фонов, можно запрограммировать анимацию для сцены.

О важности ТЗ

— Чтобы научиться плавать, — говорит Кукарача , — надо прыгнуть в воду! А чтобы научиться создавать программы, надо программировать!

Мы полностью согласны с Кукарачей , и призываем вас не жалеть времени и усилий на выполнение проектов, то есть на «творение» программ.

Отметим, что странички с проектами содержат не только задания, но и важные рекомендации, позволяющие составлять хорошо работающие программы, такие, которыми будет доволен сам Кукарача !

Раздел с проектами этого урока особенно важен: в нём рассказано, как составлять техническое задание (ТЗ) на проект. Отнеситесь к этим рекомендациям очень внимательно.

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

— это подробное описание свойств создаваемого продукта.

ТЗ составляет человек или фирма, которые заказывают продукт ( Заказчик ). ТЗ передаётся человеку или фирме, которые создают продукт ( Исполнитель ).

ТЗ необходимо, как для Исполнителя (он создаёт продукт, руководствуясь ТЗ ), так и для Заказчика (он начинает лучше понимать, что ему нужно).

Если фирма или человек заняты разработкой новых продуктов (не на заказ), то они составляют техническое задание сами для себя — ТЗ позволяет уточнить поставленные цели, определиться со свойствами продукта, в том числе, с интерфейсом и дизайном.

В работе над Скреч -проектами вам придётся, в одних случаях создавать программный продукт, руководствуясь заданным ТЗ , в других — самим разрабатывать ТЗ , опираясь на постановку задачи и отдельные рекомендации.

— Почему ТЗ так важно? — спросил Лисёнок у своего учителя.

— Потому, — отвечал Кукарача , — что ТЗ , как математика, ум в порядок приводит и словно нить Ариадны ведёт программиста к заветному результату!

Как составлять ТЗ описано на страничке с проектами к этому уроку.

Как остановить работу скриптов

Задача 5 . Музыкальный лев ( 3 кука ). Лев живёт в пустыне и очень любит слушать музыку. Соберите программу, которая запускает 3 музыкальных эпизода по описанным ниже правилам.

Картинку фона и два «костюма» льва можно взять из библиотеки, встроенной в среду Скретч .

Эпизод Запуск Описание
Начальный Зелёный флажок и клавиша 0 Лев в 1-ом костюме, уменьшенный на половину (т. е. на 50%), слушает музыкальный фрагмент garden
Первый Клавиша 1 Лев во 2-ом костюме, в исходных размерах, слушает музыкальный фрагмент drum machine
Второй Клавиша 2 Лев в 1-ом костюме, в исходных размерах, слушает музыкальный фрагмент dance snare beat

Таким образом, при запуске программы зелёным флажком Лев слушает начальную мелодию ( garden ). Клавиши 1, 2 и 0 переключают эпизоды. На видео показано, как работает программа при цепочке нажатий: флажок–1–2–0 .

Видео проекта можно посмотреть по адресу: video/01/unit02/lion.mp4

Решение . Исполнитель будет реагировать на 4 события: флажок и клавиши 1, 2, 0. Для каждого события нужен отдельный скрипт. Запишем, что должны делать эти скрипты.

В статье рассматривается создание анимации с помощью спрайтов на HTML5 canvas в JavaScript.

Начало

Первым делом создадим элемент canvas.

Добавим бордюр (чтобы мы могли видеть нашу полезную площадь).

Функция init вызывается сразу после загрузки изображения через img.onload. Это необходимо для того, чтобы изображение было загружено, прежде чем мы попытаемся с ним работать. Весь код анимации войдет в функцию init. Для учебных целей этого урока это нормально. Если бы мы имели дело с несколькими изображениями, то, вероятно, лучше бы использовать Promises, чтобы дождаться загрузки всех изображений, прежде чем что-либо делать с ними.

Spritesheet

Теперь, когда мы настроены, давайте посмотрим на изображение.

Метод drawImage

Прежде чем мы перейдем к анимации нашего изображения, давайте посмотрим на метод drawImage, который мы будем использовать для автоматического нарезания листа спрайтов и применения его к нашему canvas.

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

Параметры «Width» и «Height» (sWidth, sHeight, dWidth и dHeight) относятся к ширине и высоте листа спрайтов и canvas, начиная с их соответствующих позиций «x» и «y». Разберем его на один секцию, скажем, на исходное изображение. Если исходные параметры (sx, sy, sWidth, sHeight) равны (10, 15, 20, 30), начальная позиция (в координатах сетки) будет (10, 15) и растянута до (30, 45). Затем конечные координаты вычисляются как (sx + sWidth, sy + sHeight).

Отрисовка первого кадра

Теперь, когда мы рассмотрели метод drawImage, давайте посмотрим на него в действии.


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

Внесем следующие изменения:

Вы должны увидеть, что изображение, нарисованное на canvas, увеличилось вдвое как по горизонтали, так и по вертикали. Изменяя значения dWidth и dHeight, мы можем масштабировать исходное изображение, чтобы оно было больше или меньше на холсте. Будьте осторожны при этом, поскольку вы имеете дело с пикселями, они могут довольно быстро начать размываться. Попробуйте изменить значение scale и посмотрите, как изменится вывод.


Следующий кадр

Чтобы нарисовать второй кадр, единственное, что нам нужно сделать, это изменить некоторые значения для исходного набора. В частности, sx и sy. Ширина и высота каждого кадра одинаковы, поэтому нам никогда не придется изменять эти значения. Фактически, давайте вытащим эти значения, создадим пару масштабированных значений и нарисуем наши следующие два кадра справа от текущего кадра.

А сейчас это выглядит так:


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

Замените все вызовы ctx.drawImage следующим образом:

Наша функция drawFrame обрабатывает математику таблицы спрайтов, поэтому нам нужно передать только номера кадров (начиная с 0, как массив, поэтому кадры «x» равны 0, 1 и 2).

Значения canvas «x» и «y» по-прежнему принимают значения пикселей, поэтому мы можем лучше контролировать позиционирование персонажа. Перемещение множителя scaledWidth внутри функции (например, scaledWidth * canvasX) будет означать, что все что перемещается изменяет масштабируемую ширину за раз. Но это не сработает с анимацией ходьбы, если, скажем, персонаж перемещается на 4 или 5 пикселей за каждый кадр. Так что оставим все как есть.

Вот что у нас есть на данный момент:


Давайте оживим этого персонажа!

Теперь мы готовы оживить нашего персонажа! Давайте посмотрим в документации MDN на requestAnimationFrame.

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

По сути, requestAnimationFrame является рекурсивной функцией. Итак чтобы создать наш цикл анимации, мы снова вызовем requestAnimationFrame из функции, которую мы передаем в качестве аргумента. Напишем что то вроде этого:

Единственный вызов перед тем, как функция walk запускает цикл, затем он постоянно вызывается внутри.

Итак, наш цикл рисования будет выглядеть примерно так: очистить, нарисовать первый кадр, очистить, нарисовать второй кадр и так далее.

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

Функция step очищает canvas, отрисовывает кадр, продвигает (или сбрасывает) нашу позицию в цикле, а затем вызывает себя через requestAnimationFrame.

И чтобы запустить анимацию, давайте обновим функцию init.

Наш персонаж начал очень быстро двигаться!😂

Притормозим его!

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

Другие направления

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

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

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

И вот оно! Наш персонаж ходит во всех четырех направлениях, и все анимировано из одного изображения.

Скачайте спрайт кружки с MEGA. И закиньте его в папку res, в директории вашего проекта.


Откройте предыдущий проект, и в resources.res, добавьте следующую строчку.

Синтаксис тут следующий

Т.е. к спрайту cup.jpg обращаемся по имени spr_cup.

Сжатие выбрали самое лучшее BEST.

Как и с изображениями, вся информация о ресурсах находится в recomp.txt, находящийся в SGDK\bin

Пишем код.

Скопируйте следующий код.

Теперь, разберем его.

Тип Sprite, как понятно из названия, хранит спрайты. Звездочка, дает понять что мы создаем указатель *, следовательно, передавать его будем по ссылке &. В данной переменной, мы будем хранить спрайт.

Создали переменные в которых будем хранить координаты спрайта.

Всегда вставляйте SPR_init, в самом начале, а уже после добавляйте спрайты SPR_addSprite.


В этой строке, мы задали цвета в 4-ой палитре (отсчет начинается с нуля), цветами взятыми из спрайта кружки.

Sega Genesis поддерживает 4 палитры по 16 цветов (PAL0-PAL3), и хранит их в CRAM.


SPR_addSprite добавляет спрайт на экран, синтаксис у него следующий.

Рассмотрим атрибуты_тайла.

  • Мы использовали 4-тую палитру, в которую чуть выше, поместили палитру взятую из спрайта кружки.
  • Приоритет максимальный.
  • По оси x, спрайт переворачивать не будем.
  • Также и по оси y.

Таким образом, мы создали спрайт, и поместили в переменную cup_obj.

Обновляет и отображает спрайты на экране.

Теперь, скомпилируйте и запустите. Должно получится следующее.


Отлично, осталось заставить эту кружку двигаться. Сделаем так, что-бы она отталкивалась от границ экрана.

Двигаем кружку.

Добавьте переменные отвечающие за скорость и размер спрайта.

В цикл while, добавьте следующий код

Спрайт постоянно перемещается с заданной скоростью.

Если он зашел за границы экрана, то меняем скорость на противоположную.

И устанавливаем позицию спрайта равным x,y.

В итоге, у нас получился отталкивающийся от стен спрайт кружки.

С помощью HTML5 элемента canvas и нескольких строк JS-кода несложно сделать спрайт-анимацию для игр или интерактивных приложений. Этим мы сегодня и займемся.

Фреймы анимации размещаются в одном изображении и выводятся по одному за раз с нужной частотой, создавая эффект движения. Разберемся шаг за шагом, как все это работает.

Что такое спрайт-анимация

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

Так как все кадры находятся в одной картинке (sprite sheet), нам потребуются возможности метода drawImage – он позволяет обрезать изображение, то есть выбирать нужный фрейм.


Спрайт

Спрайты на HTML5 холсте те же самые, что мы используем в CSS – это просто несколько разных картинок, объединенных в одном файле. Например, в этом спрайте 10 кадров. Ширина всего спрайта составляет 460 пикселей, соответственно, каждый фрейм занимает 460/10 – 46 пикселей.


Начинаем анимировать

Сначала загрузим спрайт с фреймами анимации монетки. Для этого создадим новый объект Image и установим нужное значение для его свойства src :

Теперь создадим класс спрайтов. Его объектам потребуется 4 свойства:

  • контекст для рисования;
  • ширина изображения;
  • высота изображения;
  • само изображение с фреймами.

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

Создадим реальный объект спрайт-анимации монетки с нужными параметрами:

Метод drawImage

В основе спрайт-анимации на холсте – метод drawImage . Он позволяет резать изображение как вздумается и отрисовывать нужный кусок. Этот метод принимает целую кучу параметров:

  • img – исходное изображение-спрайт;
  • sx – x-координата верхнего левого угла нужного фрейма на спрайте;
  • sy – y-координата верхнего левого угла нужного фрейма на спрайте;
  • sw – ширина фрейма;
  • sh – высота фрейма;
  • dx – x-координата точки на холсте, где начнется отрисовка фрейма (его верхний левый угол);
  • dy – y-координата точки на холсте, где начнется отрисовка фрейма;
  • dw – ширина отрисованного на холсте фрейма;
  • dh – высота отрисованного на холсте фрейма.


Таким образом, параметры, начинающиеся с s- , относятся к исходному изображению (source), а параметры, начинающиеся с d- , относятся к холсту (destination).

Метод контекста холста drawImage будет использоваться в методе render класса Sprite .

Render

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

Теперь посмотрим, что получилось.


Статичная картинка. Хм, но где анимация?

Update

Нам нужен метод, который будет обновлять позицию на спрайте, соответствующую активному фрейму. Назовем его update. Также нужно сделать несколько дополнительных настроек:

  • frameIndex – индекс активного фрейма;
  • tickCount – количество обновлений, произошедших после первого вывода текущего фрейма;
  • ticksPerFrame – количество обновлений, которые должны произойти до смены фреймов.

Можно было бы обновлять frameIndex при каждом вызове метода update , но тогда нельзя будет регулировать скорость анимации. Поэтому будем отслеживать тики обновления. Например, если игра запущена со скоростью 60 кадров в секунду, а ticksPerFrame = 4 , скорость анимации будет равна 15 кадров в секунду.

Каждый вызов метода update будет инкрементировать количество тиков обновления ( tickCount ). Если оно достигнет значения tickPerFrame , то будет сброшено, а индекс активного фрейма изменится.

Добавим еще одно свойство для класса Sprite : numberOfFrames – количество фреймов в спрайте. Метод render теперь может сдвинуть границы, отрезающие активный фрейм, на основе значения frameIndex . Поправим параметры отрисовки для метода drawImage:

Что делать, если кадры спрайта кончились? Запустить ее с самого начала:

RequestAnimationFrame

Метод requestAnimationFrame позволяет привязать перерисовку анимации к циклу обновления браузера. Его реализация в разных браузерах несколько различается, поэтому стоит пользоваться кроссбраузерным вариантом:

Создадим отдельный метод start для запуска анимации:

Уже очень близко к идеалу, осталась лишь одна маленькая деталь.

Очистка холста

Метод clearRect позволяет очистить область холста от предыдущего кадра. Он принимает 4 параметра:

Читайте также: