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; }
void MemoryTestFixture::reproduceIssue_Loop() { spAtlas* atlas = nullptr; spSkeletonData* skeletonData = nullptr; spAnimationStateData* stateData = nullptr; spAnimationState* state = nullptr; ////////////////////////////////////////////////////////////////////////// // Initialize Animations LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); /////////////////////////////////////////////////////////////////////////// if (state) state->listener = (spAnimationStateListener)&spineAnimStateHandler; spAnimationState_setAnimationByName(state, 0, "walk", false); // run normal update for (int i = 0; i < 50; ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } DisposeAll(skeleton, state, stateData, skeletonData, atlas); }
void Player::stopRight() { right = false; if(!left) spAnimationState_setAnimationByName(model->state, 0, "rest", true); if(left) model->skeleton->flipX = 1; }
void Player::moveRight() { right = true; model->skeleton->flipX = 0; if(!left) spAnimationState_setAnimationByName(model->state, 0, "walk", true); }
void MemoryTestFixture::reproduceIssue_777() { spAtlas* atlas = nullptr; spSkeletonData* skeletonData = nullptr; spAnimationStateData* stateData = nullptr; spSkeleton* skeleton = nullptr; spAnimationState* state = nullptr; ////////////////////////////////////////////////////////////////////////// // Initialize Animations LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); /////////////////////////////////////////////////////////////////////////// // Run animation spSkeleton_setToSetupPose(skeleton); SpineEventMonitor eventMonitor(state); //eventMonitor.SetDebugLogging(true); // Set Animation and Play for 5 frames spAnimationState_setAnimationByName(state, 0, "walk", true); for (int i = 0; i < 5; ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } // Change animation twice in a row spAnimationState_setAnimationByName(state, 0, "walk", false); spAnimationState_setAnimationByName(state, 0, "run", false); // run normal update for (int i = 0; i < 5; ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } // Now we'd lose mixingFrom (the first "walk" entry we set above) and should leak spAnimationState_setAnimationByName(state, 0, "run", false); ////////////////////////////////////////////////////////////////////////// // Cleanup Animations DisposeAll(skeleton, state, stateData, skeletonData, atlas); }
void Player::moveLeft() { left = true; if(!right) { model->skeleton->flipX = 1; spAnimationState_setAnimationByName(model->state, 0, "walk", true); } }
static void spineAnimStateHandler(spAnimationState* state, int type, spTrackEntry* entry, spEvent* event) { if (type == SP_ANIMATION_COMPLETE) { spAnimationState_setAnimationByName(state, 0, "walk", false); spAnimationState_update(state, 0); spAnimationState_apply(state, skeleton); } }
static void testRunner(const char* jsonName, const char* atlasName) { /////////////////////////////////////////////////////////////////////////// // Global Animation Information spAtlas* atlas = spAtlas_createFromFile(atlasName, 0); ASSERT(atlas != 0); spSkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); ASSERT(skeletonData != 0); spAnimationStateData* stateData = spAnimationStateData_create(skeletonData); ASSERT(stateData != 0); stateData->defaultMix = 0.2f; // force mixing /////////////////////////////////////////////////////////////////////////// // Animation Instance spSkeleton* skeleton = spSkeleton_create(skeletonData); ASSERT(skeleton != 0); spAnimationState* state = spAnimationState_create(stateData); ASSERT(state != 0); /////////////////////////////////////////////////////////////////////////// // Run animation spSkeleton_setToSetupPose(skeleton); SpineEventMonitor eventMonitor(state); // eventMonitor.SetDebugLogging(true); AnimList anims; // Let's chain all the animations together as a test size_t count = enumerateAnimations(anims, skeletonData); if (count > 0) spAnimationState_setAnimationByName(state, 0, anims[0].c_str(), false); for (size_t i = 1; i < count; ++i) { spAnimationState_addAnimationByName(state, 0, anims[i].c_str(), false, 0.0f); } // Run Loop for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } /////////////////////////////////////////////////////////////////////////// // Dispose Instance spSkeleton_dispose(skeleton); spAnimationState_dispose(state); /////////////////////////////////////////////////////////////////////////// // Dispose Global spAnimationStateData_dispose(stateData); spSkeletonData_dispose(skeletonData); spAtlas_dispose(atlas); }
UTrackEntry* USpineSkeletonAnimationComponent::SetAnimation (int trackIndex, FString animationName, bool loop) { CheckState(); if (state && spSkeletonData_findAnimation(skeleton->data, TCHAR_TO_UTF8(*animationName))) { _spAnimationState_disableQueue(state); spTrackEntry* entry = spAnimationState_setAnimationByName(state, trackIndex, TCHAR_TO_UTF8(*animationName), loop ? 1 : 0); _spAnimationState_enableQueue(state); UTrackEntry* uEntry = NewObject<UTrackEntry>(); uEntry->SetTrackEntry(entry); trackEntries.Add(uEntry); return uEntry; } else return NewObject<UTrackEntry>(); }
void Player::onAttack() { if(!attacking) { attacking = true; attackcooldown = 50; spAnimationState_setAnimationByName(model->state, 0, "slash", false); dynamicBox.SetAsBox(1, 0.3, b2Vec2(0, -.3), 0); swordDef.shape = &dynamicBox; swordFix = body->CreateFixture(&swordDef); swordFix->SetUserData(this); } }
void Player::tick() { skeletonUpdate(model, 1 / (float) g.m.animation_tick); //Velocity update float needvel; if(right && landed) needvel = 10.; else if(left && landed) needvel = -10.; else if(right && !landed) needvel = 7.; else if(left && !landed) needvel = -7.; else needvel = 0.; float velchange = needvel - body->GetLinearVelocity().x; float force = body->GetMass() * velchange / (1 /static_cast<float>( g.m.animation_tick)); body->ApplyForce(b2Vec2(force, 0), body->GetWorldCenter(), true); //damage over time management if(contact) { if(lastproc == 0) damage(3); lastproc++; if(lastproc >= 60) lastproc = 0; } if(attacking) { if(attackcooldown == 0) { attacking = false; spAnimationState_setAnimationByName(model->state, 0, (right | left) ? "walk" : "rest", true); if(swordFix) body->DestroyFixture(swordFix); } attackcooldown--; } }
////////////////////////////////////////////////////////////////////////// // Reproduce Memory leak as described in Issue #776 // https://github.com/EsotericSoftware/spine-runtimes/issues/776 void MemoryTestFixture::reproduceIssue_776() { spAtlas* atlas = nullptr; spSkeletonData* skeletonData = nullptr; spAnimationStateData* stateData = nullptr; spSkeleton* skeleton = nullptr; spAnimationState* state = nullptr; ////////////////////////////////////////////////////////////////////////// // Initialize Animations LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); /////////////////////////////////////////////////////////////////////////// // Run animation spSkeleton_setToSetupPose(skeleton); InterruptMonitor eventMonitor(state); //eventMonitor.SetDebugLogging(true); // Interrupt the animation on this specific sequence of spEventType(s) eventMonitor .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") .AddInterruptEvent(SP_ANIMATION_START); spAnimationState_setAnimationByName(state, 0, "walk", true); spAnimationState_addAnimationByName(state, 0, "jump", false, 0.0f); spAnimationState_addAnimationByName(state, 0, "run", true, 0.0f); spAnimationState_addAnimationByName(state, 0, "jump", false, 3.0f); spAnimationState_addAnimationByName(state, 0, "walk", true, 0.0f); spAnimationState_addAnimationByName(state, 0, "idle", false, 1.0f); for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } ////////////////////////////////////////////////////////////////////////// // Cleanup Animations DisposeAll(skeleton, state, stateData, skeletonData, atlas); }
void Player::stopLeft() { left = false; if(!right) spAnimationState_setAnimationByName(model->state, 0, "rest", true); }
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); } }
void Skeleton::set_animation(int track, const char* animation, bool loop) { spAnimationState_setAnimationByName(state_, track, animation, loop); }