如何使用动画实现纸娃娃效果?

3
对于使用Canvas和Javascript的2D俯视角游戏(类似塞尔达加RPG),如何实现 paper-dolling 并同时允许动画呢?
使用 sprite-sheet 实现动画相对简单,但是将 paper-dolling 添加进去(即能够 "装备" 物品和护甲,并在人物身上 显示这些物品)似乎不是一项轻松且非重复性的任务。
例如,想象一下一个角色挥舞剑的动画。使用简单的 sprite-sheet 即可实现动画。但是如果你希望在不同的剑装备时动画中的剑实际上改变怎么办?需要创建附加的 sprite 来重复包含相同的动画帧,为每个物品都做一遍吗?还要为每个 NPC 都做一遍吗?(假设我想让NPC也拥有paper-dolling而不仅仅是角色) 可能可以这样做,只需保持最少量的可穿戴物品以限制所需的精灵动画帧数。
我认为可以将角色动画与剑/物品动画分离,然后在角色动画之上/之下添加剑/物品动画。这样,不同的角色可以重用相同的物品动画,将其与其角色动画匹配。但是,每个物品仍需要大量的精灵动画帧,并且角色必须相似。
有什么想法或建议吗?
(如果重要的话,我计划使NPC没有任何paper-dolling,并且让玩家拥有角色动画+每种物品的动画。对于护甲来说,它将与玩家的身形和尺寸匹配。)

每个肢体可能都有一个空间点和一个角度,除此之外,希望你能享受数学! - dansch
1个回答

0
我在考虑为每个可穿戴物品集合创建一个物品数组,你可以将这些物品放在玩家身上,例如:
var AwesomeDragonProofDiamondArmour =
{
    head: 'awesome-diamond-helmet.png',
    chest: 'awesome-diamond-chest.png',
    legs: 'awesome-diamond-legs.png',
    boots: 'awesome-diamond-boots.png'
};

在您的玩家设置中,您将拥有相同的数组;当然,在许多RPG游戏中,您不会从一个完整的神奇钻石盔甲开始,而是从皮革和可能是一种好的胸甲开始。
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,宽度,高度]。这种方法的缺点是只有一个尺寸,因此除非您的角色都是相同大小的(在基于平铺的RPG中实际上很可能),否则为每个角色大小制作所有图形可能需要耗费很多时间。
另一种方法是使用画布绘图函数绘制图形,在其中可以指定头盔的x / y / width / height,然后以任何您希望的大小绘制头盔。 就像这样:
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 对于宽度为奇数的线条是必要的 - 请参见此线程

无论如何,这将根据您希望在每个字符上显示多少项而耗费时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接