Cocos2D Skeletal Animation : Part 1

文章详细介绍了游戏开发中使用Cocos2D环境进行2D角色动画实现的过程,包括使用TDAnimEngine创建2D角色并转换为Cocos2D节点的方法,以及遇到的问题和解决方案。此外,还分享了Demina工具的使用体验,并对比了不同骨骼动画工具的选择,最终选择了能够满足需求的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Our game Pablo and the Puppet Punch needed a lot of animations to play on screen at once along with an inverse kinematic implementation and a whole lot of VFX. We looked for options for implementing Skeletal Animations in our game. Skeletal Animation is one of the best ways to optimize the total size of your game for mobile devices such as iPhone and iPad.

For understanding what skeletal animation is and how it can help you, read this blog

This implementation is in C#; but unfortunately he did not share the exporter he used for converting flash animations to XML that can be read in code.

No point being sad, we continued our search for different skeletal animation tools which could help us. Another promising breakthrough was “Demina”. Again, a C# implementation based on bone structure, it looked promising at first sight as it had a good UI for getting your animation in place. The only concern is that you need a “mouse” as the control to move a bone is through middle mouse button. Not a difficult requirement though! But since you have the source, you can quickly change this input control and make it an easy drive for games created in XNA etc.

Interface of Demina

But we needed something that could serve our Cocos2D environment. We got through this tutorial on Cocos2D forum called TDAnimEngine which creates 2D characters in Maya and converts it into Cocos2D nodes. Maya sounded a little threatening but still we took a chance but there were many faults in the implementation of given source and none of us being an expert in mel script, it became a headache for us to get this thing working.

TDAnimEngine Implementation in Maya

If you want to try, download this version as a lot of things have been fixed in this one. Still there were some bugs in positioning the character, and Haykhelped me figure that out.  At first please make sure to build your necessary object using simple planes and add as textures your PNG files which you’re going to use in your iOS project. This is his changed version of MayaToCocos2DNodes.mel file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
string $master = "Body";
string $sel[] = `ls -selection`;
 
// Master position
float $originalPos[] = `xform -ws -q -t ($master)`;
 
string $children[] = `ls -selection`;
print ("<root>\n<nodesConfig>\n");
 
$mat = getSurfaceShader($master);
$fileText = getTextureFromMaterial($mat);
$fileName = filepart(`getAttr ($fileText+".fileTextureName")`);
 
float $width = `getAttr ($fileText+".outSizeX")`/100;
float $height = `getAttr ($fileText+".outSizeY")`/100;
 
float $ppoint[] = `xform -q -t ($master+".rotatePivot")`;
float $px = $ppoint[0];
float $py = $ppoint[1];
 
float $apX = ($width/2+$px)/$width;
float $apY = ($height/2+$py)/$height;
float $rot[] = `getAttr ($master+".r")`;
float $scl[] = `getAttr ($master+".s")`;
 
print ("\t<node id='"+$master+"' parent='root' x='"+$originalPos[0]+"'
y='"+$originalPos[1]+"' image='"+$fileName+"' apx='"+$apX+"' apy='"+$apY+"' rz='"+$rot[2]+"' sx='"+$scl[0]+"' sy='"+$scl[1]+"' w='"+$width+"' h='"+$height+"' />\n");
 
$parentnode = $master;
 
for ($o = 0; $o < `size $children`; $o++)
{
if ($children[$o] != $master)
{
 
// -------------------------------------------------------------
// GET POSITION
 
string $parent[] = `listRelatives -p ($children[$o])`;
float $pos[] = `getAttr ($children[$o]+".t")`;
float $rot[] = `getAttr ($children[$o]+".r")`;
float $scl[] = `getAttr ($children[$o]+".s")`;
 
// -------------------------------------------------------------
// GET ANCHOR POINT
 
float $ppoint[] = `xform -q -ws -t ($children[$o]+".rotatePivot")`;
float $px = $ppoint[0];
float $py = $ppoint[1];
 
$mat = getSurfaceShader($children[$o]);
 
$fileText = getTextureFromMaterial($mat);
$fileName = filepart(`getAttr ($fileText+".fileTextureName")`);
 
//print ("\n"+$children[$o]+"\n"+$px + "\n" + $py);
// -------------------------------------------------------------
// OUTPUT
 
print ("\t<node id='"+$children[$o]+"' parent='"+$parent[0]+"' image='"+$fileName+"' x='"+$pos[0]+"' y='"+$pos[1]+"' z='"+$pos[2]+"' rz='"+$rot[2]+"' sx='"+$scl[0]+"' sy='"+$scl[2]+"' apx='"+$px+"' apy='"+$py+"' />\n");
}
}
print ("</nodesConfig>\n</root>");
 
// HELPER METHODS -------------------------------------------------------------------
 
proc string getSurfaceShader (string $objName)
{
 
string $myShapeNode[] = `listRelatives -children -shapes $objName`;
string $mySGs[] = `listConnections -type shadingEngine $myShapeNode[0]`;
string $surfaceShader[] = `listConnections ($mySGs[0] + ".surfaceShader")`;
return $surfaceShader[0];
}
 
proc string rootNode( string $object )
{
 
string $buffer[];
tokenize $object "." $buffer;
return $buffer[0];
}
 
proc string getTextureFromMaterial( string $material )
{
 
string $texture = "";
string $class[] = getClassification( `nodeType $material` );
if ( "shader/surface" == $class[0] && `connectionInfo -id
( $material + ".color" )` )
{
$texture = rootNode( `connectionInfo -sfd ( $material + ".color" )` );
}
return $texture;
}
 
global proc string filepart( string $path )
// Extracts the path portion of an absolute filepath.
// Input: e.g. "D:/projects/default/scenes/myScene.mb"
// Result: e.g. "myScene.mb"
//
// Filepath can be delimited with
// either slash ("/" or "\")
{
string $filepart = match( "[^/\\]*$", $path );
 
return $filepart;
};

We did not try this but we are sharing this as it may be of use to someone who needs a solution.

Also , In getTextureFromMaterial function value of $class[0] is “drawdb/shader/surface/lambert:shader/surface” instead of “shader/surface”.

Once you make these changes it should work for you. If it doesn’t , don’t get disappointed and keep reading .

Along with this solution, we came across an excellent tool called grapefrukt exporter.( Hayk suggested it! ) I call it excellent as it finally solved all our troubles though it was a little difficult to start with. And the most important benefit was it uses Flash and not Maya.

Below we want to share with you quickly how you can set up grapefrukt exporter and convert the XML data it generates into cocos2D nodes. You can watch this video made by the developer of this exporter to have a quick idea of what grapefrukt can do for you. To read the tutorial on how to exactly use grapefrukt, read the second part of this series here.

If you any other awesome tools for skeletal animation, please share the links in comments below. We hope this will be of use to young developers like us.

Signing off,

Team MechMocha

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值