Skeleton* Skeleton::from_json(const char* path, float scale) { // Copy the path and replace ".json" with ".atlas" const size_t length = strlen(path); auto atlas_path = std::make_unique<char[]>(length + 7); strcpy(atlas_path.get(), path); char* ext; if (path[length - 5] != '.') { ext = strrchr(atlas_path.get(), '.'); if (!ext) ext = atlas_path.get() + length; } else ext = atlas_path.get() + length - 5; memcpy(ext, ".atlas\0", 7); spAtlas* atlas = spAtlas_createFromFile(atlas_path.get(), nullptr); atlas_path.reset(); spSkeletonJson* json = spSkeletonJson_create(atlas); json->scale = scale; spSkeletonData* data = spSkeletonJson_readSkeletonDataFile(json, path); spSkeletonJson_dispose(json); if (!data) { LOGE("Spine: %s", json->error); return nullptr; } return new Skeleton(data, atlas); }
WIPAnimator::WIPAnimator(const char* atlas_path,const char* json_path,i32 w,i32 h):time_scale(1) { _out_buffer = WIPRenderTexture::create(w,h); _frame_ref = 0; spAtlas* atlas = spAtlas_createFromFile(atlas_path, 0); spSkeletonJson* json = spSkeletonJson_create(atlas); json->scale = 0.8f; spSkeletonData *skeletonData = spSkeletonJson_readSkeletonDataFile(json, json_path); if (!skeletonData) { printf("Error: %s\n", json->error); getchar(); exit(0); } //spAnimation* walkAnimation = spSkeletonData_findAnimation(skeletonData, "walk"); spSkeletonJson_dispose(json); spSkeletonBounds* bounds = spSkeletonBounds_create(); spAnimationStateData* stateData = spAnimationStateData_create(skeletonData); //spAnimationStateData_setMixByName(stateData, "walk", "jump", 0.2f); //spAnimationStateData_setMixByName(stateData, "jump", "run", 0.2f); //spAnimationStateData_setMixByName(stateData, "shoot", "walk", 0.2f); //drawable = new SkeletonDrawable(skeletonData,stateData); spBone_setYDown(true); skeleton = spSkeleton_create(skeletonData); state = spAnimationState_create(stateData); time_scale = 1; //spSkeleton* skeleton = drawable->skeleton; skeleton->flipX = false; skeleton->flipY = false; //spSkeleton_setSkinByName(skeleton, "goblin"); spSkeleton_setToSetupPose(skeleton); skeleton->x = 0; skeleton->y = 0; spSkeleton_updateWorldTransform(skeleton); spSlot* headSlot = spSkeleton_findSlot(skeleton, "head"); state->listener = callback; if (false) { spAnimationState_setAnimationByName(state, 0, "test", true); } else { spAnimationState_setAnimationByName(state, 0, "flying", true); /* spAnimationState_addAnimationByName(drawable->state, 0, "jump", false, 3); spAnimationState_addAnimationByName(drawable->state, 0, "run", true, 0); spAnimationState_addAnimationByName(drawable->state,0,"shoot",true,3); spAnimationState_addAnimationByName(drawable->state, 0, "walk", true,3); */ } //spAnimationState_setAnimation(drawable->state, 0, walkAnimation, false); //drawable->bounds = bounds; }
////////////////////////////////////////////////////////////////////////// // Helper methods static spSkeletonData* readSkeletonJsonData(const char* filename, spAtlas* atlas) { spSkeletonJson* json = spSkeletonJson_create(atlas); ASSERT(json != nullptr); spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, filename); ASSERT(skeletonData != nullptr); spSkeletonJson_dispose(json); return skeletonData; }
Skeleton::Skeleton (const char* skeletonDataFile, spAtlas* aAtlas, float scale) { initialize(); spSkeletonJson* json = spSkeletonJson_create(aAtlas); json->scale = scale == 0 ? (1 / Director::getInstance()->getContentScaleFactor()) : scale; spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile); CCAssert(skeletonData, json->error ? json->error : "Error reading skeleton data."); spSkeletonJson_dispose(json); setSkeletonData(skeletonData, true); }
void SkeletonRenderer::initWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale) { _attachmentLoader = SUPER(Cocos2dAttachmentLoader_create(_atlas)); spSkeletonJson* json = spSkeletonJson_createWithLoader(_attachmentLoader); json->scale = scale; spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str()); CCASSERT(skeletonData, json->error ? json->error : "Error reading skeleton data."); spSkeletonJson_dispose(json); setSkeletonData(skeletonData, true); initialize(); }
CCSkeleton::CCSkeleton (const char* skeletonDataFile, const char* atlasFile, float scale) { initialize(); atlas = spAtlas_readAtlasFile(atlasFile); CCAssert(atlas, "Error reading atlas file."); spSkeletonJson* json = spSkeletonJson_create(atlas); json->scale = scale == 0 ? (1 / CCDirector::sharedDirector()->getContentScaleFactor()) : scale; spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile); CCAssert(skeletonData, json->error ? json->error : "Error reading skeleton data file."); spSkeletonJson_dispose(json); setSkeletonData(skeletonData, true); }
void SkeletonAnimationFbo::loadSkeletonAndAtlasData() { releaseSkeletonRelatedData(); if (mAtlasFile.isEmpty() || !mAtlasFile.isValid()){ qDebug()<<"SkeletonAnimation::loadSkeletonAndAtlasData Error: Invalid AtlasFile:"<<mAtlasFile; return; } if (mSkeletonDataFile.isEmpty() || !mSkeletonDataFile.isValid()){ qDebug()<<"SkeletonAnimation::loadSkeletonAndAtlasData Error: Invalid SkeletonDataFile:"<<mSkeletonDataFile; return; } std::string atlasFile = QQmlFile::urlToLocalFileOrQrc(mAtlasFile).toStdString(); mspAtlas = spAtlas_createFromFile(atlasFile.c_str(), 0); if (!mspAtlas){ qDebug()<<"SkeletonAnimation::loadSkeletonAndAtlasData Error: Atals is null. AtlasFile:"<<mAtlasFile; return; } spSkeletonJson* json = spSkeletonJson_create(mspAtlas); json->scale = mScale; std::string skeletonFile = QQmlFile::urlToLocalFileOrQrc(mSkeletonDataFile).toStdString(); spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonFile.c_str()); if (!skeletonData){ qDebug()<<"SkeletonAnimation::loadSkeletonAndAtlasData Error: Failed to load json. jason error:"<<(json->error ? json->error : "null."); releaseSkeletonRelatedData(); return; } spSkeletonJson_dispose(json); mspSkeleton = spSkeleton_create(skeletonData); mspRootBone = mspSkeleton->bones[0]; const bool res = spSkeleton_setSkinByName(mspSkeleton, mSkin.toStdString().c_str()); if (!res && !mSkin.isEmpty()) qDebug()<<"SkeletonAnimation::loadSkeletonAndAtlasData Error: Invalid skin:"<<mSkin; mspAnimationState = spAnimationState_create(spAnimationStateData_create(mspSkeleton->data)); mspAnimationState->rendererObject = this; mspAnimationState->listener = animationCallback; mSkeletonLoaded = true; mTimer.invalidate(); }
Player::Player(Game& g, b2Vec2 p) : Character(g),swordFix(NULL), left(false), right(false), landed(true), contact(false), lastproc(0), life(100), attacking(false), attackcooldown(0) { bodyDef.type = b2_dynamicBody; bodyDef.position.Set(p.x, p.y); bodyDef.fixedRotation = true; body = g.w.CreateBody(&bodyDef); dynamicBox.SetAsBox(.25f, 0.9f); fixtureDef.shape = &dynamicBox; fixtureDef.density = 5.0f; fixtureDef.friction = 0.0f; fixtureDef.filter.categoryBits = PLAYER; fixtureDef.filter.maskBits = MONSTER | TRIGGER | WALL | SWORD; (body->CreateFixture(&fixtureDef))->SetUserData(this); //add "feet" to detect floor dynamicBox.SetAsBox(0.2, 0.05, b2Vec2(0, 0.9f), 0); fixtureDef.isSensor = true; fixtureDef.density = 0.1; fixtureDef.filter.categoryBits = FOOT; fixtureDef.filter.maskBits = WALL | MONSTER; (body->CreateFixture(&fixtureDef))->SetUserData(this); //add sword to kill monsters dynamicBox.SetAsBox(0.4, 0.1, b2Vec2(0.65, 0), 0); swordDef.shape = &dynamicBox; swordDef.isSensor = true; swordDef.density = 0.1; swordDef.filter.categoryBits = SWORD; swordDef.filter.maskBits = MONSTER; // Loads the Spine model ALLEGRO_PATH *path, *resourceDir, *file; resourceDir= al_get_standard_path(ALLEGRO_RESOURCES_PATH); std::cerr << al_path_cstr(resourceDir, ALLEGRO_NATIVE_PATH_SEP) << std::endl; if (modelAtlas == NULL) { file = al_create_path("data/animations/hero.atlas"); path = al_clone_path(resourceDir); al_join_paths(path, file); al_destroy_path(file); modelAtlas = spAtlas_createFromFile(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), NULL); if (!modelAtlas) throw Failure("Failed to load the hero's atlas."); al_destroy_path(path); jsonSkel = spSkeletonJson_create(modelAtlas); file = al_create_path("data/animations/hero.json"); path = al_clone_path(resourceDir); al_join_paths(path, file); al_destroy_path(file); modelData = spSkeletonJson_readSkeletonDataFile(jsonSkel, al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP)); if (!modelData) throw Failure("Failed to load the hero's data."); al_destroy_path(path); al_destroy_path(resourceDir); stateData = spAnimationStateData_create(modelData); spAnimationStateData_setMixByName(stateData, "walk", "rest", 0.2f); spAnimationStateData_setMixByName(stateData, "rest", "walk", 0.2f); spAnimationStateData_setMixByName(stateData, "rest", "slash", 0.1f); spAnimationStateData_setMixByName(stateData, "slash", "rest", 0.1f); spAnimationStateData_setMixByName(stateData, "walk", "slash", 0.1f); spAnimationStateData_setMixByName(stateData, "slash", "walk", 0.1f); model = loadSkeleton(modelData, stateData); if (!model) throw Failure("Failed to load the hero's skeleton."); spAnimationState_setAnimationByName(model->state, 0, "rest", true); } }
SpineDrawable::SpineDrawable(const std::string& atlasFile, const std::string& skeletonFile): Component(TYPE) { atlas = spAtlas_createFromFile(atlasFile.c_str(), 0); if (!atlas) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load atlas"; return; } if (skeletonFile.find(".json") != std::string::npos) { // is json format spSkeletonJson* json = spSkeletonJson_create(atlas); skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonFile.c_str()); if (!skeletonData) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load skeleton: " << json->error; return; } spSkeletonJson_dispose(json); } else { // binary format spSkeletonBinary* binary = spSkeletonBinary_create(atlas); skeletonData = spSkeletonBinary_readSkeletonDataFile(binary, skeletonFile.c_str()); if (!skeletonData) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load skeleton: " << binary->error; return; } spSkeletonBinary_dispose(binary); } bounds = spSkeletonBounds_create(); skeleton = spSkeleton_create(skeletonData); animationStateData = spAnimationStateData_create(skeletonData); animationState = spAnimationState_create(animationStateData); animationState->listener = listener; animationState->rendererObject = this; spSkeleton_setToSetupPose(skeleton); spSkeleton_updateWorldTransform(skeleton); updateMaterials(); updateBoundingBox(); indexBuffer = std::make_shared<ouzel::graphics::Buffer>(*ouzel::engine->getRenderer()); indexBuffer->init(ouzel::graphics::Buffer::Usage::INDEX, ouzel::graphics::Buffer::DYNAMIC); vertexBuffer = std::make_shared<ouzel::graphics::Buffer>(*ouzel::engine->getRenderer()); vertexBuffer->init(ouzel::graphics::Buffer::Usage::VERTEX, ouzel::graphics::Buffer::DYNAMIC); whitePixelTexture = ouzel::engine->getCache().getTexture(ouzel::TEXTURE_WHITE_PIXEL); updateHandler.updateHandler = std::bind(&SpineDrawable::handleUpdate, this, std::placeholders::_1); ouzel::engine->getEventDispatcher().addEventHandler(&updateHandler); }