Cocos2dx-lua's spine partial dress up step

Source: Internet
Author: User
Tags addchild lua strcmp

Before writing an article about Cocos2dx-lua's spine local dress up. The main principle is to add the Addskin () method according to the Setskin () method in the SpineRenderer.cpp in COCOS2DX. And in

Add method int Lua_cocos2dx_spine_skeletonrenderer_addskin (la_state* tolua_S) in Lua_cocos2dx_spine_auto.cpp, Complete the lua-building so that it can be invoked at the Lua end.

Previous address: http://blog.csdn.net/u010536615/article/details/51137235

The reasons for writing in the order are:

Spine animation When there is a key frame of things, the general animation when the first frame will be all the relevant components (slots) key on the keyframe. However, we did not animate the key on the keyframe, so the previous Addskin () method has no problem. However, after the key frame key, the Addskin () method is not used, although there is no problem with the method implementation. So the spine from parsing to the animation of the implementation of the code are read again. Enables the method to support local dress up after keyframes on key.

The solution looks directly at the title 3.

---------------------------------------------------------------1. Dress principle--------------------------------------------

Replace the attachment part in the slots slot.

Find the attachment part that corresponds to the slots, and then traverse the skins to see if there is a attachment part in the current skin, and if so, replace the part in the slots part of the original attachment.


---------------------------------------------------------------2. The cause of the problem--------------------------------------------

The reason:

Self.actor = sp. Skeletonanimation:create ("Red/red.json", "Red/red.atlas", 1)
Self.actor:setAnimation (0, "red_wait", True)
Self.actor:setPosition (450, 300)
Self:addchild (Self.actor)

In fact, only create, do not drop animation self.actor:setAnimation (0, "red_wait", True), Addskin () method is useful.

So the problem is when you play the animation. When the animation is played, the attachment in slots is replaced with the current skin. So the Addskin () that was previously set is replaced, and the animation doesn't work when it moves.

--The Setskin () of the engine belt works:

So why Setskin () is useful. That's the point.

Also said before, the replacement is to find the current settings of the skin. And the logic of the engine can only set the overall skin, that is, the whole outfit. Does not provide the ability to set a single part skin.

The Setskin method passes

Const_cast (spskin*, Self->skin) = Newskin;

To set the current overall equipment.

Replace each part with the current skin:

if (Self->skin) {

Spattachment *attachment =spskin_getattachment (Self->skin, Slotindex, AttachmentName);

if (attachment) return attachment;

}

if (Self->data->defaultskin) {

Spattachment *attachment =spskin_getattachment (Self->data->defaultskin, Slotindex, attachmentName);

if (attachment) return attachment;

}

So what we need to do is add the skin attribute to each slot.

When replacing, find out if the current part has skin, and some words apply the part's skin. Instead of the whole skin.


--------------------------------------3. Solution--------------------------------------------

1. Add skin attributes to each slot

Add the Spskin*const skin attribute to the spslotdata structure in editor-support->spine->slotdata.h and enclose the initial value.

Add Skin.h #include <spine/Skin.h>

typedef struct SPSLOTDATA {

constchar* const name;

const spbonedata* Const bonedata;

Const char* AttachmentName;

Float R, G, B, A;

Spblendmode Blendmode;

spskin* Const skin;//New Skin Property


#ifdef __cplusplus

Spslotdata ():

Name (0),

Bonedata (0),

AttachmentName (0),

Skin (0),//New Skin Property

R (0), g (0), B (0), a (0),

Blendmode (sp_blend_mode_normal) {

}

#endif

} Spslotdata; 2.addSkin () method, replace the corresponding slot attached skin

Editor-support->spine->skeleton.c to modify the Spskeleton_addskin method in my previous article:

void Spskeleton_addskin (spskeleton* self,spskin* Newskin, constchar* partname) {

if (Newskin) {

int i;

for (i = 0; i < self->slotscount; ++i) {

spslot* slot = self->slots[i];

if (slot->data->attachmentname) {

if (strcmp (Slot->data->attachmentname, PartName) ==0) {

spattachment* attachment =spskin_getattachment (Newskin, I, slot->data->attachmentname);

if (attachment)

{

Const_cast (spskin*, Self->data->slots[i]->skin) = Newskin;//slot->skin Assignment

Spslot_setattachment (slot, attachment);

}

}

}

}


}

3. To determine the current slot skin when replacing slot attachment parts
Modify the Spskeleton_getattachmentforslotindex method in Editor-support->spine->skeleton.c, where two if is the new code.

spattachment* Spskeleton_getattachmentforslotindex (constspskeleton* self, int slotindex, const char* attachmentName) {

if (Slotindex = = 1) return 0;

if (Self->skin) {

New

if (Self->data->slots[slotindex]->skin) {

Spattachment *attachment =spskin_getattachment (Self->data->slots[slotindex]->skin, SlotIndex, AttachmentName);

if (attachment) return attachment;

}

Spattachment *attachment =spskin_getattachment (Self->skin, Slotindex, AttachmentName);

if (attachment) return attachment;

}

if (Self->data->defaultskin) {

New

if (Self->data->slots[slotindex]->skin) {

Spattachment *attachment =spskin_getattachment (Self->data->slots[slotindex]->skin, SlotIndex, AttachmentName);

if (attachment) return attachment;

}

Spattachment *attachment =spskin_getattachment (Self->data->defaultskin, Slotindex, attachmentName);

if (attachment) return attachment;

}

Return0;

}

4. Application

The Setskin method is used for contrast detection.

Self.actor = sp. Skeletonanimation:create ("Red/red.json", "Red/red.atlas", 1)
Self.actor:setAnimation (0, "red_wait", True)
Self.actor:setPosition (450, 300)
Self:addchild (Self.actor)


Self.actor:setSkin ("Hm_lv1")
Local FASHIONSTR = String.Format ("hm_lv%d", 4)
Self.actor:addSkin ("Hm_lv2", "Weap_wuqi")
Self.actor:addSkin (Fashionstr, "hm_huwan_z")
Self.actor:addSkin (Fashionstr, "Hm_r_jiao")
Self.actor:addSkin (Fashionstr, "hm_jiao_l")--hm_l_jiao
Self.actor:addSkin (Fashionstr, "Hm_dun")
Self.actor:addSkin (Fashionstr, "Hm_kuzi")


--------------------------------------4. Notes & Notes--------------------------------------------

-First attach the difference between the JSON file after the animation key and the non key keyframe:

Key on:

"Animations": {"red_wait": {"slots": {

"Hm_r_jiao": {"attachment": [
{' time ': 0, ' name ': ' Hm_r_jiao '},
{' Time ': 0.6, ' name ': null}],
"Color": [
{"Time": 0, "color": "FFFFFFFF"},
{"Time": 0.3, "color": "00ffffff"}
]}}}

No key on:

"Animations": {"red_wait": {"slots": {


]}}}

In fact is the key on the slots "Hm_r_jiao" attributes, the key in the attachment attribute, in fact, remove the attachment attribute, only the Color property, before the Addskin () local dress is also useful.

--Animation code:

In SkeletonAnimation.cpp

void Skeletonanimation::update (float deltatime) {

Super::update (deltatime);


Deltatime *= _timescale;

Spanimationstate_update (_state, deltatime);

Spanimationstate_apply (_state, _skeleton);

Spskeleton_updateworldtransform (_skeleton);

}

This code to look at the line, the focus is below.

-The Attachment property of the code that parses the previous paragraph:

The _spskeletonjson_readanimation method in the Skeletonjson.c file:

else if (strcmp (timelinearray->name, "attachment") = = 0) {

Spattachmenttimeline *timeline = spattachmenttimeline_create (timelinearray->size);

Timeline->slotindex = Slotindex;

for (frame = timelinearray->child, i = 0; frame; frame = Frame->next, ++i) {

json* name = Json_getitem (frame, "name");

Spattachmenttimeline_setframe (timeline, I, Json_getfloat (frame, "time", 0),

Name->type = = Json_null? 0:name->valuestring);

}

animation->timelines[animation->timelinescount++] = Super_cast (sptimeline, Timeline);

Duration = timeline->frames[timelinearray->size-1];

if (Duration > Animation->duration) animation->duration = Duration;


}

of which spattachmenttimeline_create (timelinearray->size):

spattachmenttimeline* spattachmenttimeline_create (int framescount) {

spattachmenttimeline* self =new (spattachmenttimeline);

_sptimeline_init (SUPER (self), sp_timeline_attachment,_spattachmenttimeline_dispose,_spattachmenttimeline_apply) ;


const_cast (int, self->framescount) = Framescount;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.