首页 > 其他分享 >【Cocos2d-x】升级Spine 3.8.95

【Cocos2d-x】升级Spine 3.8.95

时间:2023-07-14 19:36:02浏览次数:41  
标签:Spine spine lua luaval cpp tolua 95 3.8 size

转载,原文连接:https://www.cnblogs.com/tomaszheng/p/14807373.html#!comments

  1. Spine官方下载3.8.95版本的spine-cpp、spine-cocos2dx;
  2. 删除cocos2d-x/cocos/editor-support/spine中所有的旧版本的spine代码;
  3. 把spine-cpp、spine-cocos2dx所有源文件全部拷贝到cocos2d-x/cocos/editor-support/spine目录;

一、Lua-binding

1、使用如下配置完全覆盖掉之前的cocos2dx_spine.ini

[cocos2dx_spine]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_spine

# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = sp

android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/%(gnu_libstdc_version)s/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/%(gnu_libstdc_version)s/include
android_flags = -D_SIZE_T_DEFINED_ 

clang_headers = -I%(clangllvmdir)s/%(clang_lib_version)s/clang/%(clang_version)s/include
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__

cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/external

cocos_flags = -DANDROID

cxxgenerator_headers = 

# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s 

# what headers to parse
headers = %(cocosdir)s/cocos/editor-support/spine/spine-cocos2dx.h

classes = SkeletonRenderer SkeletonAnimation VertexEffectDelegate  Animation TrackEntry AnimationState AnimationStateData Attachment AttachmentTimeline BoundingBoxAttachment Bone BoneData ClippingAttachment Color ColorTimeline CurveTimeline DeformTimeline DrawOrderTimeline Event EventData EventTimeline IkConstraint IkConstraintData IkConstraintTimeline MeshAttachment Polygon PathAttachment PathConstraint PathConstraintData PathConstraintMixTimeline PathConstraintPositionTimeline PathConstraintSpacingTimeline PointAttachment RegionAttachment RotateTimeline ScaleTimeline ShearTimeline Skeleton Slot Skin SkeletonBounds SkeletonData SlotData Timeline TransformConstraint TransformConstraintData TransformConstraintTimeline TranslateTimeline TwoColorTimeline VertexAttachment VertexEffect JitterVertexEffect SwirlVertexEffect ConstraintData

classes_need_extend = SkeletonAnimation

skip = SkeletonRenderer::[create createWithData initWithData createWithSkeleton createWithFile getRenderOrder],
        SkeletonAnimation::[create createWithData createWithJsonFile createWithBinaryFile onTrackEntryEvent onAnimationStateEvent setStartListener setTrackStartListener setEndListener setTrackEndListener setInterruptListener setTrackInterruptListener setEventListener setTrackEventListener setTrackDisposeListener setDisposeListener setCompleteListener setTrackCompleteListener setPostUpdateWorldTransformsListener setPreUpdateWorldTransformsListener],
        Animation::[apply],
        TrackEntry::[setListener],
        AnimationState::[apply setListener],
        Attachment::[getRTTI],
        AttachmentTimeline::[apply getRTTI],
        BoundingBoxAttachment::[getRTTI],
        Bone::[worldToLocal localToWorld getRTTI],
        ClippingAttachment::[getRTTI],
        Color::[set add],
        ColorTimeline::[apply getRTTI],
        CurveTimeline::[apply getRTTI],
        DeformTimeline::[apply setFrame getVertices getRTTI],
        DrawOrderTimeline::[apply setFrame getDrawOrders getRTTI],
        EventTimeline::[apply getRTTI],
        IkConstraint::[apply getRTTI],
        IkConstraintTimeline::[apply getRTTI],
        MeshAttachment::[getRTTI],
        PathAttachment::[getRTTI],
        PathConstraint::[getRTTI],
        PathConstraintMixTimeline::[apply getRTTI],
        PathConstraintPositionTimeline::[apply getRTTI],
        PathConstraintSpacingTimeline::[apply getRTTI],
        PointAttachment::[computeWorldPosition getRTTI computeWorldRotation],
        RegionAttachment::[computeWorldVertices getRTTI],
        RotateTimeline::[apply getRTTI],
        ScaleTimeline::[apply getRTTI],
        ShearTimeline::[apply getRTTI],
        Skeleton::[getBounds getUpdateCacheList],
        Skin::[getAttachments findNamesForSlot findAttachmentsForSlot],
        SkeletonBounds::[update aabbIntersectsSkeleton],
        Timeline::[apply getRTTI],
        TransformConstraint::[getRTTI],
        TransformConstraintTimeline::[apply getRTTI],
        TranslateTimeline::[apply getRTTI],
        TwoColorTimeline::[apply getRTTI],
        VertexEffect::[begin transform end],
        JitterVertexEffect::[begin transform end],
        SwirlVertexEffect::[begin transform end],
        VertexAttachment::[computeWorldVertices getBones getRTTI]

