{lang: ‘ru’}

уроки html5, html5 canvas, html5 примеры, html5 игрыСегодня мы продолжаем серию статей о разработке игр в HTML5 с использованием canvas. В этот раз мы будем изучать анимацию спрайтов и работу со звуком. В демке вы можете увидеть летающего дракона. Звук крыльев будет слышен все время (звук будет зациклен), а другой звук — рёв дракона (по событию MouseUp). И, наконец, мы научим нашего дракона приближаться к мыши (при удерживании кнопки мыши).

Наши предыдущие статьи вы можете прочитать здесь: Урок 3. За основу мы берем скрипт сделанный на прошлом уроке и будем его улучшать.

Demo  Исходники

Step 1. HTML

index.html

<!DOCTYPE html>
<html lang="ru" >
    <head>
        <meta charset="utf-8" />
        <title>Разработка игр на HTML5 — Урок 4 | officialplat-tt.ru</title>

        <link href="css/main.css" rel="stylesheet" type="text/css" />

        <!--[if lt IE 9]>
          <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script type="text/javascript" src="js/script.js"></script>
    </head>
    <body>
        <div class="container">
            <canvas id="scene" width="1000" height="600"></canvas>
        </div>

        <footer>
            <h2>Разработка игр на HTML5 — Урок 4</h2>
            <a href="http://officialplat-tt.ru/?p=1655" class="stuts">Вернуться на <span>officialplat-tt.ru</span></a>
        </footer>
    </body>
</html>

Шаг 2. CSS

css/main.css

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

Шаг 3. JS

js/script.js

// внутренние переменные
var canvas, ctx;
var backgroundImage;
var iBgShiftX = 100;
var dragon;
var dragonW = 75; // ширина дракона
var dragonH = 70; // высота дракона
var iSprPos = 0; // инициализация спрайтов
var iSprDir = 4; // начальное направление дракона
var dragonSound; // звук рёв дракона
var wingsSound; // звук крыльев
var bMouseDown = false; // состояние мыши
var iLastMouseX = 0;
var iLastMouseY = 0;
// -------------------------------------------------------------

// объекты :
function Dragon(x, y, w, h, image) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.image = image;
    this.bDrag = false;
}
// -------------------------------------------------------------

// функции отрисовки :
function clear() { // функция очистки canvas
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}

function drawScene() { // главная функция отрисовки
    clear(); // очистить canvas

    // отрисовка фона
    iBgShiftX -= 4;
    if (iBgShiftX <= 0) {
        iBgShiftX = 1045;
    }
    ctx.drawImage(backgroundImage, 0 + iBgShiftX, 0, 1000, 940, 0, 0, 1000, 600);

    // обновление позиций спрайтов
    iSprPos++;
    if (iSprPos >= 9) {
        iSprPos = 0;
    }

    // перемещение дракона к месту нажатия мыши
    if (bMouseDown) {
        if (iLastMouseX > dragon.x) {
            dragon.x += 5;
        }
        if (iLastMouseY > dragon.y) {
            dragon.y += 5;
        }
        if (iLastMouseX < dragon.x) {
            dragon.x -= 5;
        }
        if (iLastMouseY < dragon.y) {
            dragon.y -= 5;
        }
    }

    // отрисовка дракона
    ctx.drawImage(dragon.image, iSprPos*dragon.w, iSprDir*dragon.h, dragon.w, dragon.h, dragon.x - dragon.w/2, dragon.y - dragon.h/2, dragon.w, dragon.h);
}

// -------------------------------------------------------------

