HTML5 игры: canvas

Если вы хотите написать казуальную игру с помощью элемента HTML5 Canvas, вам нужно найти способ справиться со спрайтами. Есть несколько библиотек, которые помогут вам в написании игры, такие как  ImpactJS CraftyJS  и так далее. В этой статье используется EaselJS , который применили для написания  Pirates Love Daisies  : это HTML5 игра. Эта удивительная библиотека работает во всех современных браузерах с поддержкой HTML5.

Например, если вы работаете в  Windows 8 , вы можете установить игру Pirates Love Daisies в магазине Windows здесь:  Pirates Love Daisies для Windows 8

В этой статье мы увидим , как использовать существующие элементы спрайта и анимировать их .

Эта статья является первой из 3-х:

— HTML5 игры: анимации спрайтов в canvas с EaselJS
— HTML5 игры: создание основных объектов и обработки столкнувшись в EaselJS
— HTML5 Platformer: полный порт игры на XNA <canvas> с EaselJS

Введение

На официальном сайте  EaselJS , вы сможете найти некоторые интересные образцы и некоторые  основные документы . Мы будем использовать спрайты  образца в качестве базы. Мы будем использовать также ресурсы, имеющиеся в  образце XNA 4,0 платформер .

Платформер был обновлен в то же время команда XNA и для Xbox 360, PC и Windows Phone 7  App Hub — платформер . Вы можете скачать его и извлекать спрайты использовать их вместе с EaselJS.

В этой статье мы будем использовать эти 2 PNG файла в качестве источника нашего последовательного спрайта :

Монстр:

Игры HTML5 canvas

, который содержит  10  различных спрайтов.

Монстр в режиме ожидания:

Игры HTML5 canvas

, который содержит  11  различных спрайтов.

 Следующие образцы были успешно опробованы в IE9/IE9 Mobile/IE10 PP5/Chrome 17 и Firefox 11. Это не работает в опере в связи с ошибкой в коренной реализации изображение:  О проблеме в опере

Строительство SpriteSheet и BitmapAnimation

Мы начнем работу с перемещения монстра между началом и концом ширины нашего canvas.

Первый шаг заключается в загрузке полной последовательности, содержащиеся в файле PNG с помощью этого кода:



var imgMonsterARun = new Image();

    function init() {
    //find canvas and load images, wait for last image to load
    canvas = document.getElementById("testCanvas");

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = "img/MonsterARun.png";
    }


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



// create spritesheet and assign the associated data.
var spriteSheet = new SpriteSheet({
    // image to use
    images: [imgMonsterARun],
    // width, height & registration point of each sprite
    frames: {width: 64, height: 64, regX: 32, regY: 32},
    animations: {
        walk: [0, 9, "walk"]
    }
});


Мы хотели бы создать новую последовательность под названием «walk», которая будет состоять из изображения imgMonsterARun . Этот образ будет разделен на 10 кадров размером 64×64 пикселей. Это основной объект загрузки наши спрайты и создать последовательность. Там может быть несколько последовательностей созданы из того же файла PNG, если вы хотите, как в примере спрайтов на сайте EaselJS.

После этого мы должны использовать объект  BitmapAnimation . Это помогает нам в анимации нашей последовательности и позиционировании наших спрайтов на экране. Давайте рассмотрим код инициализации этого BitmapAnimation:



// create a BitmapAnimation instance to display and play back the sprite sheet:
    bmpAnimation = new BitmapAnimation(spriteSheet);

    // start playing the first sequence:
    bmpAnimation.gotoAndPlay("walk");     //animate

    // set up a shadow. Note that shadows are ridiculously expensive. You could display hundreds
    // of animated rats if you disabled the shadow.
    bmpAnimation.shadow = new Shadow("#454", 0, 5, 4);

    bmpAnimation.name = "monster1";
    bmpAnimation.direction = 90;
    bmpAnimation.vX = 4;
    bmpAnimation.x = 16;
    bmpAnimation.y = 32;

    // have each monster start at a specific frame
    bmpAnimation.currentFrame = 0;
    stage.addChild(bmpAnimation);