field = Color::[r g b a]

remove_prefix = 

classes_have_no_parents =

base_classes_to_skip = Ref IMiddleware SpineObject HasRendererObject Updatable Constraint

abstract_classes = Animation TrackEntry AnimationState AnimationStateData Attachment AttachmentTimeline BoundingBoxAttachment Bone BoneData ClippingAttachment Color ColorTimeline CurveTimeline DeformTimeline DrawOrderTimeline Event EventData EventTimeline IkConstraint IkConstraintData IkConstraintTimeline MeshAttachment Polygon PathAttachment PathConstraint PathConstraintData PathConstraintMixTimeline PathConstraintPositionTimeline PathConstraintSpacingTimeline PointAttachment RegionAttachment RotateTimeline ScaleTimeline ShearTimeline Skeleton Slot Skin SlotData SkeletonBounds SkeletonData Timeline TransformConstraint TransformConstraintData TransformConstraintTimeline TranslateTimeline TwoColorTimeline VertexAttachment VertexEffect JitterVertexEffect SwirlVertexEffect ConstraintData

rename_functions =  SkeletonAnimation::[createWithFile=create],
                    SkeletonRenderer::[createWithFile=create]

rename_classes = SkeletonRenderer::Skeleton

# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no

2、修改conversions.yaml

由于使用了spine-cpp版本,spine加了很多基础数据类型,在自动绑定lua时,需要定义类型转换代码

conversions:

    ...
    
    to_native:
        
        ...
        
        "String": "ok &= luaval_to_spine_string(tolua_S, ${arg_idx},&${out_value}, \"${lua_namespaced_class_name}:${func_name}\")"
        size_t: "ok &= luaval_to_size_t(tolua_S, ${arg_idx}, &${out_value}, \"${lua_namespaced_class_name}:${func_name}\")"
    
        object: ...
    
    from_native:
        
        ...
        
        # "@Vector<.*>": "ccvector_to_luaval(tolua_S, ${in_value})"
        "@Vector<(?!spine::).*>": "ccvector_to_luaval(tolua_S, ${in_value})"
        
        ...
        
        "String": "lua_pushlstring(tolua_S,${in_value}.buffer(),${in_value}.length())"
        "Color": "spine_color_to_luaval(tolua_S, ${in_value})"
        "@(?:\\bBoneData\\b|\\bSkeleton\\b|\\bColor\\b|\\bEventData\\b|\\bIkConstraintData\\b|\\bPathConstraintData\\b|\\bTransformConstraintData\\b|\\bBone\\b|\\bSlotData\\b)+(?!\\*)+":  "object_to_luaval<${ntype.replace('const ', '').replace('&', '')}>(tolua_S, \"${scriptname}\", (${ntype.replace('const ', '').replace('&', '')}*)&${in_value})"
        "@Vector<spine::((?!String).)*>": "spine_vector_ptr_to_luaval(tolua_S, ${in_value})"
        "@Vector<int.*>": "spine_vector_int_to_luaval(tolua_S, ${in_value})"
        "@Vector<unsigned int.*>": "spine_vector_uint_to_luaval(tolua_S, ${in_value})"
        "@Vector<short.*>": "spine_vector_short_to_luaval(tolua_S, ${in_value})"
        "@Vector<unsigned short.*>": "spine_vector_ushort_to_luaval(tolua_S, ${in_value})"
        "@Vector<float.*>": "spine_vector_float_to_luaval(tolua_S, ${in_value})"
        "@Vector<spine::String.*>": "spine_vector_spine_string_to_luaval(tolua_S, ${in_value})"
        size_t: "tolua_pushnumber(tolua_S,(lua_Number)${in_value})"
        
        object: ...

