Иллюстрированный самоучитель по созданию Flash-игр

Платформенный скроллер

В конце функции moveFox вызываются еще три функции: moveBunnies отвечает за движение кроликов, drawObjects перерисовывает блоки, кроликов и орехи в соответствии с новым положением игрового поля относительно лисы, а функция getAcorns проверяет, не съела ли лиса какой-нибудь из орехов.

function moveFox() {
    //(1) Определяем границы возможного перемещения лисы.
    foxBounds = determineBounds(foxPos);
    //(2) Если под лисой пусто, она начинает падать.
    if ((foxBounds.bottom > 0) and (!falling))
        falling = true;
    //(3) Падение.
    if (falling)
        checkFall();
    //(4) Если нажата левая стрелка, то движемся влево, если там нет препятствия.
    if (Key.isDownfKey.LEFT)
        ) {
            if (foxSpeed < foxBounds.lef) {
                foxPos.x -= foxSpeed;
            }
            if (foxPos.x < 0)
                foxPos.x = 0;
            fox._xscale = 25;
            moving = true;
            // Если нажата правая стрелка, то движемся вправо, если там нет препятствия.
        }
    else if (Key.isDown(Key.RIGHT)) {
        if (foxSpeed < foxBounds.right) {
            foxPos.x += foxSpeed;
        }
        if (foxPos.x > worldEnd)
            foxPos.x = worldEnd;
        fox._xscale = -25;
        moving = true;
        // Если не движемся.
    }
    else {
        moving = false;
    }
    //(5) Если стоим на поверхности и нажат пробел - прыгаем,
    if (Key.isDown(Key.SPACE) and (!falling)) {
        fallSpeed = jumpPower;
        // Прыжок = падение вверх
        falling = true;
        if (Jmoving) {
            // Используем анимацию прыжка только если лиса не идет.
            fox.gotoAndPlay("jump");
        }
    }
    //(6) Если идет и не падает, то анимируем ходьбу,
    if (moving and (!falling)) {
        fox.nextFrame();
        // Если не идет или падает - кадр со стоящей лисой.
    }
    else if (imoving and (!falling)) {
        fox.gotoAndStop(1);
    }
    //(7) Позиция лисы по вертикали.
    fox._y = floor - foxPos.y;
    // Активируем кролика.
    moveBunnies();
    // Перерисовываем все объекты в соответствии с новой позицией.
    drawObjects();
    // Проверяем,не съеден ли орех.
    getAcorns();
}

Функция determineBounds выглядит сложно, но на самом деле она довольно простая. Вначале мы предполагаем, что пространство слева, справа и сверху вокруг лисы пустое на расстоянии 1000 пикселов. Также полагаем, что нет пустого пространства под лисой. Вертикальную позицию лисы мы храним в свойстве pos.у.

Далее следует цикл по всем объектам типа box. Вычисляется расстояние от лисы до блока и записывается в переменные dx и dy.

Если блок занимает то же положение по вертикали, что и лиса (другими словами – если он на том же расстоянии от земли), то функция проверяет, находится ли он справа или слева. Далее проверяется, если расстояние до блока справа (слева) меньше текущего значения bounds.right (.left), то значение bounds.right (.left) переопределяется. Аналогично проверяются вертикальные границы.

После того как все блоки были проверены, объект bounds содержит горизонтальные и вертикальные границы для лисы в текущем положении. Например, если bounds.left равно 20, то ближайший к лисе блок справа находится на расстоянии 20 пикселов.

Функция determineBounds написана в достаточно общем виде, чтобы ее можно было использовать как для лисы, так и для кроликов. В качестве аргумента pos функции можно передать как объект foxPos, так и элемент массива objects, например кролика.

function determineBounds(pos) {
    // Определяем границы перемещения.
    var bounds = {
        left: 1000,
        right: 1000,
        top: 1000,
        bottom: pos.y
    };
    // Цикл по всем объектам.
    for (var i = 0; i < objects.length; i++) {
        // Рассматриваем только блоки,
        if (objects[i].type == "box") {
            var dx = objects[i].x - pos.x;
            var dy = objects[i].y - pos.y;
            // Если блок в той же вертикальной позиции,
            if ((dy >= 0) and (dy <= 50)) {
                // Определяем, является ли ближайшим левый блок,
                if ((dx + 50 <= 0) and (Math.abs(dx + 50) < bounds.left)) {
                    bounds.left = Math.abs(dx + 50);
                    // Определяем, является ли ближайшим правый блок.
                }
                else if ((dx >= 0) and (dx < bounds.right)) {
                    bounds.right = dx - 50;
                }
            }
            // Блок в той же горизонтальной позиции,
            if ((dx >= -50) and (dx <= 50)) {
                // Определяем, является ли ближайшим нижний блок.
                if ((dy + 50 <= 0) and (Math.abs(dy + 50) <= bounds.bottom)) {
                    bounds.bottom = Math.abs(dy + 50);
                    // Определяем, является ли ближайшим верхний блок.
                }
                else if ((dy - 50 >= 0) and (dy - 50 < bounds.top)) {
                    bounds.top = dy - 50;
                }
            }
        }
    }
    return(bounds);
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.