Как реализовать бумажную куклу с анимацией?

Для 2D-игры с видом сверху (например, Zelda + RPG), использующей Canvas и Javascript, как лучше всего реализовать бумажную куклу, допуская при этом анимацию?

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

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

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

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

Любые мысли или предложения?

(Если это имеет значение, я думаю, что я планирую сделать NPC без каких-либо бумажных кукол, а у игрока будет анимация персонажа + анимация для каждого варианта предметов. Что касается брони, она будет соответствовать фигуре и размерам игрока. .)


person Curtis La Graff    schedule 15.09.2012    source источник
comment
каждая конечность, вероятно, будет иметь точку в пространстве и угол, помимо этого, я надеюсь, вам понравится математика!   -  person Funkodebat    schedule 16.11.2012


Ответы (1)


Я думаю, что для каждого носимого набора предметов у вас будет набор предметов, которые вы могли бы надеть на игрока, например:

var AwesomeDragonProofDiamondArmour =
{
    head: 'awesome-diamond-helmet.png',
    chest: 'awesome-diamond-chest.png',
    legs: 'awesome-diamond-legs.png',
    boots: 'awesome-diamond-boots.png'
};

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

var RubbishLeatherArmour =
{
    head:   'rubbish-leather-helmet.png',
    chest:  'rubbish-leather-chest.png',
    legs:   'rubbish-leather-legs.png',
    boots:  'rubbish-leather-boots.png'
};

var SortOfGoodSteelArmour =
{
    head:   'sort-of-good-steel-helmet.png',
    chest:  'sort-of-good-steel-chest.png',
    legs:   'sort-of-good-steel-legs.png',
    boots:  'sort-of-good-steel-boots.png'
};

var Player =
{
    head:   RubbishLeatherArmour.head,
    chest:  SortOfGoodSteelArmour.chest,
    legs:   RubbishLeatherArmour.legs,
    boots:  RubbishLeatherArmour.boots
}

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

var RobustMetalArmour = 
{
    head: [120, 120, 20, 20],
    chest: [140, 120, 20, 20],
    legs: [160, 120, 20, 30],
    boots: [180, 120, 20, 10]
}

Где массив [x, y, ширина, высота]. Недостаток этого заключается в том, что он имеет только один размер, поэтому, если ваши персонажи не имеют одинакового размера (что на самом деле вполне возможно в ролевой игре, основанной на тайлах), может потребоваться много времени для создания всей графики для каждого размера персонажа.

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

function drawPlus(ctx, x, y, size, colour)
{
    ctx.lineWidth = 1;
    ctx.strokeStyle = colour;
    ctx.beginPath();
    ctx.moveTo(x + 0.5, y + 0.5 - size);
    ctx.lineTo(x + 0.5, 0.5 + y);
    ctx.lineTo(x + 0.5 + size, 0.5 + y);
    ctx.moveTo(x + 0.5 - size, y + 0.5);
    ctx.lineTo(x + 0.5, 0.5 + y);
    ctx.lineTo(x + 0.5, 0.5 + y + size);
    ctx.stroke();
    ctx.closePath();
}

Вышеупомянутая функция рисует + на экране. 0,5 необходимо для линий нечетной ширины - см. эту тему.

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

person Ben    schedule 20.01.2013