3、定义类型转换方法

在cocos2d-x/cocos/scripting/lua-bindings/manual/下增加SpineConversions.h、SpineConversions.cpp

// SpineConversions.h
#pragma once

extern "C" {
#include "lua.h"
#include "tolua++.h"
}
#include "scripting/lua-bindings/manual/tolua_fix.h"
#include "scripting/lua-bindings/manual/Lua-BindingsExport.h"
#include "editor-support/spine/Color.h"
#include "editor-support/spine/SpineString.h"
#include "editor-support/spine/Vector.h"

extern bool luaval_to_size_t(lua_State* L, int lo, size_t* outValue, const char* funcName = "");

extern bool luaval_to_spine_color(lua_State* L, int lo, spine::Color* outValue, const char* funcName);

extern bool luaval_to_spine_string(lua_State* L, int lo, spine::String* outValue, const char* funcName);

extern void spine_color_to_luaval(lua_State* L, const spine::Color& cc);

extern void spine_vector_int_to_luaval(lua_State* L, spine::Vector<int>& inValue);

extern void spine_vector_uint_to_luaval(lua_State* L, spine::Vector<unsigned int>& inValue);

extern void spine_vector_short_to_luaval(lua_State* L, spine::Vector<short>& inValue);

extern void spine_vector_ushort_to_luaval(lua_State* L, spine::Vector<unsigned short>& inValue);

extern void spine_vector_float_to_luaval(lua_State* L, spine::Vector<float>& inValue);

extern void spine_vector_spine_string_to_luaval(lua_State* L, spine::Vector<spine::String>& inValue);

template <class T>
void spine_vector_to_luaval(lua_State* L, const spine::Vector<T>& inValue)
{
    lua_newtable(L);

    if (nullptr == L)
        return;

    int indexTable = 1;
    spine::Vector<T> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        std::string typeName = typeid(tmpv[i]).name();
        auto iter = g_luaType.find(typeName);
        if (g_luaType.end() != iter)
        {
            lua_pushnumber(L, (lua_Number)indexTable);
            tolua_pushusertype(L, (void*)tmpv[i], iter->second.c_str());
            lua_rawset(L, -3);
            ++indexTable;
        }
    }
}

template <class T>
void spine_vector_ptr_to_luaval(lua_State* L, const spine::Vector<T*>& inValue)
{
    lua_newtable(L);

    if (nullptr == L)
        return;

    int indexTable = 1;
    spine::Vector<T*> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        std::string typeName = typeid(*tmpv[i]).name();
        auto iter = g_luaType.find(typeName);
        if (g_luaType.end() != iter)
        {
            lua_pushnumber(L, (lua_Number)indexTable);
            tolua_pushusertype(L, (void*)tmpv[i], iter->second.c_str());
            lua_rawset(L, -3);
            ++indexTable;
        }
    }
}
// SpineConversions.cpp
#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
#include "scripting/lua-bindings/manual/SpineConversions.h"
#include "scripting/lua-bindings/manual/tolua_fix.h"

bool luaval_to_size_t(lua_State* L, int lo, size_t* outValue, const char* funcName)
{
    return luaval_to_uint32(L, lo, reinterpret_cast<unsigned int*>(outValue), funcName);
}