Конструктор объекта BitmapAnimation  просто необходимый элемент SpriteSheet в качестве параметра. Затем мы даём имя последовательности, установим некоторые параметры, такие как скорость и начальная позиция нашего первого кадра. Наконец, мы добавляем эту последовательность в список отображения с помощью  Этапа  объекта и его метод AddChild ().

Следующий наш шаг состоит в решении, что бы мы хотели сделать в нашем цикле анимации. Этот цикл анимации вызывается каждые ххх миллисекунды и позволяет обновить позицию вашего спрайта. Для этого EaselJS предоставляет объект  Ticker , который обеспечивает централизованный тик или сердцебиение вещание на заданный интервал времени. Если вы хотите, исходный код Ticker.js, вы увидите, что объект Ticker EaselJS 0,4 поддерживает requestAnimationFrame() :



var f = window.requestAnimationFrame
  || window.webkitRequestAnimationFrame
  || window.mozRequestAnimationFrame
  ||
                window.oRequestAnimationFrame
                || window.msRequestAnimationFrame;


Благодаря этому коду, IE10, Firefox, Chrome поддерживает и будущие версии оперы тоже. Но он не используется по умолчанию, EaselJS. Вероятно, из соображений совместимости, я думаю.

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

Ладно, все, что вам надо сделать сейчас, чтобы подписаться на tick событий и реализации. Метод tick() , который будет вызван. Этот код, например, регистрирует события на глобальный объект окна:



Ticker.addListener(window);
    Ticker.useRAF = true;
    // Best Framerate targeted (60 FPS)
    Ticker.setInterval(17);


А вот код, который будет вызываться каждый 17ms (в идеале), чтобы обновить положение нашего монстра:



function tick() {
    // Hit testing the screen width, otherwise our sprite would disappear
    if (bmpAnimation.x >= screen_width - 16) {
        // We've reached the right side of our screen
        // We need to walk left now to go back to our initial position
        bmpAnimation.direction = -90;
    }

    if (bmpAnimation.x < 16) {
        // We've reached the left side of our screen
        // We need to walk right now
        bmpAnimation.direction = 90;
    }

    // Moving the sprite based on the direction & the speed
    if (bmpAnimation.direction == 90) {
        bmpAnimation.x += bmpAnimation.vX;
    }
    else {
        bmpAnimation.x -= bmpAnimation.vX;
    }

    // update the stage:
    stage.update();
}


Смотрите конечный результат:

Вы также можете просмотреть этот пример здесь:  easelJSSpritesTutorial01  если вы хотите, увидеть полный исходный код.

Но постойте! Есть 2 проблемы в этой анимации:

1 — Странные шаги анимации, кажется, цикл персонажа через различные последовательности спрайты слишком быстро,
2 — Персонаж может нормально ходить справа налево по другому, похоже, что он пытается танцевать Гопака.

Давайте посмотрим, как это исправить.

Контроль скорости анимации

Чтобы исправить скорость анимации, самый простой способ заключается в изменении  frequency ( частоты)  параметров  animations (анимации)  объекта вашего SpriteSheet объект как немного написано в документации:  SpriteSheet . Вот новый код для создания SpriteSheet:



var spriteSheetIdle = new SpriteSheet({
    images: [imgMonsterAIdle],
    frames: { width: 64, height: 64, regX: 32, regY: 32 },
    animations: {
        idle: [0, 10, "idle", 4]
    }
});


Вам необходимо также замедлить скорость за счет изменения  уХ от 4 до 1  (логически делится на 4).

Для добавления новых кадров анимации, для нормальной ходьбы слева направо, мы должны перевернуть каждый кадр. EaselJS предоставляет объект  SpriteSheetUtils  , как и метод addFlippedFrames ()   вы найдете в  документах . Вот пример кода, который использует это:



SpriteSheetUtils.addFlippedFrames(spriteSheet, true, false, false);


Мы создаем производную последовательность, которая будет называться »  walk_h  » , основанный на «walk» последовательность, что бы листать горизонтально. Наконец, вот код, который обрабатывает в какой последовательности мы должны проигрывать по характеру положения:



function tick() {
    // Hit testing the screen width, otherwise our sprite would disappear
    if (bmpAnimation.x >= screen_width - 16) {
        // We've reached the right side of our screen
        // We need to walk left now to go back to our initial position
        bmpAnimation.direction = -90;
        bmpAnimation.gotoAndPlay("walk")
    }

    if (bmpAnimation.x < 16) {
        // We've reached the left side of our screen
        // We need to walk right now
        bmpAnimation.direction = 90;
        bmpAnimation.gotoAndPlay("walk_h");
    }

    // Moving the sprite based on the direction & the speed
    if (bmpAnimation.direction == 90) {
        bmpAnimation.x += bmpAnimation.vX;
    }
    else {
        bmpAnimation.x -= bmpAnimation.vX;
    }

    // update the stage:
    stage.update();
}


Смотрите конечный результат:

Вы также можете просмотреть этот пример здесь:  easelJSSpritesTutorial02  если вы хотите просмотреть полный исходный код.

Загрузка нескольких спрайтов и проигрывание с несколькими анимациями

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

Затем мы загрузим несколько файлов PNG с веб-сервера. Это очень важно, ждём, пока все ресурсы загрузятся или вы можете попробовать сделать самому. Вот очень простой способ сделать это:



var numberOfImagesLoaded = 0;

    var imgMonsterARun = new Image();
    var imgMonsterAIdle = new Image();

    function init() {
    //find canvas and load images, wait for last image to load
    canvas = document.getElementById("testCanvas");

    imgMonsterARun.onload = handleImageLoad;
    imgMonsterARun.onerror = handleImageError;
    imgMonsterARun.src = "img/MonsterARun.png";

    imgMonsterAIdle.onload = handleImageLoad;
    imgMonsterAIdle.onerror = handleImageError;
    imgMonsterAIdle.src = "img/MonsterAIdle.png";
    }

    function handleImageLoad(e) {
    numberOfImagesLoaded++;

    // We're not starting the game until all images are loaded
    // Otherwise, you may start to draw without the resource and raise
    // this DOM Exception: INVALID_STATE_ERR (11) on the drawImage method
    if (numberOfImagesLoaded == 2) {
    numberOfImagesLoaded = 0;
    startGame();
    }
    }


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

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



// Idle sequence of the monster
    var spriteSheetIdle = new SpriteSheet({
    images: [imgMonsterAIdle],
    frames: { width: 64, height: 64, regX: 32, regY: 32 },
    animations: {
    idle: [0, 10, "idle", 4]
    }
    });

    bmpAnimationIdle = new BitmapAnimation(spriteSheetIdle);

    bmpAnimationIdle.name = "monsteridle1";
    bmpAnimationIdle.x = 16;
    bmpAnimationIdle.y = 32;


Теперь, в методе tick(), мы должны остановить анимацию ходьбы, как только мы достигли возвращение в левой части экрана, и проиграть в простой анимации. Вот код, который делает, это:



if (bmpAnimation.x < 16) {
    // We've reached the left side of our screen
    // We need to walk right now
    bmpAnimation.direction = 90;
    bmpAnimation.gotoAndStop("walk");
    stage.removeChild(bmpAnimation);
    bmpAnimationIdle.gotoAndPlay("idle");
    stage.addChild(bmpAnimationIdle);
}


Смотрите конечный результат:

Вы также можете просмотреть этот пример здесь:  easelJSSpritesTutorial03  если вы хотите увидеть полный исходный код.

 этот учебник первоначально был написан для  EaselJS 0.3.2  в июле 2010 года и был обновлен на  EaselJS 0,4 . Для тех из вас, кто читает версию 0.3.2, вот основные изменения в этом уроке, чтобы быть в курсе:

  1. BitmapSequence больше не доступен в 0,4 и был заменен BitmapAnimation
  2. Теперь вы можете замедлить анимацию цикла спрайты изначально при строительстве объекта SpriteSheet
  3. EaselJS 0.4 теперь использует requestAnimationFrame для более эффективной анимации поддерживаемых браузеров (например, ИЕ10 +, Firefox 4.0 + и Chrome с помощью префиксов соответствующих производителей).

Название статьи: HTML5 игры: анимации спрайтов в canvas с EaselJS

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML -теги и атрибуты: <a href= http://pixelcom.crimea.ua/"" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>