// инициализация
$(function(){
    canvas = document.getElementById('scene');
    ctx = canvas.getContext('2d');

    var width = canvas.width;
    var height = canvas.height;

    // загрузка фонового изображения
    backgroundImage = new Image();
    backgroundImage.src = 'images/hell.jpg';
    backgroundImage.onload = function() {
    }
    backgroundImage.onerror = function() {
        console.log('Error loading the background image.');
    }

    // инициализация звука 'Рёв дракона'
    dragonSound = new Audio('media/dragon.wav');
    dragonSound.volume = 0.9;

    // инициализация звука 'Крылья'
    wingsSound = new Audio('media/wings.wav');
    wingsSound.volume = 0.9;
    wingsSound.addEventListener('ended', function() { // проигрывание звука крыльев
        this.currentTime = 0;
        this.play();
    }, false);
    wingsSound.play();

    // инициализация дракона
    var oDragonImage = new Image();
    oDragonImage.src = 'images/dragon.gif';
    oDragonImage.onload = function() {
    }
    dragon = new Dragon(400, 300, dragonW, dragonH, oDragonImage);

    $('#scene').mousedown(function(e) { // привязываем событие нажатия мыши(для перетаскивания)
        var mouseX = e.layerX || 0;
        var mouseY = e.layerY || 0;
        if(e.originalEvent.layerX) { // изменения jquery 1.7
            mouseX = e.originalEvent.layerX;
            mouseY = e.originalEvent.layerY;
        }

        bMouseDown = true;

        if (mouseX > dragon.x- dragon.w/2 && mouseX < dragon.x- dragon.w/2 +dragon.w &&
            mouseY > dragon.y- dragon.h/2 && mouseY < dragon.y-dragon.h/2 +dragon.h) {

            dragon.bDrag = true;
            dragon.x = mouseX;
            dragon.y = mouseY;
        }
    });

    $('#scene').mousemove(function(e) { // привязываем событие движения мыши
        var mouseX = e.layerX || 0;
        var mouseY = e.layerY || 0;
        if(e.originalEvent.layerX) { // изменения jquery 1.7
            mouseX = e.originalEvent.layerX;
            mouseY = e.originalEvent.layerY;
        }

        // сохраняем последние координаты
        iLastMouseX = mouseX;
        iLastMouseY = mouseY;

        // перетаскиваем дракона
        if (dragon.bDrag) {
            dragon.x = mouseX;
            dragon.y = mouseY;
        }

        // изменить направление дракона (в зависимости от положения курсора мыши)
        if (mouseX > dragon.x && Math.abs(mouseY-dragon.y) < dragon.w/2) {
            iSprDir = 0;
        } else if (mouseX < dragon.x && Math.abs(mouseY-dragon.y) < dragon.w/2) {
            iSprDir = 4;
        } else if (mouseY > dragon.y && Math.abs(mouseX-dragon.x) < dragon.h/2) {
            iSprDir = 2;
        } else if (mouseY < dragon.y && Math.abs(mouseX-dragon.x) < dragon.h/2) {
            iSprDir = 6;
        } else if (mouseY < dragon.y && mouseX < dragon.x) {
            iSprDir = 5;
        } else if (mouseY < dragon.y && mouseX > dragon.x) {
            iSprDir = 7;
        } else if (mouseY > dragon.y && mouseX < dragon.x) {
            iSprDir = 3;
        } else if (mouseY > dragon.y && mouseX > dragon.x) {
            iSprDir = 1;
        }
    });

    $('#scene').mouseup(function(e) { // привязываем событие отжатия мыши
        dragon.bDrag = false;
        bMouseDown = false;

        // проигрываем звук рёва дракона
        dragonSound.currentTime = 0;
        dragonSound.play();
    });

    setInterval(drawScene, 30); // отрисовка сцены с заданным интервалом
});

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

1. Зацикленный фоновый звук

// инициализация звука 'Крылья'
    wingsSound = new Audio('media/wings.wav');
    wingsSound.volume = 0.9;
    wingsSound.addEventListener('ended', function() { // проигрывание звука крыльев
        this.currentTime = 0;
        this.play();
    }, false);
    wingsSound.play();

2. Отрисовка спрайтов

    var oDragonImage = new Image();
    oDragonImage.src = 'images/dragon.gif';
    oDragonImage.onload = function() {
    }
....
    // обновление позиций спрайтов
    iSprPos++;
    if (iSprPos >= 9) {
        iSprPos = 0;
    }

    // отрисовка дракона
    ctx.drawImage(dragon.image, iSprPos*dragon.w, iSprDir*dragon.h, dragon.w, dragon.h, dragon.x - dragon.w/2, dragon.y - dragon.h/2, dragon.w, dragon.h);

Сначала мы загружаем все изображение полностью, после чего рисуем только его часть в цикле.

Шаг 4. Дополнительные файлы

images/dragon.gif, images/hell.jpg, media/dragon.wav and media/wings.wav

Все файлы есть в исходниках.

Demo Исходники



Понравился ли Вам наш новый ручной дракон? :) Я буду рад, если вы поделитесь ссылкой на урок с друзьями и оставите комментарии. Удачи!


Получайте новые статьи блога прямо себе на почту