bool luaval_to_spine_color(lua_State* L, int lo, spine::Color* outValue, const char* funcName)
{
    if (NULL == L || NULL == outValue)
        return false;

    bool ok = true;

    tolua_Error tolua_err;
    if (!tolua_istable(L, lo, 0, &tolua_err))
    {
#if COCOS2D_DEBUG >=1
        luaval_to_native_err(L, "#ferror:", &tolua_err, funcName);
#endif
        ok = false;
    }

    if (ok)
    {
        lua_pushstring(L, "r");
        lua_gettable(L, lo);
        outValue->r = lua_isnil(L, -1) ? 0 : lua_tonumber(L, -1);
        lua_pop(L, 1);

        lua_pushstring(L, "g");
        lua_gettable(L, lo);
        outValue->g = lua_isnil(L, -1) ? 0 : lua_tonumber(L, -1);
        lua_pop(L, 1);

        lua_pushstring(L, "b");
        lua_gettable(L, lo);
        outValue->b = lua_isnil(L, -1) ? 0 : lua_tonumber(L, -1);
        lua_pop(L, 1);

        lua_pushstring(L, "a");
        lua_gettable(L, lo);
        outValue->b = lua_isnil(L, -1) ? 0 : lua_tonumber(L, -1);
        lua_pop(L, 1);
    }

    return ok;
}

bool luaval_to_spine_string(lua_State* L, int lo, spine::String* outValue, const char* funcName)
{
    if (NULL == L || NULL == outValue)
        return false;

    bool ok = true;

    tolua_Error tolua_err;
    if (!tolua_iscppstring(L, lo, 0, &tolua_err))
    {
#if COCOS2D_DEBUG >=1
        luaval_to_native_err(L, "#ferror:", &tolua_err, funcName);
#endif
        ok = false;
    }

    if (ok)
    {
        size_t size;
        auto rawString = lua_tolstring(L, lo, &size);
        *outValue = spine::String(rawString);
    }

    return ok;
}

void spine_color_to_luaval(lua_State* L, const spine::Color& cc)
{
    if (NULL == L)
        return;
    lua_newtable(L);                                    /* L: table */
    lua_pushstring(L, "r");                             /* L: table key */
    lua_pushnumber(L, (lua_Number)cc.r);               /* L: table key value*/
    lua_rawset(L, -3);                                  /* table[key] = value, L: table */
    lua_pushstring(L, "g");                             /* L: table key */
    lua_pushnumber(L, (lua_Number)cc.g);               /* L: table key value*/
    lua_rawset(L, -3);                                  /* table[key] = value, L: table */
    lua_pushstring(L, "b");                             /* L: table key */
    lua_pushnumber(L, (lua_Number)cc.b);               /* L: table key value*/
    lua_rawset(L, -3);                                  /* table[key] = value, L: table */
    lua_pushstring(L, "a");                             /* L: table key */
    lua_pushnumber(L, (lua_Number)cc.b);               /* L: table key value*/
    lua_rawset(L, -3);                                  /* table[key] = value, L: table */
}

void spine_vector_int_to_luaval(lua_State* L, spine::Vector<int>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<int> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushnumber(L, (lua_Number)tmpv[i]);
        lua_rawset(L, -3);
    }
}

void spine_vector_uint_to_luaval(lua_State* L, spine::Vector<unsigned int>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<unsigned int> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushnumber(L, (lua_Number)tmpv[i]);
        lua_rawset(L, -3);
    }
}

void spine_vector_short_to_luaval(lua_State* L, spine::Vector<short>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<short> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushnumber(L, (lua_Number)tmpv[i]);
        lua_rawset(L, -3);
    }
}

void spine_vector_ushort_to_luaval(lua_State* L, spine::Vector<unsigned short>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<unsigned short> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushnumber(L, (lua_Number)tmpv[i]);
        lua_rawset(L, -3);
    }
}

void spine_vector_float_to_luaval(lua_State* L, spine::Vector<float>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<float> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushnumber(L, (lua_Number)tmpv[i]);
        lua_rawset(L, -3);
    }
}

void spine_vector_spine_string_to_luaval(lua_State* L, spine::Vector<spine::String>& inValue)
{
    if (nullptr == L)
        return;

    lua_newtable(L);

    spine::Vector<spine::String> tmpv = inValue;
    for (size_t i = 0, count = (size_t)tmpv.size(); i < count; i++)
    {
        lua_pushnumber(L, (lua_Number)(i + 1));
        lua_pushstring(L, tmpv[i].buffer());
        lua_rawset(L, -3);
    }
}

4、自动导入SpineConversions.h

修改cocos2d-x/tools/bindings-generator/targets/lua/templates/layout_head.c,自动导入SpineConversion.h

