_animateLosingChevron() {
    return new Promise((resolve) => {
      // play gain chevron sfx
      audio_engine.current().play_effect(RSX.sfx_unit_onclick.audio, false);

      this._currentShownStars -= 1;
      const chevronIndex = this._currentShownStars;
      const oldChevronSprite = this._chevronSprites[chevronIndex];
      const newChevronSprite = new BaseSprite(RSX.ranked_chevron_empty.img);
      this._chevronSprites[chevronIndex] = newChevronSprite;
      newChevronSprite.setPosition(oldChevronSprite.getPosition());
      newChevronSprite.setOpacity(0);
      newChevronSprite.setScale(0.8);
      this.addChild(newChevronSprite);

      const inwardsParticles = BaseParticleSystem.create(RSX.ptcl_rank_chevron_inwards.plist);
      inwardsParticles.setPositionCenterOfSprite(oldChevronSprite);
      inwardsParticles.setDuration(CONFIG.ANIMATE_FAST_DURATION);
      inwardsParticles.resumeSystem();
      inwardsParticles.setAutoRemoveOnFinish(true);
      inwardsParticles.setPositionType(cc.ParticleSystem.TYPE_RELATIVE);
      inwardsParticles.setZOrder(-1);
      this.addChild(inwardsParticles);

      this.runAction(cc.sequence(
        cc.spawn(
          cc.targetedAction(oldChevronSprite, cc.scaleTo(CONFIG.ANIMATE_MEDIUM_DURATION, 0.8).easing(cc.easeOut(3.0))),
          cc.targetedAction(oldChevronSprite, cc.fadeOut(CONFIG.ANIMATE_MEDIUM_DURATION)),
          cc.targetedAction(newChevronSprite, cc.fadeIn(CONFIG.ANIMATE_MEDIUM_DURATION)),
          cc.targetedAction(newChevronSprite, cc.scaleTo(CONFIG.ANIMATE_MEDIUM_DURATION, 1.0).easing(cc.easeOut(3.0))),
        ),
        cc.targetedAction(oldChevronSprite, cc.removeSelf()),
        cc.callFunc(() => {
          resolve();
        }),
      ));
    });
  }
Animate losing last chevron
@private
@return {Promise} A promise which resolves when animation is complete