...

\#include "scripting/lua-bindings/manual/tolua_fix.h"
\#include "scripting/lua-bindings/manual/LuaBasicConversions.h"
\#include "scripting/lua-bindings/manual/SpineConversions.h"

...

5、适配Skeleton的创建接口

由于Spine 3.8.95增加了二进制文件格式,因此Cocos2dx的适配层LuaSkeletonAnimation需要做如下修改:

// scripting/lua-bindings/manual/LuaSkeletonAnimation.cpp
LuaSkeletonAnimation* LuaSkeletonAnimation::createWithFile(const std::string& skeletonFilepath, Atlas* atlas, float scale) {
    LuaSkeletonAnimation* node = new LuaSkeletonAnimation();
    if (FileUtils::getInstance()->getFileExtension(skeletonFilepath) == ".json") {
        node->initWithJsonFile(skeletonFilepath, atlas, scale);
    }
    else {
        node->initWithBinaryFile(skeletonFilepath, atlas, scale);
    }
    node->autorelease();
    return node;
}

LuaSkeletonAnimation* LuaSkeletonAnimation::createWithFile(const std::string& skeletonFilepath, const std::string& atlasFile, float scale) {
    LuaSkeletonAnimation* node = new LuaSkeletonAnimation();
    if (FileUtils::getInstance()->getFileExtension(skeletonFilepath) == ".json") {
        node->initWithJsonFile(skeletonFilepath, atlasFile, scale);
    }
    else {
        node->initWithBinaryFile(skeletonFilepath, atlasFile, scale);
    }
    node->autorelease();
    return node;
}

二、Win32

用VS2017打开项目工程,移除所有的旧的Spine代码引用,再把新的Spine代码引入进来,重新编译。

三、IOS

类似Win32,唯一区别是把VS2017换成Xcode

四、Android平台

Android需要改动到Android.mk(如果使用NDK进行编译)或CMakeList.txt(如果使用CMake),以下以NDK编译示例

1,Spine库的Android.mk

Spine库的Android.mk在目录cocos2d-x/cocos/editor-support/spine/Android.mk,使用以下代码覆盖掉之前的。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := spine_static

LOCAL_MODULE_FILENAME := libspine

LOCAL_ARM_MODE := arm

LOCAL_SRC_FILES := \
Animation.cpp \
AnimationState.cpp \
AnimationStateData.cpp \
Atlas.cpp \
AtlasAttachmentLoader.cpp \
Attachment.cpp \
AttachmentLoader.cpp \
AttachmentTimeline.cpp \
AttachmentVertices.cpp \
Bone.cpp \
BoneData.cpp \
BoundingBoxAttachment.cpp \
ClippingAttachment.cpp \
ColorTimeline.cpp \
ConstraintData.cpp \
CurveTimeline.cpp \
DeformTimeline.cpp \
DrawOrderTimeline.cpp \
Event.cpp \
EventData.cpp \
EventTimeline.cpp \
Extension.cpp \
IkConstraint.cpp \
IkConstraintData.cpp \
IkConstraintTimeline.cpp \
Json.cpp \
LinkedMesh.cpp \
MathUtil.cpp \
MeshAttachment.cpp \
PathAttachment.cpp \
PathConstraint.cpp \
PathConstraintData.cpp \
PathConstraintMixTimeline.cpp \
PathConstraintPositionTimeline.cpp \
PathConstraintSpacingTimeline.cpp \
PointAttachment.cpp \
RegionAttachment.cpp \
RotateTimeline.cpp \
RTTI.cpp \
ScaleTimeline.cpp \
ShearTimeline.cpp \
Skeleton.cpp \
SkeletonAnimation.cpp \
SkeletonBatch.cpp \
SkeletonBinary.cpp \
SkeletonBounds.cpp \
SkeletonClipping.cpp \
SkeletonData.cpp \
SkeletonJson.cpp \
SkeletonRenderer.cpp \
SkeletonTwoColorBatch.cpp \
Skin.cpp \
Slot.cpp \
SlotData.cpp \
spine-cocos2dx.cpp \
SpineObject.cpp \
TextureLoader.cpp \
Timeline.cpp \
TransformConstraint.cpp \
TransformConstraintData.cpp \
TransformConstraintTimeline.cpp \
TranslateTimeline.cpp \
Triangulator.cpp \
TwoColorTimeline.cpp \
Updatable.cpp \
VertexAttachment.cpp \
VertexEffect.cpp

LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/..

LOCAL_C_INCLUDES := $(LOCAL_PATH)/..

LOCAL_STATIC_LIBRARIES := cocos2dx_internal_static

include $(BUILD_STATIC_LIBRARY)

2,luacocos2d库的Android.mk

把SpineConversions放入luacocos2d库中

...

LOCAL_SRC_FILES += ../manual/spine/lua_cocos2dx_spine_manual.cpp \
                   ../manual/spine/LuaSkeletonAnimation.cpp \
                   ../manual/SpineConversions.cpp \
                   ../auto/lua_cocos2dx_spine_auto.cpp

...

五、实现挂点

实现Spine挂点,有两种方案:

  1. Creator的实现方案:根据骨骼层次生成节点树,在Spine每次render时更新节点树的世界矩阵;
  2. 不创建节点树,在Spine每次transform后,同步更新需要挂载的节点;

对于方案一,在Cocos2d-x中较难实现,主要是在矩阵转换上比较麻烦,而且对引擎侵入性较大,对于此方案,目前没有找到比较好的解决方法。

采用方案二简单实现挂点

1,定义PostUpdateWorldTransforms事件

// cocos2d-x/cocos/editor-support/spine/AnimationState.h
enum EventType {
    ...
    
    EventType_PostUpdate,
};
// cocos2d-x/cocos/scripting/lua-bindings/manual/cocos2d/LuaScriptHandlerMgr.h
enum class HandlerType: int
{
    ...
    
    EVENT_SPINE_ANIMATION_POST_UPDATE
}

// cocos/spine/SpineConstants.lua
sp.EventType =
{
    ...
    
    ANIMATION_POST_UPDATE = 6,
}

2,手动绑定监听

//  cocos2d-x/cocos/scripting/lua-bindings/manual/spine/lua_cocos2dx_spine_manual.cpp
int tolua_Cocos2d_CCSkeletonAnimation_registerSpineEventHandler00(lua_State* tolua_S)
{
    ...
    
    switch (eventType) {
        ...
        
        case EventType::EventType_PostUpdate: {
            self->setPostUpdateWorldTransformsListener([=](SkeletonAnimation* skeletonAnimation) {
                handleSpineUpdateEvent(handler, skeletonAnimation);
            });
            ScriptHandlerMgr::getInstance()->addObjectHandler((void*)self, handler, ScriptHandlerMgr::HandlerType::EVENT_SPINE_ANIMATION_POST_UPDATE);
            break;
        }
    }
}

int tolua_Cocos2d_CCSkeletonAnimation_unregisterSpineEventHandler00(lua_State* tolua_S)
{
    ...
    
    switch (eventType) {
        ...
        
        case EventType::EventType_PostUpdate: {
            handlerType = ScriptHandlerMgr::HandlerType::EVENT_SPINE_ANIMATION_POST_UPDATE;
            break;
        }
    }
}

增加回调处理方法

static int handleSpineUpdateEvent(int handler, spine::SkeletonAnimation* skeletonAnimation)
{
    LuaStack* stack = LuaEngine::getInstance()->getLuaStack();

    stack->pushObject(skeletonAnimation, "sp.SkeletonAnimation");

    stack->executeFunctionByHandler(handler, 1);
    stack->clean();

    return 0;
}

3,lua中调用

self.skeleton:registerSpineEventHandler(function(event)
    updateAttachedNode(self.skeleton, self.attachedBoneName, self.attachedNode)
end, sp.EventType.ANIMATION_POST_UPDATE)

function updateAttachedNode(skeleton, boneName, attachedName)
    local bone = skeleton:findBone(boneName)
    attachedNode:setPosition(cc.p(bone:getWorldX(), bone:getWorldY()))
    attachedNode:setRotation(-bone:getWorldRotationX())
    attachedNode:setScaleX(bone:getWorldScaleX())
    attachedNode:setScaleY(bone:getWorldScaleY())
    attachedNode:setVisible(bone:isActive())
end
 

标签:Spine,spine,lua,luaval,cpp,tolua,95,3.8,size
From: https://www.cnblogs.com/zc347656462/p/17554772.html

相关文章

  • 【Java 新的选择】,Solon v2.3.8 发布
    Solon是什么开源项目?一个,Java新的生态型应用开发框架。它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态规模)。与其他框架相比,它解决了两个重要的痛点:启动慢,费内存。解决痛点?由于SolonBean容器的独特设计,不会因为扩展依赖变多而启动很慢(开发调试时,......
  • P8095 [USACO22JAN] Cereal 2 S 谷物早餐
    P8095[USACO22JAN]Cereal2S谷物早餐[P8095USACO22JAN]Cereal2S-洛谷|计算机科学教育新生态(luogu.com.cn)目录P8095[USACO22JAN]Cereal2S谷物早餐[USACO22JAN]Cereal2S题目描述输入格式输出格式样例#1样例输入#1样例输出#1提示分析[USACO22JAN]Cerea......
  • 95.静态成员与普通成员的区别是什么?
    95.静态成员与普通成员的区别是什么?1.生命周期静态成员变量从类被加载开始到类被卸载,一直存在;普通成员变量只有在类创建对象后才开始存在,对象结束,它的生命期结束;2.共享方式静态成员变量是全类共享;普通成员变量是每个对象单独享用的;3.定义位置普通成员变量存储在栈或堆中,而......
  • 595-大的国家
    大的国家原文地址:595.大的国家-力扣(LeetCode)题目如下所示个人题解这题目看起来复杂,实际上的SQL非常简单,如下所示--1.建表CREATETABLE595_world( nameVARCHAR(20), --国家名称 continentVARCHAR(20),--所属大陆 areaINT,--面积 populationINT......
  • 永磁同步电机无位置传感器控制,采用的是龙贝格,基于模型的 定点开发,仿真效果和实际95%高
    永磁同步电机无位置传感器控制,采用的是龙贝格,基于模型的定点开发,仿真效果和实际95%高度吻合,可以仿真学习,也可以直接移植到项目中YID:32768642079012761......
  • loj3959
    惊奇地发现我的赛时做法也可以通过转化一下计算式优化到\(O(n+m)\)。或许也算是一种另解?首先,我们考虑把后手的决策视为图上的一个自环或一条边。对于每条边,你要对其选择其连接的一个点,且使得其满足两两不同。对先手的决策,则意味着对这个点/边的额外代价,包括无额外代价。(\(|......
  • “金九银十”和秋招通过率高达 95% 的 Android面试题集锦,你确定不来看看吗?
    前言已经进入七月份了,职场上的“金三银四”也早已经结束。对于求职者来说,面试是一道坎,很多人会恐惧面试,即使是工作很多年的老鸟,也可能存在面试焦虑。就今年的IT行业来说,可能真的根本没有所谓的“金三银四”或是“金九银十”。各大招聘网站或者软件上不管是大厂还是中小公司看似挂个......
  • Ubuntu源码编译安装Python3.8
    一、下载源码https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz二、编译参数--prefix:指定安装目录使用–prefix参数可以指定Python的安装目录,例如:./configure--prefix=/usr/local/python38这将把Python3.8安装在/usr/local/python38目录下。–enable-optim......
  • 由Spine出现黑边说起纹理格式问题
    项目中的纹理一直使用的ETC2格式,以前主要是考虑到兼容性问题。最近在Spine使用PMA方案的时候出现了部分接缝位置黑边的情况,像下图这样: 怀疑了spine的导出,怀疑了shader,怀疑了材质的设置,最后发现是ETC2格式导致的问题。使用RGBA或者ASTC格式,显示正常了。附几张不同ASTC格式下的......
  • 数据结构课后题答案 - XDU_953
    参考书:数据结构与算法分析(第二版)作者:荣政编出版社:西安电子科技大学出版社出版日期:2021年01月01日答案解析: ......